Bartłomiej Mucha
Bartłomiej Mucha

Reputation: 2782

how to manage presentation details for multiple pages in single place

I have following item structure in sitecore:

Items can be accessed by urls:

This items renders tabs for user and user can click tab and switch to other tab. On /root first tab is active.

Items have a few placeholders: header, footer, content, aside, and tab.

All this items have to render same controls for all placeholders except "tab" placeholder. Tab placeholder could have different controls, so you will see different things on each tab.

Easy solution for this is to ask client to edit controls on all this items. For instance if he want's to add image above tabs, he will have to add this image on all items: Root, Tab 2, Tab 3, Tab 4.

But I need another solution to this, so client could edit controls in one place. But could have separate controls for each tab.

UPDATE:

I will be using ajax request for switching tabs, but also regular GET request should work for this tabs and urls for tabs should be as above. Of course I can specify initial set of controls on _Standard Values for template, but when editor change something inside page editor this should reflect on all tabs.

So far I come up with following solution (but editing in page editor in not working for all tabs but root one):

I crated processor inside pipeline (after: Sitecore.Pipelines.InsertRenderings.Processors.GetItem):

public class SetRootTabAsContextItem : InsertRenderingsProcessor
{
    /// <summary>
    /// Processes the specified args.
    /// </summary>
    /// <param name="args">The argumentss.</param>
    public override void Process(InsertRenderingsArgs args)
    {
        Assert.ArgumentNotNull(args, "args");

        var contextItem = Context.Item;
        if (contextItem.IsInsideRootTab())
        {
            args.ContextItem = Context.Item.GetRootTabItem();
        }
    }
}

I also created additional placeholders for all tabs: tab_1, tab_2, tab_3. Inside tab placeholder there is sublayout that has all this additional placeholders in it but is displaying only placeholder that should be visible on specific tab.

So all tab's presentation details are now configured on root tab. Thanks to this processor that I created controls from root tab are rendered on all tabs.

But sadly page editor is working only on root tab. When I'm trying to add control from page editor when I'm on not root tab, I'm getting javascrip error, some null reference.

Upvotes: 0

Views: 954

Answers (3)

jammykam
jammykam

Reputation: 16990

Another option would be to use a jQuery/JavaScript based tab plugin (something like jQuery UI Tabs). In your "root" Item add your tab control, which renders the required HTML markup (to match the spec of your Javascript Tab plugin).

The Tab control should look at it's datasource value or if that is not set then iterate over it's own children with a specific template. You need to decide where this is best placed. Sometimes it is in a global shared folder, sometimes it is directly beneath the content item (putting it in folder in case there is sub-navigation number this page)... Both have advantages and disadvantages, but it comes down to a design choice based on requirements and preference.

Your url's would slightly change, you would be using hashes instead of specific paths but the end result would be the same. You can see a good example of that on the Tab page I linked to.

  • /root
  • /root#tab-2
  • /root#tab-3
  • /root#tab-4

So the rest of your page is exactly the same. Also, an advantage of this is that there is no page reload in order to show the content.

Remember to design your component with Page Editor in mind, the Javascript sometimes plays a little bit of funkiness with the additional markup Sitecore injects in, but you can Detect Page Mode in Javascript.

EDIT:

Personally I would not bother with the AJAX load unless there is large amounts of data present in the tabs, but that is your call.

An alternative would be to insert a processor after ItemResolver, which checks if the current request is for a Tab template. If so, set Context.Item to the parent. You can then switch to the correct tab using some Javascript to extract the last part of the current URL (which should be the same as your tab id). If you use the correct controls and set the Item on those correctly then PageEditor should also work.

It get's tricky if you need to AJAX load your tab data, since request a tab URL would redirect the user (essentially). You could pass an additional parameter in your AJAX call, something like ?request=ajax or check the request type. The processor could skip it's logic and return the tab content instead. This of course will not work in PageEditor, so instead you would need to add some logic into your sublayout to check if the Page is in editing mode which would fall back to NOT using AJAX.

Upvotes: 1

RobertoBr
RobertoBr

Reputation: 1801

My first option would be the usage of Components to accomplish that. The Header, Footer, Content and aside could be components that share the same datasource, and the tab could be a component that is added to the page.

Some posts about Components:

http://www.nonlinearcreations.com.br/Digital/how-we-think/articles/2014/03/4-patterns-Sitecore-component-development.aspx

http://johnnewcombe.net/blog/sitecore-part-2

You should google it as well...

Another option - which I don`t like too much - would be the use of Alias. You could have a single page with multiple Alias and then you could use a Sitecore personalization based on the request url to determine which datasource your tab component is pointing to.

Upvotes: 0

Anton
Anton

Reputation: 9961

It could be solved by inheritance all tabs(tab-1, tab-2, tab-3) from one template: tab. Then you can set presentation for __Standard Values of tab template. Then you will have ability to change only required controls on tab items.

Upvotes: 0

Related Questions