.NET usercontrol code-behind not rendering inside XSLT Umbraco macro - xslt

I have a XSLT macro that renders some markup and .NET usercontrol macros in a loop. So thats multiple usercontrol macros inside a xslt macro:
<xsl:for-each select="$node/* [#isDoc]">
//Some markup etc...
<xsl:value-of select="umbraco.library:RenderMacroContent('<?UMBRACO_MACRO NodeId="#id" macroAlias="LogTag"></?UMBRACO_MACRO>', #id)" disable-output-escaping="yes"/>
</xsl:for-each>
The markup from the usercontrols markup is rendered just fine, but everything in the Page_load is not executed. Why is that?
Heres the usercontrol markup:
<div class="logTag" id="Tag" runat="server">
<img src="someimage.png" alt="image"/>
</div>
And code-behind:
public int NodeId { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)return;
var tools = new Tools();
var userId = (Int32)Membership.GetUser().ProviderUserKey;
Tag.Visible = tools.GetLog(NodeId, userId);
Response.Write("Node=" + NodeId + " - User=" + userId + "<br />");
}
Neither the Response.Write or Tag.Visible is working. I've tried testing the usercontrol macro directly on a blank - works fine! Is this not possible, or am I doing something wrong?

Unfortunately due to the nature of XSLT macros and where the render event is called in the page lifecycle means that the library.RenderMacroContent() method will not work inside XSLTs.
There is a workaround discussed on Hendy Racher's blog which is used to create "widgets" functionality, if this is what you are after. This utilises an ASP.NET repeater which injects the usercontrols at the correct phase of the page cycle to allow usercontrol macros to work. Otherwise, use the Macro Container datatype in Umbraco 4.7 and upwards, which allows drag-drop functionality of macros inside the Umbraco backoffice, and can be successfully rendered (usercontrols, Razor or XSLT) using an <umbraco:Item /> tag.

Related

How to create html with link-to property inside custom jquery plugin?

I have a custom jquery plugin that use to create drop down html for a search box.
Inside that, html is created as follows.
$.each(stack, function (i, stackItem) {
var url = _getItemURL(stackItem, lang);
if (stackItem.INS !== undefined) {
html += '<li class="row"> ' + stackItem.DS_HIGHLIGHTED + ' - ' + stackItem.E + '<br>' + stackItem.TICKER_DESC + ' </li>';
} else {
html += '<li class="row"> ' + stackItem.COMPANY_DESC_HIGHLIGHTED + '<br>' /*+ _getCountry(stackItem.CC, lang)*/ + ' </li>';
}
itemCount++;
});
As you can see href attribute is used to create links in this html. But when user click on those links application reloads the browser page. I want it to correctly map to different route in the application like in hbs files as follows
<li> {{#link-to 'stock-overview' 'en' 'tdwl' '1010'}}Stock{{/link-to}} </li>
How can I generate html like that inside previous java script code.
Appreciate any help?
First, I would recommend you to think if you really need that jQuery plugin or could go with a plain ember solution. There are some pretty fancy addons like ember-power-select.
But if you really want to do that you need to understand that a {{#link-to}} does not only generate a <a> tag but only handles clicks on it and then doing a transitionTo.
So no, its not possible to do this when you simply append the HTML to the DOM. You would have to catch the click events on the <a> tags manually and then trigger the transition. It depends a bit how you inject the html into the DOM.
One thing you could do is to create a unique id for each <a> tag and after you inserted the html into the DOM you find the <a> tags by the id and attach the onclick event.
A better way would be to create DOM instead of HTML, so manually call document.createElement and then attach the click event.
To trigger the transition you can do something like this inside any Object that has the owner injected (like a component):
Ember.getOwner(this).lookup('controller:application').transitionToRoute('stock-overview', 'en', 'tdwl', '1010');
However cleanly the best solution would be to go for a ember handlebars template and a {{#each}} loop instead of the jQuery solution. To tell you how to do that however we need more information. So best is probably you ask a new question and explain exactly what you want to achieve, and now ask about a problem you have with a probably wrong solution for another problem.

Add enclosing tag for only UnOrdered list from Rich Text Editor in UL

I need to style UL's coming from Rich Text Editor in Sitecore. I am trying to find out if there is a class that I can add to all UL's coming from Sitecore's Rich Text Editor.
Thanks in Advance
Ashok
The easiest solution is just to wrap your FieldRenderer with an HTML element with appropriate class applied in code:
<div class="rich-text">
<sc:FieldRenderer ID="frRichTextField" runat="server" FieldName="MyFieldName" />
</div>
And then add in some CSS styles to handle your UL's within this:
.rich-text ul {
/* add in your styling */
}
You can also use the before and after properties of the FieldRenderer to pass in your tag:
<sc:FieldRenderer ID="frRichTextField" runat="server" FieldName="MyFieldName"
Before="<div class='rich-text'>" After="</div>" />
EDIT:
If you wanted to be more drastic then you could add in your own renderField pipeline processor to ensure your control is always wrapped with the required tag or you could make use of the enclosingTag property and patch the AddBeforeAndAfterValues pipeline instead:
namespace MyCustom.Pipelines.RenderField
{
public class AddBeforeAndAfterValues
{
public void Process(RenderFieldArgs args)
{
Assert.ArgumentNotNull((object)args, "args");
if (args.Before.Length > 0)
args.Result.FirstPart = args.Before + args.Result.FirstPart;
if (args.After.Length > 0)
{
RenderFieldResult result = args.Result;
string str = result.LastPart + args.After;
result.LastPart = str;
}
if (args.EnclosingTag.Length == 0 || args.Result.FirstPart.Length <= 0 && args.Result.LastPart.Length <= 0)
return;
// check if a css class paramter has been passed in
string cssClass = args.Parameters.ContainsKey("class") ? args.Parameters["class"] : String.Empty;
// add the class to the enclosing tag property
args.Result.FirstPart = StringExtensions.FormatWith("<{0} class='{1}'>{2}", (object)args.EnclosingTag, cssClass, (object)args.Result.FirstPart);
args.Result.LastPart = StringExtensions.FormatWith("{0}</{1}>", (object)args.Result.LastPart, (object)args.EnclosingTag);
}
}
}
Patch the Sitecore config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"
xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore>
<pipelines>
<renderField>
<processor type="Sitecore.Pipelines.RenderField.GetLinkFieldValue, Sitecore.Kernel"
set:type="MyCustom.Pipelines.RenderField.AddBeforeAndAfterValues, MyCustom.Pipelines" />
</renderField>
</pipelines>
</sitecore>
</configuration>
And then call the FieldRenderer with the EnclosingTag set and pass in your class parameter:
<sc:FieldRenderer ID="frRichTextField" runat="server" FieldName="MyFieldName"
EnclosingTag="div" Parameters="class=rich-text" />
This really doesn't add much over using the before/after properties though and I would generally try to stay away from overwriting default Sitecore processors to save heartache when upgrading.
You could either tap into relevant pipelines or update your sublayouts so that you always have a fixed class around every instance of the rich text field rendering:
<div class="rtf">
<sc:Text ID="scContent" runat="server" FieldName="Content" />
</div>
You will have to make sure as a developer that all current and future instances of rich text field renderings are enclosed by a tag with this class.
You could then include in the global CSS, a common style for this class.
.rtf ul {
...
....
}
If you don't want to have to add this wrapper for every single rtf rendering, you could tap into a relevant pipeline. (Note - this might be a better approach with regard to code maintainability)
You could choose to use one of the two:
renderField pipeline
or the
saveRichTextContent pipeline
So you would add a new processor for either of these pipelines, in which you could access the text within rich text fields only and process that as you please (easier to manipulate the html using the html agility pack)
If you use renderField pipeline - the text within the rich text field in sitecore will not change, the code you write will execure only while rendering the field - in preview / page editor or normal mode.
Using saveRichTextContent pipeline on the other hand, will update the in the rich text field when the content author clicks on save (after entering the text) in content editor mode.
You can see the following examples for these:
renderField - http://techmusingz.wordpress.com/2014/05/25/unsupported-iframe-urls-in-sitecore-page-editor-mode/ (Sample of HtmlUtility is also present here - instead of selecting all tags, you could select all and add your desired class attribute.)
saveRichTextContent - http://techmusingz.wordpress.com/2014/06/14/wrapping-rich-text-value-in-paragraph-tag-in-sitecore/
Hope this helps.
Best practice would be to just add the Class to the Rich Text Editor for use in the Editor.
There are lots of good articles on doing this. Here are a couple:
http://sitecoreblog.blogspot.com/2013/11/add-css-class-to-richtext-editor.html
http://markstiles.net/Blog/2011/08/13/add-css-classes-to-sitecore-rich-text-editor.aspx
These are minimal changes that provide you with the ability to put the styling ability in the hands of the Content Author, but still controlling what styles and classes they can use inline.

How iterate over List<T> and render each item in JSF Facelets

I am wondering how to display a List<T> as obtained below in a Facelet:
public List<T> searchByString(String string) {
return getEntityManager().createNamedQuery("Userdetails.findByUsername").setParameter("username", "%" + string + "%").getResultList();
}
Would a <h:dataTable> be a suitable way?
You're going need to iterate over it. JSF 2 offers three iteration components out the box. Provided that the User entity look like below,
#Entity
public class User {
private #Id Long id;
private String username;
private String email;
private LocalDate birthdate;
// Add/generate getters+setters.
}
and that the search results are assigned as a List<User> users property of a bean which is available as #{bean},
#Named #RequestScoped
public class Bean {
private List<User> users;
// Add/generate postconstruct+getter.
}
here are some examples based on it:
<h:dataTable>, an UI component which generates a HTML <table>.
<h:dataTable value="#{bean.users}" var="user">
<h:column>#{user.id}</h:column>
<h:column>#{user.username}</h:column>
<h:column>#{user.email}</h:column>
<h:column>#{user.birthdate}</h:column>
</h:dataTable>
<ui:repeat>, an UI component which generates no HTML markup (so, you'd have to write all that HTML in the desired fashion yourself, which could easily be changed to e.g. <ul><li>, or <dl><dt><dd>, or <div><span>, etc):
<table>
<ui:repeat value="#{bean.users}" var="user">
<tr>
<td>#{user.id}</td>
<td>#{user.username}</td>
<td>#{user.email}</td>
<td>#{user.birthdate}</td>
</td>
</ui:repeat>
</table>
<c:forEach>, a tag handler which runs during view build time instead of view render time (background explanation here: JSTL in JSF2 Facelets... makes sense?), it also doesn't produce any HTML markup:
<table>
<c:forEach items="#{bean.users}" var="user">
<tr>
<td>#{user.id}</td>
<td>#{user.username}</td>
<td>#{user.email}</td>
<td>#{user.birthdate}</td>
</td>
</c:forEach>
</table>
See also:
Java EE 6 tutorial - Adding components to a page - using <h:dataTable>
How and when should I load the model from database for h:dataTable
You can save your List in a class variable, give it a getter and (maybe) a setter. Declare searchByString method as void and call it with let's say a (provided you are using PrimeFaces):
<p:commandLink update="#form" process="#this" action="#{myBean.searchByString}">
myBean:
public void searchByString(String string) {
userList = getEntityManager().createNamedQuery("Userdetails.findByUsername").setParameter("username", "%" + string + "%").getResultList();
}
provided your table sits in a form that you just updated you could display the List in it.
<p:dataTable var="user" value="#{myBean.userList}">
<p:column headerText="Name">
<h:outputText value="#{user.name}" />
</p:column>
</p:dataTable>

Conditional Statement In Visualforce?

I'm trying to display records on a page (not a form) via VisualForce based on a checkbox value.
For example, if checkbox "Active_c" is checked, I would like to display five subsequent fields. If checkbox "Active_c" is not checked, I would like to display nothing.
The only example I can find are display text in the output, however, they don't support displaying multiple field output. For example:
{! IF ( CONTAINS('salesforce.com','force.com'), 'Yep', 'Nah') }
Anyone have experience with a conditional?
Apex Controller:
public YourObject__c YourObject { get; set; }
public YourClass(){
YourObject = [ Select Active__c, Field1__c, Field2__c From YourObject__c Limit 1 ];
}
Visualforce Page:
<apex:actionFunction name="showHideFields" reRender="myFields" />
<apex:inputField value="{!YourObject.Active_c}" onChange="showHideFields()"/>
<apex:outputPanel id="myFields">
<apex:outputPanel rendered="{!YourObject.Active_c}">
<apex:outputField value="YourObject.Field1__c" />
<apex:outputField value="YourObject.Field2__c" />
</apex:outputPanel>
</apex:outputPanel>
Another example. Without reRendering, just checking the value of the checkbox on the runtime:
<apex:outputPanel>
<apex:outputField value="YourObject.Field1__c" rendered="{!YourObject.Active_c}" />
<apex:outputField value="YourObject.Field2__c" rendered="{!YourObject.Active_c}" />
</apex:outputPanel>

Sitecore Field Renderer - add markup inside rendering

As part of an SEO enhancement project, I've been tasked with adding the following property inside the markup for the image that the field renderer is generating on the page:
itemprop="contentURL" - before the closing tag.
<sc:FieldRenderer ID='FieldRenderer_MainImage' Runat='server' FieldName='Homepage Image'
CssClass="_image" Parameters="w=150" itemprop="contentURL" />
When I tried to place this inside the Field Renderer, or add it as a "parameter" - it doesn't work.
Is there another way to do this, without having to create a control file and generate the output in the code-behind?
You need to use the "Parameters" property for setting extra properties on both the and control.
You can to it like this :
<sc:FieldRenderer ID="PageImage" runat="server" FieldName="ContentImage" Parameters="ControlType=C4Image&rel=relString" />
<sc:Image ID="SCPageImage" runat="server" Field="ContentImage" Parameters="ControlType=C4Image&rel=relString" />
That will be rendered like this :
<img width="1232" height="637" controltype="C4Image" rel="relString" alt="" src="~/media/Images/DEMO backgrounds/background2.ashx">
Note: This works in 6.5 and 6.6 - not sure which version is being used in this question.
Couldn't this be done by extending the RenderField pipeline? You could potentially decompile (using Reflector or ILSpy) the GetImageFieldValue and add your own logic to adjust the output from the ImageRenderer?
Reference Sitecore.Pipelines.RenderField.GetImageFieldValue.
In cases where "Parameters" doesn't work or trying to create a Custom control, and instead of wrapping the control in a classed div like this:
<div class="my-class">
<sc:FieldRenderer runat="server" />
</div>
You can use this:
<sc:FieldRenderer Before="<div class='my-class'>" After="</div>" runat="server" />
Notice the Single quotes in the class declaration of the div above.
This keeps it a little cleaner and in context with the Sitecore control instead of a Web Developer adding an external div that might later lose its context if changes occur.
I recommend saving yourself some trouble and using the MVC version of Sitecore though, now, (when starting new Sitecore projects), as you can very simply add a class to it like so:
How can I get Sitecore Field Renderer to use a css class for an image
You actually cannot do this on a FieldRenderer. You're options are:
Extend the FieldRenderer with the ability to do this (this will likely require a high level of effort)
Use a regular .NET control and bind the data from the Sitecore item via the C# code-behind.
You may want to try using the <sc:image /> tag.
If you add a custom parameter there, it's added as an attribute to the img tag.
In your case the tag will look like this:
<sc:image runat="server" field="Homepage Image" width="150" itemprop="contentURL" class="_image" />
using mvc, I found this was easier than extending the FieldRender, should be reusable, but will have to test a bit more. WIP.
var image = "<span class=\"rightImage\">" + FieldRenderer.Render(contentBlock, "Image", "mw=300") + "</span>";
var text = FieldRenderer.Render(contentBlock, "Text");
model.Text = FieldRendererHelper.InjectIntoRenderer(text, image, "<p>");
public static HtmlString InjectIntoRenderer(string parentField, string injectField, string injectTag)
{
return new HtmlString(parentField.Insert(parentField.IndexOf(injectTag, StringComparison.InvariantCulture) + injectTag.Length, injectField));
}