Request a topic or
contact an Arke consultant
404-812-3123
Sitecore

Arke Systems Blog

Useful technical and business information straight from Arke.

About the author

Author Name is someone.
E-mail me Send mail

Recent comments

Archive

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2024

Render unto c#

When it comes to CMS development (among other things in life) I’m a big fan of granularity and reusability. I believe that in a good solution architecture, both content and code are managed in discreet, granular pieces, which promotes both consistency and reusability.

That’s why it bothers me that so many Sitecore professionals react to the word “rendering” the same way a horse would. To my mind, a good solution has a geometric ratio of layouts to sublayouts, and sublayouts to renderings. Yet I see projects that are extremely sublayout-centric, with content IA and logic governing page layout.

Sitecore’s arsenal of presentation management tools, such as layout details, placeholder settings and rendering parameters, allows us as developers to truly empower our content owners. When implemented well, these features give the content authors what I like to call “controlled control” over their pages.

Unfortunately, we often see solutions where sublayouts are the dominant presentation component. Sublayouts are far less efficient than renderings, both in terms of performance and management. With sublayouts, there are all the ascx files to manage and deploy. And using sublayouts to present content seems to promote having a single component (sublayout) present multiple fields. This can dramatically reduce the solution’s flexibility – or worse, lead to having multiple components that are slight variations on each other, or have cumbersome logic (often wired to “control” fields in the content) to suppress content or change the presentation behavior.

Worse, some solutions rely almost entirely on the content tree to govern layout, such as by having fields in page templates that change the behavior of the layout, and/or by having sets of child items that code “bubbles up” into the page when they are present.

So why are renderings so often left out of solution architecture? I suspect that the problem lies in Sitecore training. Although Sitecore trainers do point out the different ways that renderings can be created, they tend to use XSL as the example technology in class (probably because it’s quicker to demonstrate --the trainer can show changes to an XSL rendering immediately, without compiling). Regrettably, this leaves many with a linkage in their minds between renderings as a Sitecore artifact and XSL as a technology. The oft-maligned rendering can be implemented using multiple technologies, yet many, many developers believe that renderings can only be developed using XSL.

I’m not going to wade into the great XSL debate here. I personally like XSL, but I rarely use it in Sitecore projects, for a number of reasons that I’ll get into that in a separate post. Suffice it to say that many developers, even if they know XSL, want to avoid it if for no other reason than to make their projects sustainable. XSL is a far more rare skill than c#, so it makes sense to ensure that future developers will be able to extend and maintain the project. And since there’s this misconception that “renderings = XSL”, the “baby” of a rendering-based architecture gets thrown out with the “bathwater” of XSL. And that’s a shame.

So let’s set the record straight. Renderings can and should be developed in c#. Actually, John West points out in his book “Professional Sitecore Development,” there are four types of renderings:

  1. XSL renderings
  2. Method renderings
  3. URL renderings
  4. Web Controls

Of these, Web Control renderings – controls that are implemented entirely in code and deployed in assemblies – are the least used yet most useful presentation component available. (In my next post, I’ll delve into the anatomy of a web control rendering.)

As a simple example, consider a page with a “core content” (“body”) area consisting of a title, a main image, and some body text. These three fields are defined in the page’s template. One way of handling this is to create a sublayout that renders these fields to the output (hopefully, at least, using field renderers). But what happens when the author does not want a title on a particular page (this is a simple example, so let’s not quibble over usability or SEO). Sure, the sublayout’s code-behind could suppress the <h1> when the field is empty or null. Or we could have a checkbox in the template to suppress the title.

What if the content author wants something other than a main image, like a flash or a video? What if they need to insert something between the image and the body? And after the body, they might need set of “spots” to point to other content?

So we might resort to having different sublayouts with variations on the content. This can lead to an unmanageable mess, creating confusion as to which sublayout does what. It also leads to redundant code, which makes ongoing maintenance and modification to the site much more challenging.

Another solution would be to put fields in the template to suppress content, or add content, or modify the presentation of content. Or we might create templates for child items that, when present, are bubbled up into the page. This puts management of presentation into the data. Sitecore is so well architected to give us excellent separation of content and presentation, so why fight that and force content to manage presentation?

I much prefer solutions that have very “light” layouts and sublayouts, with lots of renderings bound to placeholders. For the simple example, I would have a separate rendering each for title, main image, and body text, which I would bind to a placeholder in the sublayout for the core content area. Standard values in the item’s template would bind them by default, but the content owner would have the freedom to change the presentation as required. We can use features like thumbnails, rendering parameters, placeholder settings and compatible renderings both to assist them in the layout process, and to enforce brand or visual design requirements.

Most of my layouts and sublayouts are little more than div’s and placeholders. They exist to manage the geometry of the page or of regions of the page, not to present the actual content. Renderings bound to placeholders actually emit the content. Rendering parameter templates allow the editor to influence the source and behavior of the content in the page. Now, control over presentation and layout are managed in the presentation layer, and content is managed in the content layer. The design of the IA can break the content down into more manageable chunks, promoting reusability and avoiding redundancy.

To be fair, there are times when sublayouts are a better choice than renderings. For example, for forms or other situations where postback is required, I refer to use sublayouts (ascx) controls.. Also, in cases where the parts of the page structure are immutable, it is more efficient to statically bind renderings into sublayouts (by including them in the sublayout markup). This is fine for cases like fixed headers and footers, or when the site design requires an element (like a title) to always be present. There are also rare occasions when I allow a folder of child items to bubble up into a page, but even then, I usually use a placeholder-bound rendering to do the bubbling.

A highly granular architecture, which maintains separation of content from presentation, is hugely empowering to both developers and content editors. It promotes reusability of both code and content, shifts much of the responsibility for page assembly from code to configuration, and empowers editors with more control over the layout of their pages.


Posted by Andy Uzick on Thursday, January 24, 2013 6:52 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Sitecore: Getting Started with Breadcrumbs

Posted from Amy’s Sitecore Adventures (a little late)

Breadcrumbs have been covered by just about everyone so there are lots of examples that all seem to do things a Little differently. With that in mind I’m going to keep this short with my example and two other examples I’ve found that might also meet your needs and cover the basics for just about every xslt breadcrumb example you’ll find.

The general idea: you’re at item c, in your tree the path is something like:  /sitecore/content/a/b/c and you want to display a pretty html list for a » b » c anywhere on your site.  You’ll always be dealing with the ancestors of your current item so you’ll be making use of $sc_currentitem/ancestor-or-self::… somewhere.

You’ll need to go through each ancestor item and display it, probably checking to see if you’re at the last item so you don’t display a ‘»’ after the final item. You also need to make sure to not display unwanted ancestors in your breadcrumb, being /sitecore and /content in our case.

So onto the examples!

First is the Sitecore breadcrumb xslt example: http://sdn.sitecore.net/Articles/XSL/Breadcrumb%20Example.aspx
  You will need a login to sdn to view this, but the magic is that it does a for-each across ancestor-or-self::item and then has an if statement to make sure that position()> 2 (this avoids the sitecore/content portion) and avoiding folders and there is the requisite check for position()!=last() so that we do not have the extra » after c.

Next up is Brian Pedreson’s breadcrumb example http://briancaos.wordpress.com/2009/02/09/breadcrumb-in-sitecore/
Similar to the above, however in this case he only selected items which had the appropriate template and a check to make sure the items should be in the navigation at all:
select="$sc_currentitem/ancestor-or-self::item[sc:IsItemOfType('mypages',.) and sc:fld('ShowInMenu',.)='1']"

I am certain there are many many more breadcrumb examples, but these were the first I was able to find easily to share.

Finally, my contribution to the breadcrumb party:

  <xsl:template match="*" mode="main">
    <div>
      <ul class="breadcrumb">
        <xsl:variable name="ancestors" select="$sc_currentitem/ancestor-or-self::item[ancestor-or-self::item/@template='home page']" />
        <xsl:for-each select="$ancestors">
          <li>
            <xsl:choose>
              <xsl:when test="position()=last()">
                <sc:text field="Breadcrumb Title" />
              </xsl:when>
              <xsl:otherwise>
                <sc:link>
                  <sc:text field="Breadcrumb Title" />
                </sc:link>  »
              </xsl:otherwise>
            </xsl:choose>
          </li>
        </xsl:for-each>
      </ul>
    </div>
  </xsl:template>

To satisfy the condition of not showing /sitecore or /content, I am only grabbing ancestors (or self) who have the ancestor (or is the item) that has the special template for the Home item. This excludes anything above the home item, but includes the home item too so that it can be listed. And we end up with a » b » c.

Hope this can be helpful if you are getting started with breadcrumbs!


Categories: Sitecore
Posted by Amy Winburn on Tuesday, March 22, 2011 4:32 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Sitecore: Using the Source Property

For each of the properties in your template you can set a source for it, this isn’t always used but can improve user experience drastically when done throughout a site. The source field comes in to play whenever you are using any of the following fields: Droplink, Droplist, Droptree, File, Grouped Droplink, Grouped Droplist, Image, Multilist, Treelist, Rich text field and a number of others.

There are various ways of setting these up to achieve different results – but in general you are using the source to limit the set of items that can be used, and this requirement can also help you determine what kind of field to use. For example, if you have a Set of items all split down into sub folders and want the content editor to make use of the tree, you could use a TreeList or Drop Tree, but if you just want a set of items without the opportunity to see where those items are – multilists or droplinks are the way to go. For Images you’re generally just specifying where to look for and put the images within the media library, and for Rich text fields the source determines the type of editor to use (if not the default).

There are a number of options for setting the source property but not all can work with every field.

Setting the Root Node: To do this you just give the full path to the item you want to use as the ‘root’. This works with just about every field that pulls options and you can easily grab the path from the content pane when you select your desired item(looking at the Item Path). Ie: if you have a treelist and you only want to show the categories item and its children, you’d put in the path to that item: /sitecore/content/Data/Categories

Sitecore Query: This applies to a smaller set of fields (the List Fields), but gives a lot of power and is what I’ll mainly be going over. The fields you can use this with are: Checklist, Droplink, Droplist, Grouped Droplist, Grouped Droplink, or Multilist. You can also use the fast query: this has some limitations over just using sitecore query but gives benefits of better performance and using less memory.

Treelists are also a little special and can use parameters(I think some other fields will work with this as well, but I most often end up using the query on other items so I don’t have a ton of experience with this), you can specify the root item, what templates/items to display or ignore and which they can select, for example:

DataSource=/Sitecore/Content/Home/Root/Node&IncludeTemplatesForSelection=desiredTemplate1,desiredTemplate2&ExcludeTemplatesForDisplay=secretFolder&ExcludeItemsForDisplay=secretItem&AllowMultipleSelection=true

The above sets the root node to /Sitecore/Content/Home/Root/Node and allows the user to select items using desiredTemplate1 or desiredTemplate2, it also excludes secretFolder and secretItem from showing up in the list as well as allowing the user to choose more than one of the same item.

More on Sitecore Query

Using the query option over simply setting a root node improves the experience for your clients as well as helps to keep your data accurate. If you don’t want them to be able to pick a certain template or value or need to select something dependent on a specific axes – using sitecore query will make it possible.

In the source field, your queries need to begin with query: followed by your query. I’m going to go over a few examples I’ve found useful, but for a more detailed explanation of using Sitecore Query take a look at the Data Definition Reference, there is a Sitecore Query section that explains all the details!

So, a few useful tidbits:

* grabs all the children of a node: query:/sitecore/content/home/dessert/*  <--  the * grabs every child and / followed by text denotes the exact item name you’re looking at. So you could also mix this up a bit and return query:/sitecore/home/*/pie/* <-- this will grab all the items that have a parent pie from any item under home with the pie grandchild.

. references the context item, this can be handy if you need to find the ancestors, children or anything along the axes (if you need just the parent, use: .. ): query:./pies/* <-- if we were the dessert item, this would grab all the grandchildren with the parent pie.

// is the descendant axis – this should be used Very sparingly but can be done the following way: query:/sitecore/content/home//pie/* <-- this grabs all the items with a parent pie under home. So that would include, home/pie/*, home/anything/pie/* and so on. The fear with using this is that you’re going to return the whole tree or a whole section which might have thousands of items, so when considering using the descendant axis or any query, be mindful of the result set you will get.

@ denotes a field, and @@ denotes an xml attribute for the item, you’ll probably be using mainly @@templatename or @@templateid.

For example: query:/sitecore/content/home/dessert/*[@pastry=’1’] <-- this grabs all the items under desserts which have the checkbox ‘pastry’ checked (so it might return pies).

Sitecore query also supports the xpath axes, allowing you to use things like ancestor-or-self, following and preceeding (siblings) and so on:

query:./ancestor-or-self::*[@@templatename='Site']/Data/Touts/*

For a more practical example in a multisite solution, the above takes the current item, finds an ancestor or itself that represents the top ‘site’ item and then find the Data folder and then grabs all the children of the Touts folder.

Logical operators can be used to combine options as well, so we could look for query:./*[@@templatename='template1' or @@templatename='template2'] or something more like query:./pies/*|./cakes/* <-- this would give both children of pies and cakes instead of choosing one or the other.

There are also functions you can use (here’s a link with a listing of a number of useful functions), primarily I end up using: position(), last(), and contains()

To use them, you’d do something like query:./*[position()=1] <-- grabs the first item

query:./*[position()=last()] <-- grabs the last item

query:./*[contains(@ingredients,’apple’)] <-- grabs the items with ‘apple’ in their ingredients field, this could also be written as: query:./*[@ingredients = '%apple%']

To test out any query, you can always open up the developer center and then open the xpath builder. You do not need query: before your query but you do need to include fast: if you want to use the fast query.

These queries can become pretty complex depending on your needs, but that initial work can leave content editors with a very easy to use and understand set of items and fields. Leave a comment if you know of any good query examples or are wondering how to form a query to meet your needs (I’ll try to help)!


Categories: Sitecore
Posted by Amy Winburn on Tuesday, March 22, 2011 4:27 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Sitecore: Links as Items Redux!

Previously I had posted on how to set up items in your content tree to act as external links to other pages (for use with Navigation mainly – for example if you have a blog elsewhere but still want it listed in the main navigation). However, Ivan Buzyka pointed out some issues with the simple implementation so I added creating a better redirect to my ‘to do’ list for the blog. The time has come!

Let’s pretend we are modifying an existing site, we don’t want to change the navigation so that won’t be covered here – we just want to update our layout to work a little more universally. Our new items need to be able to link to an internal, external or Media item reliably for display in our navigation. Our template will consist of similar things to last time:

Link: General Link

Nav Title: Text -> standard values: $name

In Navigation: Checkbox ->standard values: checked

Create the template, add in standard values for it with the above settings and now we can create our Layout which should be assigned to the standard values of the new template.

In my layout is the following (inside the page load):

String url;
Item extItem = Sitecore.Context.Item;
LinkField extLink = (LinkField)(extItem.Fields["Link"]);
if (extLink != null)
{
  if (extLink.IsInternal && extLink.TargetItem != null)
  {
    url = Sitecore.Links.LinkManager.GetItemUrl(extLink.TargetItem);
  }
  else if (extLink.IsMediaLink && extLink.TargetItem != null)
  {
    url = Sitecore.StringUtil.EnsurePrefix('/', Sitecore.Resources.Media.MediaManager.GetMediaUrl(extLink.TargetItem));
  }
  else
  {
    url = extLink.Url;
  }
}
else 
{
  Item homeItem = Sitecore.Context.Database.GetItem(Sitecore.Context.Site.StartPath);
  url = Sitecore.Links.LinkManager.GetItemUrl(homeItem);
}
if (!String.IsNullOrEmpty(url))
{
   Response.Redirect(url);
}

To step through it: we’re setting the default to bring the user back to the home page just in case something goes wrong. From there, we check to see if the Link field exists and what type of link it is.

For an internal link, we grab the url for the item itself, and for the media item, we’re grabbing the url for the Media item to be displayed (or pdf etc.), and if it’s external – we’re just redirecting them to the url they specified.

If we stopped here, everything would be working great as long as the content was entered appropriately, however, that doesn’t always happen and we’d like to avoid this going boom. To do that we can add a simple validator: open up the content tree within Sitecore and then head to your template, expanding out the children and select the Link field item.

Scroll down to Validation in the Data section.

We want to make sure that the Link field is Always one of the following: and Internal link, a Media item, or an external Link. Also, we want it to have Some value.

Within Validation you’ll need to put the actual content you want to validate, and ValidationText is what will appear if that is not met. This will pop up when the user tries to save the item with an improper value.

validation

Shown above is the Validation and our error message: linktype is how we can determine what sort of link it is, and is generated automatically when a user selects their link (unless they are editing raw values). Our validation just makes sure that the linktype text contains one of those three options (internal, media, or external) and as long as one of those match the text in the raw value for the field we have a valid link.

This helps prevent a scenario where the user has used one of the other options for an external link which would stop the page from going anywhere.

You can also add in some of the default validation options – I'd recommend adding the Required field validator as well.


Categories: Sitecore
Posted by Amy Winburn on Thursday, February 24, 2011 6:10 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Sitecore: Adding your own Icons

Items can be configured to have an icon – and Sitecore provides an extensive list of them. But you may want to add your own for whatever reason. To do this you’ll need an image suitable for making into an icon, and the ability to resize this image to the correct sizes (Paint.net, Photoshop, GIMP).logo

For our example we’re making an Arke Icon and we're going to say our largest icon will be 128x128, so we have a transparent png called logo.png to work with: 

The image you want to use should have a transparent background unless you want the icon to be a square, and ideally not overly detailed as it will be very small.

Next, we need to make this image into various sizes, and put logo.png into the appropriately named directories, the structure is as follows (if you have several icons, just do the same thing by putting multiple icons into each size folder):

  • ArkeIcon
    • 16x16
      • logo.png
    • 24x24
      • logo.png
    • 32x32
      • logo.png
    • 48x48
      • logo.png
    • 128x128
      • logo.png

Zip this all up with the same name as the containing folder, so ArkeIcon.zip

Upload this new zip file to /sitecore/shell/Themes/Standard/ and make sure the permissions are correct for your installation (check the other files such as Application.zip for a comparison).

Back within your content editor: each item has an Icon field and you can now enter in your custom icon by entering: ArkeIcon/16x16/logo.png

Once you do this, the new icon will show up in the list of recently used icons as well.

As for adding the new icon set to the list of usable icons – that’s a little more tricky since the list is specified statically (if you know a good way of changing this please share).

You can however modify the existing sets/zips of images, such as the aforementioned application.zip – just add your image to the appropriate directories and you can use it just like all the other icons!

Posted from: Amy's Sitecore Adventures


Categories: Sitecore
Posted by Amy Winburn on Friday, February 18, 2011 5:52 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Sitecore: Setting and Customizing the Rich Text Field Editor

This is well documented in the Sitecore documentation and elsewhere, but I always forget where so this post is definitely for my own benefit (and anyone else like me who doesn’t know where to look right away).

There are two ways of changing around the rich text editor that I’ll cover, I’ll start with the easier one:

1. Setting the source property for the rich text field on your template

templatesource

 

I was pretty thrilled to learn this, just go into your content editor or template manager, open up the template with the rich text field that you want to set this for and choose one of the following options as the source (in italics).

Rich Text Default:

/sitecore/system/Settings/Html Editor Profiles/Rich Text Default

This is the default (shocking!) and the control portion looks like the following:rtdefault

Rich Text Full:

/sitecore/system/Settings/Html Editor Profiles/Rich Text Full

This is a much more filled out editor shown below:

rtfull

Rich Text Medium:

/sitecore/system/Settings/Html Editor Profiles/Rich Text Medium

This is the middle of the road editor, more than just the default and less than the Full version.

rtmedium

Our next method of changing the rich text editor comes about when the above (or the ones not listed: IDE, Mail) do not meet your needs, or if they Almost do but need to be adjusted.

2. Modifying the default rich text editor

To do this you need to switch to the Core Database – at the bottom right in Desktop view is a little grey icon: click that and choose Core from the popup.

Once the screen refreshes open up the Content Editor and we need to browse to the HTML Editor Profiles (the paths above are where we are going). If you want to change the properties of the default editor for all rich text fields Copy the Rich Text Default and rename it (just in case!) and then you can pick and choose items from the other Profiles – just copy them over to the Rich Text Default item.

rtfull-folder As seen on the left there are a number of folders and then sets of toolbars: the toolbars are where the magic is at and the folders contain data that can be displayed and modified.

For example, you can change the inline styles that are available by selecting the inline style item, and then changing the children (or adding new children for your own custom styles).

If you wanted to add Inline styles to your Rich Text Default you can do the following: make sure to copy the Inline Styles folder to Rich Text Default, and then make sure to add the drop down option for css (called Css Class in Toolbar 3 from Full) to the toolbar in Rich Text Default.

Each toolbar is separated by a solid line around it or displayed on a new row on the edit screen and you can add, copy, modify or rearrange items as you wish like any other set of items. They can be deleted as well, so it’s always a good idea to keep a copy of the profile you’re editing if something goes wrong.

I hope that helps anyone else who has wanted to make changes to the default rich text editor and wasn’t sure where to begin!

 

 

 

 

Posted from: Amy’s Sitecore Adventures!


Categories: Sitecore
Posted by Amy Winburn on Wednesday, October 13, 2010 1:11 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Sitecore: A Simple Site Map

Similar to creating a menu – creating a site map is even easier, there are modules that can do this but with a little preparation it can be very easy to create yourself.

To start we are assuming every template used for the pages includes some ‘base template’ for common aspects for all pages.

To do this, create (or select if already created) the Base Template with the information you want to have and to that base template, add:

InSiteMap: Checkbox

Then create or modify the Page templates with the other information you want. From those templates, click to the Content tab, and select the Base template to be included:

 

sitecoretemplatecontent

In the Standard values for the base template, you may want to have InSiteMap checked so that it will be on by default for all the pages.

For the sitemap itself, we’re going to create a rendering and then we can place it wherever we would like.

The rendering creates a basic nested list of all the items that have InSiteMap checked.

<xsl:template match="*" mode="main">
    <ul>
      <li>
        <sc:link select="$home">
          Home
        </sc:link>
        <xsl:variable  name="hasSubItems" select="$home/item[sc:fld('InSiteMap',.) = '1']"/>
        <xsl:if test="$hasSubItems">
          <xsl:call-template name="subitems">
            <xsl:with-param name="itemparent" select="$home" />
          </xsl:call-template>
        </xsl:if>

      </li>
    </ul>
  </xsl:template>

  <xsl:template name="subitems">
    <xsl:param name="itemparent" />
    <ul>
      <xsl:for-each select="$itemparent/item[sc:fld('InSiteMap',.) = '1']">
        <li>
          <sc:link>
            <sc:text field="Page Title" />
          </sc:link>
        </li>
        <xsl:variable  name="hasSubItems" select="item[sc:fld('InSiteMap',.) = '1']"/>
        <xsl:if test="$hasSubItems">
          <xsl:call-template name="subitems">
            <xsl:with-param name="itemparent" select="." />
          </xsl:call-template>
        </xsl:if>
      </xsl:for-each>
    </ul>
  </xsl:template>

Above we list the link to the home item in an unordered list:

 <sc:link select="$home">
    Home
 </sc:link>

<sc:link> with no parameters will link to the current item that is being processed by the xslt file – if not specified by any settings this will default to the page that the rendering is on. Since the current page is Not actually the home page, we are choosing to use $home as the source for the link (if the source for the link was actually in a field in the item you’d used field=”field name”).

 

Moving on, if there are any items under home that are listed as ‘InSiteMap’ it will call our template named subitems and pass the value for the parent of the item.

        <xsl:variable  name="hasSubItems" select="$home/item[sc:fld('InSiteMap',.) = '1']"/>
        <xsl:if test="$hasSubItems">
          <xsl:call-template name="subitems">
            <xsl:with-param name="itemparent" select="$home" />
          </xsl:call-template>
        </xsl:if>

 

Here the variable hasSubItems is created and the value for this is determined by any items within $home containing the field InSiteMap being checked (=’1’ – unchecked would be =’0’).

If we have any items that will be in the sitemap under $home, we call our template.

Within the template, we create a new unordered list, and then go through each item which will be listed in the site map and display a link using the ‘Page Title’ (this is any field that we want to have displayed to represent the item). We then check to see if we have any subitems to display and run the template again! With a bit of recursion, we head through all the items on the site as long as they and their parents have InSiteMap checked.

All that is left is adding the rendering to a page to be seen, and it will display a nested list of the pages on the site to be styled as needed!

Alternately, instead of checking for a selected checkbox, it could run through all pages with a specific template(or selection of templates) if you did not need to worry about excluding any specific pages that are using it.


Categories: Sitecore
Posted by Amy Winburn on Friday, June 4, 2010 5:29 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Sitecore:Web Forms for Marketers: Send Email

To have the save action for your form actually send email, you will need to change one of the settings, otherwise you will receive this error whenever submitting the form:

We experience a technical difficulty while processing your request. Your data may not have been correctly saved.

Also in your log (/data/logs/newest log file) you will see this error after the form has been submitted:

Exception: System.Net.WebException
Message: The remote name could not be resolved: 'example.host'
Source: System
   at System.Net.ServicePoint.GetConnection(PooledStream PooledStream, Object owner, Boolean async, IPAddress& address, Socket& abortSocket, Socket& abortSocket6, Int32 timeout)
   at System.Net.PooledStream.Activate(Object owningObject, Boolean async, Int32 timeout, GeneralAsyncDelegate asyncCallback)
   at System.Net.PooledStream.Activate(Object owningObject, GeneralAsyncDelegate asyncCallback)
   at System.Net.ConnectionPool.GetConnection(Object owningObject, GeneralAsyncDelegate asyncCallback, Int32 creationTimeout)
   at System.Net.Mail.SmtpConnection.GetConnection(String host, Int32 port)
   at System.Net.Mail.SmtpTransport.GetConnection(String host, Int32 port)
   at System.Net.Mail.SmtpClient.GetConnection()
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
WARN  Web Forms for Marketers: an unhandled exception: Failure sending mail. has occured while trying to execute an action.

In your content tree, browse down to: /sitecore/system/Modules/Web Forms for Marketers/Settings/Actions/Save Actions/Send Mail

Under that item there will be a submit section with parameters:

wffmpara

Just replace example.host with your SMTP host information for the server, and form@example.host with the address you want to send mail from – save, and republish!

That should correct the error above and, barring any other issues, hopefully the form will be working as intended!


Posted by Amy Winburn on Tuesday, May 18, 2010 6:16 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Sitecore: External and Internal Links as Items

I ran into a problem creating the navigation for the footer rendering on a page – On there I needed to have links to the following pages: terms, contact, careers, and the sitemap. The problem arose when trying to add ‘Contact’ and ‘Careers’: ‘Contact’ was a few levels down in the tree of content items and ‘Careers’ was an external page. Initially, I had a checkbox in the template of each page for if the item was in the footer (ie: InFooterNav checked) and then the XSLT file would go through the entire list of items to find what would be in the footer navigation. It wasn’t an ideal solution when so few items had the tag in the entire site and it did not help with my external link at all. Thus was born: The Link Template!

The new template basically consisted of:

Link Data:

  • Link: General Link //This is the link to our item or the URL for the external page
  • Nav Title: Single Line Text //The title we want to have displayed in our menu – this is the same as in my regular items
  • Target: Single Line Text (or a drop down list) //The target if we want to open the page in a new window

Properties:

  • InFooterNav: Checkbox //Just a checkbox to see if this link is going to be in our footer, this is the same as regular items.

Within the Standard Values I assigned a new layout for the items with the following code within:

<% Sitecore.Data.Items.Item item = Sitecore.Context.Item; 
   Response.Redirect(((Sitecore.Data.Fields.LinkField)item.Fields["Link"]).Url); %>

The above redirects the user to whatever URL was provided within the “Link” field.

I then created a bunch of items with the appropriate links in the folder where other footer only type items also lived – for our example let us say “/sitecore/content/Home/Footer/”

To retrieve my footer items I now only had to check that folder and not search the entire site to actually see if the box is checked.

And a little more useful - using this template, I could put a link to any external page under any item – allowing me to have external links within my navigation such as Careers.

The above layout will work fine for my footer, but what if you wanted links to open in other windows? Or didn’t want to take the extra step of creating a layout? The rendering can be changed to make use of our new template:

    <ul>
      <xsl:for-each select="$home/Footer/item[sc:fld('InFooterNav',.) = '1']">
        <li>
          <xsl:choose>
            <xsl:when test="@template = 'link template'">
              <xsl:variable name="linkTarget" select="sc:fld('Target',.)" />
              <sc:link field="Link" target="{$linkTarget}" >
                <sc:text field="Nav Title" />
              </sc:link>
            </xsl:when>
            <xsl:otherwise>
              <sc:link>
                <sc:text field="Nav Title" />
              </sc:link>
            </xsl:otherwise>
          </xsl:choose>
        </li>
      </xsl:for-each>
    </ul>

Above we have a choose statement to determine if this is using the new link template or not (called “Link Template” but listed in lowercase):

<xsl:when test="@template = 'link template'">

 

Then we create a variable for our target and create the link based on our General Link field called “Link” by specifying it for field:

<xsl:variable name="linkTarget" select="sc:fld('Target',.)" />
<sc:link field="Link" target="{$linkTarget}" >
  <sc:text field="Nav Title" />
</sc:link>

 

Otherwise if it is a normal item in the tree, we give it a normal link and continue to the next item!

<xsl:otherwise>
   <sc:link>
     <sc:text field="Nav Title" />
   </sc:link>
</xsl:otherwise>

Categories: Sitecore
Posted by Amy Winburn on Thursday, May 13, 2010 2:41 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Sitecore: A Simple Single Level Menu with Rounded Edges

After taking some time to figure this out, I thought I’d share my approach to a simple single level menu rendering with rounded edges. Initially, the idea here is very straight forward – create a list, style it, voila! Unfortunately, Round edges and dynamic content make it a little less forgiving.

Here is an Example of what we are trying to achieve:

menubar

Each of these items would be a sub item in the site, all at the same level  under ‘/Sitecore/Content/Site’

In our XSLT  rendering we need to grab the list, and apply the appropriate styles to the appropriate items, notably: The first item needs to have a round corner on the left, the Last item needs to have a round corner on the right, and the inner items need to have borders around them all – and we need to be able to Hover for a different effect.

To do this I did the following:

<xsl:template match="*" mode="main">
  <ul id="MainNav">
    <xsl:for-each select="$SiteContent/item[sc:fld('InTopNav',.) = '1']">
      <xsl:variable name="EdgeClass">
        <xsl:if test="position()='1'">FirstItem</xsl:if>
        <xsl:if test="position() = last()">LastItem</xsl:if>
      </xsl:variable>
      <xsl:if test="position() = last()">
        <li class="preLastItem">
          <span>.</span>
        </li>
      </xsl:if>
      <li class="{$EdgeClass}" >
        <span>
          <sc:link >
            <sc:text field="Nav Title" />
          </sc:link>
        </span>
      </li>
    </xsl:for-each>
  </ul>
</xsl:template>

The above runs through every item which has InTopNav checked in that level (if you had /SiteCore/Content/Site/Home and then all the items under Home, it would be a bit different)

In terms of what happens when this runs:

1. First item is read and link displayed -- given the “FirstItem” class.

2. 2nd item is read -- link is displayed with No class assigned.

N. Last item is read: $EdgeClass is now “LastItem”, list item with a period is displayed followed by the list item for the last link -- given the “LastItem” class.

All that is left is styling the menu: I created extra wide images for the left rounded edge, right rounded edge and the general middle links so that they could overlap and slide around depending on the length of the text and set them as the background images for the links (ie: #Menu li.FirstItem a).


Categories: Sitecore
Posted by Amy Winburn on Tuesday, May 11, 2010 11:09 AM
Permalink | Comments (0) | Post RSSRSS comment feed