You can do
a lot with the regular HTML-editor in Camelonta CMS but sometimes you want to
make it easier for the editor to add nice looking formatted pieces of data to
the site without the hassle of formatting it themselves or you want to force a
specific design on the site. For example an image with an author name attached
to the bottom of it or a movie with a header and a summary. That is easily done
with the Panel element like this.
<Element Name="ImageWithAuthor" Type="Panel">
<Label xml:lang="en">Image with an author</Label>
<Element Name="Image" Type="ImageChooser">
<Label xml:lang="en">Image</Label>
</Element>
<Element Name="Author" Type="TextField">
<Label xml:lang="en">Author</Label>
</Element>
</Element>
Now you can
retrieve the data in your template like this:
<CMS:Image PropertyFilename="ImageWithAuthor/Image" runat="server" />
<p>
<CMS:Property PropertyName="ImageWithAuthor/Author" runat="server" />
</p>
Adding multiple elements
That is
pretty simple but what if you want the editor to be able to add several of
these images? Well, that is when we can use our handy ForEach-control. CMS:ForEach is a control that makes it possible to
iterate over several elements. First we need to be able to add several of the
ImageWithAuthor-panel. To do this we add the MaxOccurs-property that tells the PageType how many of this element
can be added to the page. It can be a number or unbounded for an unlimited
amount.
<Element Name="ImageWithAuthor" Type="Panel" MaxOccurs="unbounded">
<Label xml:lang="en">Image with an author</Label>
<Element Name="Image" Type="ImageChooser">
<Label xml:lang="en">Image</Label>
</Element>
<Element Name="Author" Type="TextField">
<Label xml:lang="en">Author</Label>
</Element>
</Element>
If you edit
your page now you will be able to add several of the ImageWithAuthor-element.
Ok, but if
you add a couple of these elements and then preview the page you will only see
the first one. Let’s fix this by adding our ForEach-control to iterate through
them and render all of them instead.
<CMS:Foreach Property="ImageWithAuthor" runat="server">
<ItemTemplate>
<CMS:Image PropertyFilename="Image" runat="server" />
<p>
<CMS:Property PropertyName="Author" runat="server" />
</p>
</ItemTemplate>
</CMS:Foreach>
Now you
should have a list with all of them. Try reordering the elements on the Edit Page
and you’ll notice that the ForEach-control respects the order that you place
them in. What is happening here? Well first we have added the ForEach-control
around our previous template-code. It takes the name of the property we want to
iterate over as a property. You can also see that we have removed the prefix
ImageWithAuthor on the CMS:Image and CMS:Property tags. That is because inside
the CMS:Foreach we are now in the context of the element ImageWithAuthor.
Iterating over several
different elements at the same time
Ok let’s
mix it up a little. We want to be able to add a header text in-between any of these images, so that we can group
them together. We also want the editor to freely be able to decide the order of
the images and headers.
First we
add a new element in the Schema file:
<Element Name="Header" Type="TextField">
<Label xml:lang="en">Header</Label>
</Element>
Then we change our ForEach like this:
<CMS:Foreach Property="Header|ImageWithAuthor" runat="server">
<ItemTemplate>
<CMS:If CurrentElementName="Header" runat="server">
<h2><CMS:Property PropertyName="this" runat="server" /></h2>
</CMS:If>
<CMS:If CurrentElementName="ImageWithAuthor" runat="server">
<CMS:Image PropertyFilename="Image" runat="server" />
<p>
<CMS:Property PropertyName="Author" runat="server" />
</p>
</CMS:If>
</ItemTemplate>
</CMS:Foreach>
Let me
walk you through the changes here. First we changed the property of the ForEach
to Header|ImageWithAuthor. The pipe-sign is a union operator and this tells the
control that we want to iterate through both of those elements at the same
time. In the ForEach template we need to know what the current element is in
order to apply different rendering depending on the element. To do that we use
the If control and the CurrentElementName attribute. If CurrentElementName is “ImageWithAuthor” then
we print the same code as before. If it is “Header” we need to use the “this”
keyword to reference the “Header”-element. Why use “this”? Well, remember
before when I said that inside the ForEach-control we are in the context of the
child element? When we are in the
Header-context we don’t have a child element to print as we do with
ImageWithAuthor. Instead we just use the “this” keyword to print the current
property instead.
Check out this page on out demo site to view a live example of how it may look
<<- Tillbaka till listan