Added non-generic registration interface to IKernel and IWindsor to accommodate dynam...
[castle.git] / MonoRail / Castle.MonoRail.Framework / ViewComponents / SiteMapComponent.cs
blob6d71c052633a395645dabae355d7ceaf76a87648
1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.MonoRail.Framework.ViewComponents
17 using System.Web;
19 /// <summary>
20 /// Provides access to sitemap content and renders it either using nested sections or a custom
21 /// specified view.
22 /// </summary>
23 ///
24 /// <example>
25 /// The following example uses nvelocity view engine syntax.
26 /// <code>
27 /// <![CDATA[
28 /// #blockcomponent(SiteMapComponent with "providerName=support")
29 ///
30 /// #startparentnode
31 /// $node.Name
32 /// <ul>
33 /// #end
34 /// #endparentnode
35 /// </ul>
36 /// #end
37 ///
38 /// #startnode
39 /// <li> $node.Name
40 /// <ul>
41 /// #end
42 /// #endnode
43 /// </li> </ul>
44 /// #end
45 ///
46 /// #leafnode
47 /// <a href="$node.url"> $node.Name </a>
48 /// #end
49 ///
50 /// #end
51 /// ]]>
52 /// </code>
53 /// <para>
54 /// Using a custom view:
55 /// </para>
56 /// <code>
57 /// <![CDATA[
58 /// #component(SiteMapComponent with "providerName=support" "customview=directoryview")
59 /// ]]>
60 /// </code>
61 /// </example>
62 ///
63 /// <remarks>
64 /// To use this view component you just need to set up one or more sitemaps within your web app,
65 /// then specify the provider name (optionally) using the <see cref="ProviderName"/>
66 ///
67 /// <para>
68 /// You can use the following nested sections:
69 /// Supported sections: <br/>
70 /// <c>startparentnode</c>: invoked for SiteMapNode without a parent <br/>
71 /// <c>endparentnode</c>: same thing but after visiting its children <br/>
72 /// <c>startnode</c>: invoked for node with parents and children <br/>
73 /// <c>endnode</c>: ditto. <br/>
74 /// <c>leafnode</c>: invoked for nodes without children <br/>
75 /// </para>
76 /// </remarks>
77 [ViewComponentDetails("SiteMapComponent", Sections = "startparentnode,endparentnode,leafnode,startnode,endnode")]
78 public class SiteMapComponent : ViewComponent
80 private SiteMapProvider targetProvider;
82 private string providerName;
83 private string customView;
84 private IProviderAccessor providerAccessor = new AspNetProviderAccessor();
86 /// <summary>
87 /// Gets or sets the provider accessor.
88 /// </summary>
89 /// <value>The provider accessor.</value>
90 public IProviderAccessor ProviderAccessor
92 get { return providerAccessor; }
93 set { providerAccessor = value; }
96 /// <summary>
97 /// Gets or sets the name of the sitemap provider to use.
98 /// </summary>
99 /// <value>The name of the provider.</value>
100 [ViewComponentParam]
101 public string ProviderName
103 get { return providerName; }
104 set { providerName = value; }
107 /// <summary>
108 /// Gets or sets the custom view to be used to render the root node.
109 /// If not provided, the sections will be used.
110 /// </summary>
111 /// <value>The custom view.</value>
112 [ViewComponentParam]
113 public string CustomView
115 get { return customView; }
116 set { customView = value; }
119 /// <summary>
120 /// Called by the framework once the component instance
121 /// is initialized
122 /// </summary>
123 public override void Initialize()
125 if (providerName == null)
127 targetProvider = providerAccessor.DefaultProvider;
129 else
131 targetProvider = providerAccessor[providerName];
134 if (targetProvider == null)
136 throw new ViewComponentException("Could not obtain provider instance");
139 base.Initialize();
142 /// <summary>
143 /// Called by the framework so the component can
144 /// render its content
145 /// </summary>
146 public override void Render()
148 SiteMapNode node = targetProvider.RootNode;
150 if (customView != null)
152 PropertyBag["node"] = node;
153 RenderView(customView);
155 else
157 RecursiveRenderNode(node);
161 private void RecursiveRenderNode(SiteMapNode node)
163 if (node == null) return;
165 if (node.ParentNode == null)
167 PropertyBag["node"] = node;
168 RenderSection("startparentnode");
170 foreach(SiteMapNode child in node.ChildNodes)
172 RecursiveRenderNode(child);
175 PropertyBag["node"] = node;
176 RenderSection("endparentnode");
178 else if (node.HasChildNodes)
180 PropertyBag["node"] = node;
181 PropertyBag["parent"] = node.ParentNode;
182 RenderSection("startnode");
184 foreach (SiteMapNode child in node.ChildNodes)
186 RecursiveRenderNode(child);
189 PropertyBag["node"] = node;
190 PropertyBag["parent"] = node.ParentNode;
191 RenderSection("endnode");
193 else
195 PropertyBag["node"] = node;
196 PropertyBag["parent"] = node.ParentNode;
197 RenderSection("leafnode");
201 /// <summary>
202 /// Abstract the access to sitemap providers
203 /// </summary>
204 public interface IProviderAccessor
206 /// <summary>
207 /// Gets the default provider.
208 /// </summary>
209 /// <value>The default provider.</value>
210 SiteMapProvider DefaultProvider { get; }
212 /// <summary>
213 /// Gets the <see cref="System.Web.SiteMapProvider"/> with the specified provider name.
214 /// </summary>
215 /// <value></value>
216 SiteMapProvider this[string providerName] { get; }
219 /// <summary>
220 /// Accessor for the sitemap provider using the ASP.Net API
221 /// </summary>
222 public class AspNetProviderAccessor : IProviderAccessor
224 /// <summary>
225 /// Gets the default provider.
226 /// </summary>
227 /// <value>The default provider.</value>
228 public SiteMapProvider DefaultProvider
230 get { return SiteMap.Provider; }
233 /// <summary>
234 /// Gets the <see cref="System.Web.SiteMapProvider"/> with the specified provider name.
235 /// </summary>
236 /// <value></value>
237 public SiteMapProvider this[string providerName]
239 get { return SiteMap.Providers[providerName]; }