Should I use tcdl, Tridion tag, or RenderComponentPresentation? - tridion

Managing a "Global" Logo with Tridion
To manage, for example, a website-wide logo and its text elements with SDL Tridion, I'd want it in a component, rendered by a (dynamic) component template, and placed by page templates. My requirements would include:
Logo as a Component--image as a multimedia (mm) component and link, alt (i.e. "home"), and other text in an optional container component
Dynamic Component Presentation (DCP)--ability to manage logo's markup presentation and publish changes without requiring publishing every page
Share-able--ability to localize multimedia and text in components, rather than templates, in lower publications
Authors shouldn't need to place the logo as a component presentation (CP) on every page, although a logo CP just on the homepage could offer dynamic linking.
RenderComponentPresentation(), TCDL, or Tridion tags for "Non CPs"
For this CP-less approach, I think RenderComponentPresentation() or TCDL tag would be the right "agnostic" approach. Is one preferred over the other?
For example, my template outputs:
<h3>By tridion: (ASP.NET) tag</h3>
<tridion:ComponentPresentation runat="server"
PageURI="tcm:7-1535-64"
ComponentURI="tcm:7-1533"
TemplateURI="tcm:7-1532-32"/>
<h3>By tcdl: tag</h3>
<tcdl:ComponentPresentation
PageURI="##Page.ID##"
type="Dynamic"
ComponentURI="tcm:7-1533"
TemplateURI="tcm:7-1532-32"/>
<h3>by render component presentation</h3>
##RenderComponentPresentation('tcm:7-1533','tcm:7-1532-32')##
These get transformed to the following on the file system.
<h3>By tridion: (ASP.NET) tag</h3>
<tridion:ComponentPresentation runat="server"
PageURI="tcm:7-1535-64"
ComponentURI="tcm:7-1533"
TemplateURI="tcm:7-1532-32"/>
<h3>By tcdl: tag</h3>
<tridion:ComponentPresentation runat="server"
PageURI="tcm:7-1535-64"
ComponentURI="tcm:7-1533"
TemplateURI="tcm:7-1532-32"/>
<h3>by render component presentation</h3>
<tridion:ComponentPresentation runat="server"
PageURI="tcm:7-1535-64"
ComponentURI="tcm:7-1533"
TemplateURI="tcm:7-1532-32"/>
Each renders delivery-side so the user sees the correct CP in the browser.
Question(s):
Any approach gets us a DCP referenced from a PT with an agnostic format that gets retrieved presentation-side, avoiding full-site publishing. It's not really on the page so we have to be sure to publish the logo with a dynamic CT (it's html fragment in this case). Am I missing anything?
Is RenderComponentPresentation() preferred over TCDL or a specific presentation-side syntax? Any reason I'd actually want <tridion:ComponentPresentation runat="server"> instead?
Edit: I was missing the Type="Dynamic" attribute and value, also for a moment thought RenderComponentPresentation didn't create the right CP reference.

Basically you have answered your first question yourself already I think, apart from how you want to write it out in your template you have your DCP there.
My preference would be to use ##RenderComponentPresentation('tcm:7-1533','tcm:7-1532-32')## but I would actually not use it with hardcoded TCMURIs. I'd probabaly write a TBB which reads the Multimedia Component TCMURI and its Template URI somewhere from for instance a configuration Component or the Publication metadata, then your template could look something like:
##RenderComponentPresentation(${LogoUri}, ${LogoTemplateUri})##
When using Dreamwever TBBs for your layout, I would use this as a preference. If you are using another way of layout, then the next best thing would be to use the TCDL tag. Indeed to try and keep your templates code agnostic. The only time I would ever revert to writing out the tridion control code myself, is when I cannot get it there another way.

Related

Kentico ASPX+Portal templates not registering zones in database

In Kentico I'm using ASPX+Portal model created a template as a webform on disk with a single widget zone as follows:
<asp:Content id="content" runat="server" ContentPlaceHolderID="content">
<h1>Home: <%= this.PageModel.DisplayTitle %></h1>
<cms:CMSPagePlaceholder ID="plcZones" runat="server">
<LayoutTemplate>
<cms:CMSWebPartZone ID="zoneEditorContent" runat="server" ZoneTitle="Page content" WidgetZoneType="Editor" />
</LayoutTemplate>
</cms:CMSPagePlaceholder>
</asp:Content>
I then registered this in Kentico's Page templates module.
Pages using this template would now show the zone on the Page tab but wouldn't let me add widgets to it. I could browse the widget library, select a widget, set its properties, save and close the dialogue, but the page would refresh remaining empty.
After some dabbling I discovered that the relevant template record in database table [dbo].[CMS_PageTemplate] had its [PageTemplateWebParts] property set to the value '<page />'.
I discovered that changing this to '<page><webpartzone id="zoneEditorContent" v="1" widgetzonetype="editor" /></page>' resolved the problem. I could now add widgets to the zone on the Page tab.
My question is, what am I doing wrong here? I presume I'm not supposed to set this database field manually. Should Kentico be doing this automatically, and if so, what step am I missing to make this happen? I believe I've followed Kentico documentation accurately.
You are not doing anything wrong. I have to agree this is weird behavior but it is not possible (= does not take any effect) to set WidgetZoneType property in markup. You need to set it manually via admin UI (zone properties). If this is issue for you consider to add it to Kentico`s User voice.
YMHO I think you are right and it should be at least mentioned in doc that it is not possible to use this property in markup.
EDIT: My bad, please note it is mentioned in the docs, too:
Changing the WidgetZoneType property directly in layout code does not save the changes in the database. You need to set the Widget zone type property by configuring the zone properties.

How to set control properties in css?

Is there a way to set this kind of properties in css?
So I can use the same calendar and be more organized with my code
<asp:Calendar ID="Calendar1" runat="server" Height="189px" CssClass="Calendar"
ondayrender="CalendarRender" TitleStyle-BackColor="#00718F" TitleStyle-ForeColor="White" ShowGridLines="true" TitleStyle-BorderStyle="Solid" TitleStyle-BorderWidth="1px" TitleStyle-BorderColor="Black" SelectedDayStyle-ForeColor="#281dc9" SelectedDayStyle-Font-Bold="true" DayHeaderStyle-BorderColor="Black" DayHeaderStyle-BorderWidth="1px" DayHeaderStyle-BorderStyle="Solid"
onselectionchanged="Calendar1_SelectionChanged"></asp:Calendar>
Assuming you're talking about properties such as:
TitleStyle-BackColor="#00718F" TitleStyle-ForeColor="White"
... etc..
Your best bet would be to render the calendar to a page, check its source and see what style it adds. You can then extract this out for use in CSS.
UPDATE
This page has some of the selector names for you, along with what they control ASP.Net Calendar Control Custom Theme Format using CSS
If you want to be more organized, and don't want your project to become like 'spaghetti' in future, use CSS file for css properties. Do not embed this properties in headers, unless this is the only way to solve current issue. This is bad for you, and for all who will work with your project.
I've met lot of legacy projects, wasting too much time to find why some dom element's behaviours differs from what I need.
Just specify CssStyle property in your aspx markup, and it will be mapped to real css class.
And add description for this class in css file.

Custom Content Block in Sitefinity

I want to create a custom content block in Sitefinity so I can wrap an tag around it and pick up my CSS.
I created a custom widget, but I'm not sure how to make it a content block. I cannot find documentation on this, but I'm sure it is a common occurrence. Basically, I want a drag out content block that does this:
<aside>
[code for content block]
</aside>
I don't know how to generate the [content block] code in .net. I am new to .net development. I am using VB but can use C#.
Any help would be greatly appreciated. Thank you.
Maria
You can create a custom Layout Control which can be used in conjunction with other controls, such as Content Blocks.
To create a Layout control, open your project in Visual Studio and create a new control (.ascx) file in the WebApp project. I normally put mine in a ~/LayoutControls folder which I create. In that control file, enter something like:
<div runat="server" class="sf_cols">
<aside>
<div id="Div1" runat="server" class="sf_colsIn"></div>
</aside>
</div>
You'll notice that besides the markup you want, the aside tag, I have two other divs with some specifics. These are needed so Sitefinity can treat this as a control, and be able to dynamically inject content into it.
A div with class sf_cols is common to all controls and the div with class sf_colsIn (id="Div1") is where control you drop onto the layout control will go. So there is an outer wrapper div, your markup, and an inner div. It's the inner div where your content will go.
Save your file, compile the project, then register the control in Sitefinity.
To do that, login to the backend then navigate to Administration | Settings | Advanced Settings | Toolboxes | Toolboxes | PageLayouts | Sections. I normally add a new section with these properties:
name=Custom,Title=Custom,Description=Custom Layouts,Global resourceClassId=PageResources
Then select your new section, select Tools, then Create New. The Name, Title, Description are whatever makes sense for you control. The Control CLR Type should be Telerik.Sitefinity.Web.UI.LayoutControl, Telerik.Sitefinity and the Layout Template should be the path to your ascx file, i.e. ~/LayoutControls/AsideBlock.ascx. The other properties can have the default values (most are just blank). Then Save.
Now when you are editing a page, click the 'Layout' button in the right hand column and you will see a 'Custom' Section which contains your control. Drag it onto the page, then go back to 'Content' editing (using the button in the right hand column). You will see your layout control and drop a content block onto it.
Add content normally. When the page renders, the content will be wrapped in the aside tag.
the easiest way to do this is with an external template for the content block. The template you want is ContentBlock.ascx and is in the SDK.
Copy this file to your project then add the wrapping tags around the contentHtml literal control (which renders the actual content of the control).
Then open the Advanced settings of the content block widget you want to use this template and specifiy the LayoutTemplatePath. It should have a default value of something like "~/SFRes/Telerik.Sitefinity.Resources.Templates.Backend.GenericContent.ContentBlock.ascx".
Simply change this to the virtual path to the template you created, then save and publish the page.
The content block will render with your template instead of the default one, with any markup you add.
I hope this is helpful!
I'm going to create a more detailed blog post that walks through this process and will link it here when I'm done. thank you for the inspiration!

How to use SiteEdit in DD4T in Tridion

Can anyone direct me on how to use SiteEdit specific syntax or tags in the Razor template in DD4T code? I have seen Site Edit related classes in it, but could not understand how to use SiteEdit tags in the view where there were some syntax similar to Dreamweaver for example RenderComponentField or tcdl:ComponentField which we used in Dreamweaver. I am very new to DD4T and am using SiteEdit 2009 SP3 and SDL Tridon 2011 SP1.
Thanks in advance.
Update: We have tried the implementation mentioned in the answer but unfortunately we are getting an error when we are accessing the page in proxy stating "Invalid template -The HTML is invalid, probably because your template code produces invalid HTML, such as a p tag inside another p tag. Check your HTML using a validator such as the W3C Markup Validation Service, correct your template, and republish."
I guess this is because Xml content is being pushed into html page due to the use of Dynamic Page and Component TBBs which we used in our Component and Page Templates.
Let us kow how to continue further.
The SiteEdit markup is not generated like it is done in a Dreamweaver Template, you are responsible yourself to place the markup for your editable fields in the Razor view. Good thing for this is that it works for similar for SiteEdit 2009 SP3 and UI 2012. Downside for UI 2012 is that it is not listening (yet) to the Enable Inline Editing which you can set on the Component or Page Templates (something we should consider for a future DD4T version).
Everything is based on the DD4T SiteEditHelper class. You start in your page view (before the </body> tag) by placing the following call:
#Html.SiteEditPage(Model)
This will write out the page markup, and if you set the style to "SiteEdit2012" in your SiteEdit_config.xml it will also write out the bootstrap script required for UI 2012.
Then for every Component Presentation and every editable Component Field you will also need to add the appropriate markup. For a Component presentation you can use:
#{var ComponentPresentation = ViewBag.ComponentPresentation as IComponentPresentation;}
<div>
#Html.SiteEditComponentPresentation(ComponentPresentation)
</div>
Make sure you write this out inside a DIV or some other element that can mark the boundary of your Component Presentation. For Component Fields a similar story, you can use:
<div>
#Html.SiteEditField(Model, Model.Fields["FieldName"])
#Model.Fields["FieldName"].Value
</div>
Apart from the changes to your views, as Bart has described, you also need to put a configuration file in the root of your web application, called SiteEdit_config.xml. It should look like this:
<?xml version="1.0" encoding="utf-8" ?>
<siteEdit enabled="true" tridionHostUrl="http://tridion.my.com">
<contextPublications>
<contextPublication id="10" componentPublication="3" pagePublication="9" publishPublication="10" />
<contextPublication id="11" componentPublication="3" pagePublication="9" publishPublication="11" />
</contextPublications>
</siteEdit>
You must list all your active publications here. DD4T tries to match your current page to the correct context publication (based on the 'id' attribute). If it cannot find it, SiteEdit will be disabled. The other attributes allow you to control the behaviour of SiteEdit.
componentPublication: new components will be created here
pagePublication: new pages will be created here (not used in Tridion UI 2012)
publishPublication: pages and components will be republished from this context (usually coincides with the id)
DD4T can also easily be configured for use with Tridion UI 2012. Just change the first element in the configuration as follows:
<?xml version="1.0" encoding="utf-8" ?>
<siteEdit enabled="true" style="SiteEdit2012" tridionHostUrl="http://tridion.my.com">
...
</siteEdit>

How can I add properties/attributes to an HTML markup container tag in ASP.Net

I've seen all of the usual pages with information about how to create a sub-tag that allows content within a user control (using ITemplate and INamingContainer) but I've yet to see anyone able to add properties that become attributes to said tags, for example:
<asp:MyControl runat="server" ID="myControlTest" SomeAttribute="SomeValue">
<Content ContentAttribute="Something">
Blah
</Content>
</asp:MyControl>
If you see the ContentAttribute on the Content tag, that is what I'd like to be able to achieve, but if I set it all up using ITemplate and INamingContainer etc, I can add a property that does in fact appear in Intellisense for that tag but when I run the code, it says Content does not have property/attribute named ContentAttribute (it also gives the same as a warning in VS IDE but still allows me to compile it).
I have tried everything to make this work and so far the only way seems to be if I make the Content property on MyControl a class that inherits from System.Web.UI.Control and implements ITemplate. That works but unfortunately I have to specify the runat attribute on the Content tag (because it sees it as a control rather than a sub-tag) and I'd rather not do that if possible.
Hope I have explained this well enough, if I haven't please let me know and I'll do my best to elaborate further.
Thanks in advance.
I think what you're proposing is something like a MIME email where there are a variable number of sections, each with an identifier for the client to choose the best version of the email it can handle. I assume you're wanting to select the appropriate template at runtime, based on that attribute.
The standard .NET controls don't implement that way, so far as I can tell. Think of the Repeater which has:
<asp:Repeater id="myRepeater" runat="server">
<HeaderTemplate>...</HeaderTemplate>
<ItemTemplate>...</ItemTemplate>
<FooterTemplate>...</FooterTemplate>
</asp:Repeater>
Each of the subitems (templates) has a different name, not the same name with a separate attribute.
Is there any way for you to define, ahead of time, what all of the possible sections might be, the way the repeater does?
<asp:MyControl runat="server" ID="myCtlTest">
<SomethingTemplate>Blah</SomethingTemplate>
<OtherTemplate>Blah</OtherTemplate>
</asp:MyControl>
I'm guessing not but wanted to throw it out there in case.
Alternately, could the ContentAttribute move to MyControl? The SETter would then load/build the template for you depending on the value.
<asp:MyControl runat="server" ID="myCtlTest" ContentAttribute="Something">
<Template></Template>
</asp:MyControl>
...or it could be loaded with a method instead of using the property SETter.
If you will always need multiple templates, perhaps a combination of those two concepts would help.
<asp:MyControl runat="server" ID="myControlTest"
SomethingTemplate="Something"
OtherTemplate="Other">
<SomethingTemplate></SomethingTemplate>
<OtherTemplate></OtherTemplate>
</asp:MyControl>

Resources