1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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
20 /// Provides access to sitemap content and renders it either using nested sections or a custom
25 /// The following example uses nvelocity view engine syntax.
28 /// #blockcomponent(SiteMapComponent with "providerName=support")
47 /// <a href="$node.url"> $node.Name </a>
54 /// Using a custom view:
58 /// #component(SiteMapComponent with "providerName=support" "customview=directoryview")
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"/>
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/>
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();
87 /// Gets or sets the provider accessor.
89 /// <value>The provider accessor.</value>
90 public IProviderAccessor ProviderAccessor
92 get { return providerAccessor; }
93 set { providerAccessor = value; }
97 /// Gets or sets the name of the sitemap provider to use.
99 /// <value>The name of the provider.</value>
101 public string ProviderName
103 get { return providerName; }
104 set { providerName = value; }
108 /// Gets or sets the custom view to be used to render the root node.
109 /// If not provided, the sections will be used.
111 /// <value>The custom view.</value>
113 public string CustomView
115 get { return customView; }
116 set { customView = value; }
120 /// Called by the framework once the component instance
123 public override void Initialize()
125 if (providerName
== null)
127 targetProvider
= providerAccessor
.DefaultProvider
;
131 targetProvider
= providerAccessor
[providerName
];
134 if (targetProvider
== null)
136 throw new ViewComponentException("Could not obtain provider instance");
143 /// Called by the framework so the component can
144 /// render its content
146 public override void Render()
148 SiteMapNode node
= targetProvider
.RootNode
;
150 if (customView
!= null)
152 PropertyBag
["node"] = node
;
153 RenderView(customView
);
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");
195 PropertyBag
["node"] = node
;
196 PropertyBag
["parent"] = node
.ParentNode
;
197 RenderSection("leafnode");
202 /// Abstract the access to sitemap providers
204 public interface IProviderAccessor
207 /// Gets the default provider.
209 /// <value>The default provider.</value>
210 SiteMapProvider DefaultProvider { get; }
213 /// Gets the <see cref="System.Web.SiteMapProvider"/> with the specified provider name.
216 SiteMapProvider
this[string providerName
] { get; }
220 /// Accessor for the sitemap provider using the ASP.Net API
222 public class AspNetProviderAccessor
: IProviderAccessor
225 /// Gets the default provider.
227 /// <value>The default provider.</value>
228 public SiteMapProvider DefaultProvider
230 get { return SiteMap.Provider; }
234 /// Gets the <see cref="System.Web.SiteMapProvider"/> with the specified provider name.
237 public SiteMapProvider
this[string providerName
]
239 get { return SiteMap.Providers[providerName]; }