33 |
36 | {{partial name="foot"}}
37 |
38 |
39 | ```
40 |
41 | In order to get this layout view to work you need to create the following things:
42 | - A Sitecore placeholder item for each placeholder (3x in this example)
43 | - A Sitecore layout item
44 | - A Sitecore controller rendering called `Breadcrumb`
45 | - A C# controller `BreadcrumbController`.
46 |
47 | Please follow the [Getting started](getting-started.md) page for this simple case.
48 |
49 | ### Model on layout level
50 |
51 | In the above example you can only see partials, placeholders and components in the markup without data properties. But what if you need to add direct values to the first level of your handlebars hierarchy, e.g. a simple string indicating the language?
52 |
53 | You can make use of the out of the box functionality of Sitecore where you can define a model on your layout. First change your layout to this:
54 |
55 | ```html
56 |
57 |
58 | ...
59 |
60 | ```
61 |
62 | Create a model inheriting from the Sitecore.Mvc.Presentation.IRenderingModel and implement the `Initialize()` method where you set your properties:
63 |
64 | ```csharp
65 | public class DefaultRenderingModel : IRenderingModel
66 | {
67 | public string HtmlLanguage { get; set; }
68 |
69 | public void Initialize(Rendering rendering)
70 | {
71 | HtmlLanguage = Sitecore.Context.Language.Name;
72 | }
73 | }
74 | ```
75 |
76 | In the Sitecore backend create a new model item under `/sitecore/layout/Models`. On the newly created item in the field `Model Type` enter the fully qualified name of the DefaultRenderingModel you've created above (e.g. `MyProject.Internet.Model.DefaultRenderingModel, MyProject.Internet.Model`).
77 |
78 | Finally you need to link your layout to the model item. Do this in the `Model` field of the layout item. Reload your page and voila, the value is there.
79 |
80 | ### Controller invocation with template and data attribute
81 |
82 | With NitroNet for Sitecore it is possible to determine with which template and data attribute a Controller was called.
83 | All you have to do is to add the two parameters `string template` `string data` to the `Index()` method of the Controller.
84 |
85 | Let's look at the following example:
86 |
87 | View snippet:
88 |
89 | ```html
90 |
99 | ```
100 |
101 | `Index()` method:
102 |
103 | ```csharp
104 | public ActionResult Index(string data, string template)
105 | {
106 | FooterLinkListViewModel model;
107 | if (data.Equals("social", StringComparison.InvariantCultureIgnoreCase))
108 | {
109 | model = _service.CreateSocialLinks()
110 | }
111 | else if (template.Equals("templateB", StringComparison.InvariantCultureIgnoreCase))
112 | {
113 | model = _service.CreateBLinks()
114 | }
115 | else
116 | {
117 | model = _service.CreateFooterLinks();
118 | }
119 |
120 | return View("[path to your component folder]/footer-link-list", model);
121 | }
122 | ```
123 |
124 | For direct values like `title` there needs to be a property, for the `footer-link-list` component not.
125 |
126 | ### Use of Sitecore edit frames
127 |
128 | An important feature when developing with Sitecore is the use of edit frames for the Experience Editor.
129 | The following example shows you how you can achieve this when using *handlebars* and *NitroNet.Sitecore*.
130 |
131 | #### 1.) Create a view model
132 | In the first step you have to create C# view model for your edit frame:
133 |
134 | ```csharp
135 | public class EditFrame
136 | {
137 | public string EditFrameStart { get; set; }
138 | public string EditFrameStop { get; set; }
139 | }
140 | ```
141 |
142 | #### 2.) Write a method to populate the view model
143 | In the second step you have to write a method for populating the edit frame view model. You can copy the following method or use it as a basis for your own implementation:
144 |
145 | ```csharp
146 | public EditFrame GetEditFrame(string path, string buttons, string title, string tooltip, string css, object parameters)
147 | {
148 | var result = new EditFrame();
149 | if (!Sitecore.Context.PageMode.IsExperienceEditorEditing)
150 | return result;
151 |
152 | var output = new StringWriter();
153 | var writer = new HtmlTextWriter(output);
154 | var editFrame = new Sitecore.Mvc.Common.EditFrame(path,buttons, title, tooltip, css, parameters);
155 | editFrame.RenderFirstPart(writer);
156 | result.EditFrameStart = output.ToString();
157 |
158 | output = new StringWriter();
159 | writer = new HtmlTextWriter(output);
160 | editFrame.RenderLastPart(writer);
161 | result.EditFrameStop = output.ToString();
162 |
163 | return result;
164 | }
165 | ```
166 |
167 | #### 3.) Use the edit frame in your views
168 | And last but not least you need this handlebars markup to activate the edit frame.
169 |
170 | ```html
171 | {{{editframe.editframeStart}}}
172 |
175 | {{{editframe.editframeStop}}}
176 | ```
177 |
178 | Please keep in mind that the context object needs to have a property with the following type and name:
179 |
180 | ```csharp
181 | public EditFrame EditFrame { get; set; }
182 | ```
183 |
184 | ## Nitro helpers for Sitecore
185 |
186 | ### Placeholders
187 |
188 | Placeholders don't need a special interaction in user code. In Sitecore you need to create a placeholder setting item with the same key value as the `name` attribute of the placeholder. The `template` parameter is completely ignored by NitroNet.
189 |
190 | ```html
191 |
194 | ```
195 |
196 | #### Identical placeholders on the same level
197 |
198 | You might run into situations where you want to have multiple placeholders with the same key on the same hierarchical level. Therefore you need to use the `index` or `indexprop` attribute. NitroNet uses Dynamic Placeholders by default.
199 |
200 | ##### index attribute
201 |
202 | ```html
203 |
219 | ```
220 |
221 | Model snippet:
222 |
223 | ```csharp
224 | public class AccordionModel
225 | {
226 | public IEnumerable Items { get; set; }
227 | }
228 |
229 | public class AccordionItemModel
230 | {
231 | public string Id { get; set; }
232 | }
233 | ```
234 |
235 |
236 | ### A component with subcomponents
237 | There are two ways to deal with a component who contains subcomponents (e.g. a molecule that consists of one or more atoms):
238 |
239 | #### 1) Create a Controller for each or selected subcomponents
240 | Sometimes it is necessary to controll the caching of the individual subcomponents (e.g. header component) and therefore necessary to create Sitecore controller renderings and C# Controllers for these subcomponents. If you do not provide a model of the subcomponent, NitroNet tries to invoke a Controller for this subcomponent. You can also create a Sitecore controller rendering for it if you need to set special caching settings for this component because it is run through the rendering pipeline. NitroNet for Sitecore internally invokes the controller respectively the rendering pipeline.
241 |
242 | In the following example we will look more detailed into that:
243 |
244 | View snippet:
245 |
246 | ```html
247 |
256 | ```
257 |
258 | C# Model:
259 |
260 | ```csharp
261 | public class FooterContainerModel
262 | {
263 | public string Title { get; set; }
264 | }
265 | ```
266 |
267 | C# Controller for the `footer-link-list`:
268 |
269 | ```csharp
270 | public class FooterLinkListController : Controller
271 | {
272 | private readonly IFooterLinkService _service;
273 |
274 | public FooterLinkListController(IFooterLinkService service)
275 | {
276 | _service = service;
277 | }
278 |
279 | public ActionResult Index(string data)
280 | {
281 | FooterLinkListViewModel model;
282 | if (data.Equals("social", StringComparison.InvariantCultureIgnoreCase))
283 | {
284 | model = _service.CreateSocialLinks()
285 | }
286 | else
287 | {
288 | model = _service.CreateFooterLinks();
289 | }
290 |
291 | return View("path/to/your/template/footer-link-list", model);
292 | }
293 | }
294 | ```
295 |
296 | For direct values like `title` there needs to be property, for the `footer-link-list` component not. At this point the controller gets invoked directly.
297 |
298 | If you want to cache the `footer-link-list` component specifically you need to create a Controller Rendering called *FooterLinkList* (hyphens and case sensitivity can be ignored) in Sitecore. Now, the rendering pipeline gets invoked and you can set all the caching configurations for the component. Note that the `data` attribute is considered if you choose *Vary By Data*.
299 |
300 | #### 2) Create only one Controller for the parent component
301 | You can find the code example and explanations for this case [here](https://github.com/merkle-open/NitroNet/blob/master/docs/samples.md#a-component-with-subcomponents).
302 |
--------------------------------------------------------------------------------
/packaging.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget"))
5 |
6 |
7 |
8 | $(SolutionDir).nuget
9 |
10 |
14 |
15 |
16 | true
17 |
18 | true
19 |
20 | C:\nuget_local
21 |
22 |
23 | Sitecore82
24 | true
25 | snupkg
26 |
27 |
28 |
29 |
30 |
31 | $(PackageVersion)-$(PrereleaseVersion)$([System.String]::Format('{0:000}', $([MSBuild]::Add($(BuildNumber), 0))))
32 |
33 |
34 |
35 |
36 | $(PackageVersion)
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | $(NugetPackageVersion)
45 |
46 |
47 |
48 |
49 | $(NitroNetCoreMajorVersion).$(NitroNetCoreMinorVersion).$(NitroNetCorePatchVersion)-$(NitroNetCorePrereleaseVersion)$([System.String]::Format('{0:000}', $([MSBuild]::Add($(NitroNetCoreBuildnumber), 0))))
50 |
51 |
52 |
53 |
54 | $(NitroNetCoreMajorVersion).$(NitroNetCoreMinorVersion).$(NitroNetCorePatchVersion)
55 |
56 |
57 |
58 |
59 |
60 | $(BuildDependsOn);
61 | BuildPackageCustom;
62 | PublishPackage;
63 |
64 | $(NuGetToolsPath)\NuGet.exe
65 | "$(NuGetExePath)"
66 | mono --runtime=v4.0.30319 $(NuGetExePath)
67 | <_NugetApiKey Condition="'$(NugetApiKey)' != ''"> -ApiKey "$(NugetApiKey)"
68 | $([System.IO.Path]::GetDirectoryName('$(ProjectDir)$(IntermediateOutputPath)'))
69 | $(ProjectPath.Replace('.csproj', '.nuspec'))
70 | $(ProjectName.Replace('.csproj', '')).*$(NugetPackageVersion).nupkg
71 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" $(IncludeReferencedProjects) -Properties "ProductVersion=$(ProductVersion);DependentVersion=$(NugetPackageVersion);DependentNitroNetVersion=$(DependentNitroNetVersion)" -Version "$(NugetPackageVersion)"
72 | $(NuGetCommand) push "$(PackageOutputDir)\$(PackageOutput)" $(_NugetApiKey) -source "$(NugetRepository)"
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/versioning.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 1
8 | 1
9 | 0
10 | 0
11 | $(MajorVersion).$(MinorVersion).$(PatchVersion)
12 | $(MajorVersion).$(MinorVersion).0.0
13 | $(PackageVersion).$(BuildNumber)
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------