#region License // Copyright (c) 2007-2008, James M. Curran // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #endregion namespace Castle.MonoRail.ViewComponents { #region Reference using System; using System.IO; using System.Collections; using Castle.MonoRail.Framework; using Castle.MonoRail.Framework.Helpers; using Castle.Core.Logging; using System.Web; using System.Collections.Specialized; #endregion /// /// Helper class to provide a some convenient methods for viewcomponents. /// /// May one day be incorporated into base class. public abstract class ViewComponentEx : ViewComponent { private ILogger logger; public ILogger Logger { get { if (logger == null) logger = NullLogger.Instance; return logger; } set { logger = value; } } /// /// Renders the text, formatted. /// /// The format. /// The args. public void RenderTextFormat(string format, params object[] args) { string content = String.Format(format, args); base.RenderText(content); } /// /// Renders the optional section, or the default text, if section not present. /// /// The section. /// The default text. protected bool RenderOptionalSection(string section, string defaultText) { if (Context.HasSection(section)) { Context.RenderSection(section); return true; } RenderText(defaultText); return false; } /// /// Renders the optional section. /// /// The section. /// bool, [true] is the section was rendered protected bool RenderOptionalSection(string section) { if (Context.HasSection(section)) { Context.RenderSection(section); return true; } return false; } /// /// Gets the section text. /// /// The section. /// public string GetSectionText(string section) { using (StringWriter sw = new StringWriter()) { if (String.IsNullOrEmpty(section)) RenderBody(sw); else Context.RenderSection(section, sw); return sw.ToString(); } } /// /// Gets the body text. /// /// public string GetBodyText() { return GetSectionText(null); } /// /// Confirms a section is present. /// /// Throws an exception if the given section is not present. /// /// The section. /// If specified section is not present. public void ConfirmSectionPresent(string section) { if (!Context.HasSection(section)) { string message = String.Format("{0}: you must supply a '{1}' section", Context.ComponentName, section); throw new ViewComponentException(message); } } /// /// Gets a boolean parameter value. /// /// The key. /// The value used if there is no parameter named key. /// [Obsolete("use GetParamValue instead")] public bool GetBoolParamValue(string key, bool defaultValue) { return GetParamValue(key, defaultValue); } public bool GetParamValue(string key, bool defaultValue) { object parmValue = Context.ComponentParameters[key]; bool value = defaultValue; if (parmValue is string) { if (!Boolean.TryParse(parmValue as string, out value)) value = defaultValue; } else if (parmValue is bool) { value = (bool)parmValue; } return value; } public string GetParamValue(string key, string defaultValue) { return Context.ComponentParameters[key] as string ?? defaultValue; } /// /// Gets the param value. /// /// /// The key. /// The default value. /// public E GetParamValue(string key, E defaultValue) where E:struct { object parmValue = Context.ComponentParameters[key]; E value = defaultValue; if (parmValue is string) { try { value = (E)Enum.Parse(typeof(E), parmValue as string, true); } catch { value = defaultValue; } } else if (parmValue is E) { value = (E)parmValue; } return value; } /// /// Makes an unique id. /// /// The given prefix is prepended to the generated number. /// The ID isn't actually guarenteed to be unique (which would require /// using all 32 digits of the guid). But this produce ids sufficently /// distinctive to generate multiple controls on a page. /// /// The prefix. /// A string usable as a Html element Id public string MakeUniqueId(string prefix) { byte[] bytes = Guid.NewGuid().ToByteArray(); int a = BitConverter.ToInt32(bytes, 0); int b = BitConverter.ToInt32(bytes, 4); int c = BitConverter.ToInt32(bytes, 8); int d = BitConverter.ToInt32(bytes, 12); return prefix + (a ^ b ^ c ^ d).ToString("x08"); } #region Render Composite Component /// /// Renders the component. /// /// Intended to render a viewComponent from within a different viewComponent.

/// Original concept devised by Joey Beninghove.

/// http://joeydotnet.com/blog/archive/2007/05/15/Creating-Composite-View-Components-In-MonoRail--Refactoring-Exercise.aspx /// /// ("linkText=Search", /// string.Format("formToSubmit={0}", searchFormName)); /// ]]> /// The type of the ViewComponent. /// The component params. public void RenderComponent(IDictionary componentParams) where VC : ViewComponentEx, new() { ViewComponentEx component = new VC(); RenderComponent(component, componentParams); } ///

/// Renders the component. /// /// For full details, /// /// (DictHelper.N("linkText","Search").N("formToSubmit", searchFormName); /// ]]> /// The type of the C. /// The component params. public void RenderComponent(params string[] componentParams) where VC : ViewComponentEx, new() { ViewComponentEx component = new VC(); RenderComponent(component, DictHelper.Create(componentParams)); } /// /// Renders the component. /// /// The component. /// The component params. /// For full details, /// /// public void RenderComponent(ViewComponentEx component, params string[] componentParams) { RenderComponent(component, DictHelper.Create(componentParams)); } /// /// Renders the component. /// /// The component. /// The component params. /// For full details, /// /// public void RenderComponent(ViewComponentEx component, IDictionary componentParams) { component.Init(EngineContext, Context); foreach (DictionaryEntry dictionaryEntry in componentParams) { component.Context.ComponentParameters[dictionaryEntry.Key]= dictionaryEntry.Value; } component.Initialize(); component.Render(); string html = string.Empty; component.Context.Writer.Write(html); RenderText(html); } #endregion } /// /// Base class to be inherited by ViewComponents which access /// the ASP.NET SiteMap. Handles the Provider & SiteMapProvider properties, /// defaulting to the values in web.config, as does ASP.NET /// /// Also added a SiteMapFile property, to set it more directly. /// public abstract class ViewComponentUsingSiteMap : ViewComponentEx { /// /// Gets or sets the site map file. /// /// The site map file. [ViewComponentParam("SiteMapFile")] public string SiteMapFile { get; set; } SiteMapProvider m_Provider; /// /// Gets or sets a that is associated with the ViewComponent. /// /// The provider. /// The Provider property specifies an instance of a site map provider to use with the control. /// This provider may be different from the provider identified by the property, if set. /// [ViewComponentParam] public SiteMapProvider Provider { get { if (m_Provider == null) { if (!string.IsNullOrEmpty(SiteMapProvider)) { m_Provider= SiteMap.Providers[SiteMapProvider]; } else if (this.SiteMapFile ==null) { m_Provider= SiteMap.Provider; } if (m_Provider== null) { // Create an instance of the XmlSiteMapProvider class. XmlSiteMapProvider testXmlProvider = new XmlSiteMapProvider(); NameValueCollection providerAttributes = new NameValueCollection(1); providerAttributes.Add("siteMapFile", this.SiteMapFile ?? "~/web.sitemap"); // Initialize the provider with a provider name and file name. testXmlProvider.Initialize("ViewComponentUsingSiteMapProvider", providerAttributes); // Call the BuildSiteMap to load the site map information into memory. testXmlProvider.BuildSiteMap(); m_Provider = testXmlProvider; } } return m_Provider; } set { m_Provider = value; } } /// /// Gets or sets the name of the used to render the site navigation control. /// /// The site map provider. [ViewComponentParam] public string SiteMapProvider { get; set; } } }