Sitecore Personalize is not working - sitecore

I create a simple demo site for DMS function of Sitecore.
In sitecore content, I created this structure:
Home
|-Personalize
..|-HomeView1
..|-HomeView2
HomeView1, HomeView2 and Home have the same template, which contains only one Field: Display Text
Now I create Personalize for home page, set rule for it.
The rule is current month is August and point the Personalize Content to HomeView1.
When I do preview the content doesn't change into text of HomeView1.
Here is my source code:
public partial class HomePage : System.Web.UI.UserControl
{
protected Item currentItem;
protected void Page_Load(object sender, EventArgs e)
{
currentItem = Sitecore.Context.Item;
}
}
And this what I bound on Home page
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="HomePage.ascx.cs" Inherits="DMSDemo.sublayouts.HomePage" %>
<div><%= currentItem["Display Text"].ToString() %></div>
I wonder why Sitecore.Context.Item will not return the correct item (HomeView2) when the personalize rule is applied?
Please give me some advise. Thanks in advance.

The context item doesn't change when you personalize, the sublayout's datasource does. So you should set currentItem to the datasource.
Here's some common code to get the datasource which I copy/pasted from Matthew Dresser's blog:
var sublayout = this.Parent as Sitecore.Web.UI.WebControls.Sublayout;
if (sublayout != null)
{
Guid dataSourceId;
Sitecore.Data.Items.Item dataSource;
if (Guid.TryParse(sublayout.DataSource, out dataSourceId))
{
dataSource = Sitecore.Context.Database.GetItem(new ID(dataSourceId));
}
else
{
dataSource = Sitecore.Context.Database.GetItem(sublayout.DataSource);
}
}
Some other points:
In general, it's good practice to avoid the use of the context
item
There is no requirement for your page item (Home) to be the
same template has the datasource items.
I don't think personalization
works in preview mode, but you can check it in edit mode.

Related

Sitecore 7, Link manager, alwaysIncludeServerUrl not working

I am using sitecore 7 single site instance.
Content editor is generating link to other sitecore pages in this format
Agriculture
after publishing link is not converted to the actual sever related URL.
I have chnaged the link manager setting "alwaysIncludeServerUrl" to true but still not getting proper URL.
I have published the page but still not showing actual URL.
Update: I can't use field control here because there is some additional logic that controls what text needs to be rendered. for example, If there is page data source is defined then use that otherwise use "ContentBlock" field of the current item.
public string ContentBlockContent = "";
Sitecore.Data.Items.Item currentItem;
if (Parent is Sublayout && !string.IsNullOrEmpty(((Sublayout) Parent).DataSource))
{
currentItem = Sitecore.Context.Database.GetItem(((Sublayout) Parent).DataSource);
}
else
{
currentItem = Sitecore.Context.Item;
}
if (currentItem.Fields["ContentBlock"] != null)
{
ContentBlockContent = currentItem.Fields["ContentBlock"].ToString();
}
if (currentItem.Fields["PageContentSource"] != null)
{
var contentPageSource = currentItem.Fields["PageContentSource"];
var sourceItem = Sitecore.Context.Database.GetItem(contentPageSource.ToString());
if (sourceItem != null && sourceItem.Fields["ContentBlock"] != null)
{
ContentBlockContent = sourceItem.Fields["ContentBlock"].ToString();
}
}
and this is how "ContentBlockContnet" property is rendered on the page.
<%= ContentBlockContent %>
>>after publishing link is not converted to the actual sever related URL.
It’s not converted after publishing, it’s converted when page is rendered.
Make sure you render content fields using Sitecore render controls e.g. sc:text, sc:link or FieldRenderer. In this way Sitecore will run the “renderField” pipeline which take care about link conversion.

Copy Presentation Details to new PlaceHolder programmatically Sitecore 7.2

currently I am working on a page that generates a print view of a specific item. So this means I dont need all the stuff from my MainLayout like Navigation etc.
For this reason I have created a new Layout that only has a placeholder.
Lets call this PrintLayout.aspx:
<sc:placeholder ID="PlPrint" runat="server" key="phPrintOutput"></sc:placeholder>
In the code behind I have a method that fetches the renderings from the item, but I am stuck at the point where I want to copy them to my phPrintOutput Placeholder on the fly:
public void AddPresentationDetailsToPlaceHolder(Item item)
{
List<RenderingReference> renderings = item.Visualization.GetRenderings(Sitecore.Context.Device, false).ToList();
foreach(RenderingReference r in renderings)
{
// How can I apply the renderings on the fly to my phPrintOutput Placeholder??
}
}
Of course it is very important that every sublayout keeps it current datasource.
Any help would be appreciated, thank you all
You only require to add the control to the placeholder. To do so, please see the code below:
public void AddPresentationDetailsToPlaceHolder(Item item)
{
List<RenderingReference> renderings = item.Visualization.GetRenderings(Sitecore.Context.Device, false).ToList();
foreach(RenderingReference r in renderings)
{
if(r.RenderingID == new ID("Rendering Id you want to be displayed on layout"))
{
this.PlPrint.Controls.Add(r.GetControl());
}
}
}
This will automatically add the rendering to the layout.

Sitecore custom ribbon button not working

I have created a custom ribbon button following the steps mentioned in http://jondjones.com/how-to-add-a-custom-sitecore-button-to-the-editor-ribbon/
I can see the button appearing in sitecore:
Custom button
Command does not get triggered when clicked on the button.
Below is my code:
using System;
using Sitecore.Shell.Applications.Dialogs.ProgressBoxes;
using Sitecore.Shell.Framework.Commands;
namespace SitecoreVsPoc.Commands
{
public class TranslateContent : Command
{
private static readonly object Monitor = new object();
public override void Execute(CommandContext context)
{
if (context == null)
return;
try
{
ProgressBox.Execute("Arjun", "Title", "Applications/32x32/refresh.png", Refresh);
}
catch (Exception ex)
{
Sitecore.Diagnostics.Log.Error("Error!", ex, this);
}
}
public void Refresh(params object[] parameters)
{
// Do Stuff
}
}
}
Below is the command I have registered in commands.config:
<command name="contenteditor:translatecontent" type="SitecoreVsPoc.Commands.TranslateContent,SitecoreVsPoc" />
Note: I am using Sitecore 8.2 initial release.
Can someone suggest a solution for this?
In Sitecore 8 it was changed the way you add Ribbon button. As far I see your link is from Sitecore 7 or 6.
To create the new button item for the Experience Editor ribbon:
In the Core database, open the Content Editor and navigate to /sitecore/content/Applications/WebEdit/Ribbons/WebEdit/Page Editor/Edit.
Create a new item based on the relevant ribbon control template, for example, the Small Button template. The templates are located at /sitecore/templates/System/Ribbon/.
For the new item, add the following information:
In the Header field, enter the display name of the button.
In the ID field, enter a unique identifier for the item. For example, you can include the ribbon group name in the ID.
In the Icon field, enter the path to the relevant icon. Depending on the button you create, adjust the icon size accordingly.
Open Sitecore Rocks and add the relevant control rendering, for example SmallButton, to the layout of the button item you created.
Enter a unique ID for the rendering.
For other SPEAK controls, you can point to another item in the Data Source field and specify the configuration in this other item.
Important
More informations you can find here: https://doc.sitecore.net/sitecore_experience_platform/content_authoring/the_editing_tools/the_experience_editor/customize_the_experience_editor_ribbon
http://reyrahadian.com/2015/04/15/sitecore-8-adding-edit-meta-data-button-in-experience-editor/
Before it was very simple, you didn't need to add new code:
https://blog.istern.dk/2012/05/21/running-sitecore-field-editor-from-a-command/

Issue trying to use Datasource Template in Sitecore sublayout; getting empty Sublayout.Datasource

We've been trying to "componentize" our Sitecore solution as we move forward, in prep for transitioning to Page Editor usage (Woot! Finally!), but we're still practically working primarily with Page templates that may be inheritance-based composites of page specific fields, plus 1:many of these componentized templates. An example of how this looks in our solution is below -- Banner Feature Carousel and Featured Cartoon are some of these new components we're creating:
In the interest of trying to move away from using Sitecore.Context.Item (as I was recently reminded by this post) I've started filling in the Datasource template field on the sublayouts for the new components, and it seems like I've got the appropriate connections made between presentation details, the Sitecore sublayout and the .NET code file (as far as I can tell; again, we're newer to working this way).
I've also tried setting up a base class for these components as per this post by Nick Allen, but here's where I'm running into a problem: When I execute my code, this base class is finding the component Sublayout appropriately (the whole "this.Parent as Sublayout" thing) but, when I go to interrogate the Sublayout.Datasource property, it's an empty string. Here's my code (so far) for this base class:
public class ComponentBase : System.Web.UI.UserControl
{
private Sublayout Sublayout { get { return Parent as Sublayout; } }
public Item DataSourceItem
{
get
{
return Sublayout != null && !String.IsNullOrEmpty(Sublayout.DataSource) ?
Sitecore.Context.Database.GetItem(Sublayout.DataSource) : Sitecore.Context.Item;
}
}
}
I'm apparently missing some interplay between the Datasource Template field in the Sitecore sublayout, and how that actually translates to a datasource. Is it because these component templates are being used to compose Page templates? I was thinking that the datasource would just ultimately resolve to the Page template on which the component in question was currently being used, but perhaps that's my misunderstanding.
If anyone could give me any hints of things to check or point me to any resources I might use to get further, I'd appreciate it. I've done quite a bit of asking the Googs, myself, but am just not getting anything that's helping.
Thank you in advance, Sitecore friends!
It looks like you have configured the allowed templates for your sublayout in the steps you describe above. This basically tells Sitecore; 'allow user to select items based on these templates for this sublayout'. This alone does not set up the data source on items using the sublayout. You still need to go into the presentation details for any items using this sublayout, select the sublayout and then set its datasource property (within the content editor go to Presentation > Details > [Sublayout] > Data Source).
My answer to this question gives the source code needed to retrieve the datasource item and to iterate through the sitecore controls on your sublayout setting all of their Item propertys.
Here is the code:
public class SublayoutBase : UserControl
{
private Item _dataSource;
public Item DataSource
{
get
{
if (_dataSource == null)
{
if (Parent is Sublayout)
{
_dataSource =
Sitecore.Context.Database.GetItem(((Sublayout)Parent).DataSource);
}
if (_dataSource == null)
{
_dataSource = Sitecore.Context.Item;
}
}
return _dataSource;
}
}
protected override void OnLoad(EventArgs e)
{
foreach (Control c in Controls)
{
SetFieldRenderers(DataSource, c);
}
base.OnLoad(e);
}
private void SetFieldRenderers(Item item, Control control)
{
if (item != null)
{
var ctrl = control as Sitecore.Web.UI.WebControl;
if (ctrl != null && !string.IsNullOrEmpty(ctrl.DataSource))
{
//don't set the source item if the DataSource has already been set.
return;
}
if (control is FieldRenderer)
{
var fr = (FieldRenderer)control;
fr.Item = item;
}
else if (control is Image)
{
var img = (Image)control;
img.Item = item;
}
else if (control is Link)
{
var link = (Link)control;
link.Item = item;
}
else if (control is Text)
{
var text = (Text)control;
text.Item = item;
}
else
{
foreach (Control childControl in control.Controls)
{
SetFieldRenderers(item, childControl);
}
}
}
}
}
When you start using sublayouts on which you will set your datasource try to use the marketplace "Sublayout Parameter Helper". When you use the class they provide as base class and have set everything up right in your Sitecore Environment you will find yourself having a "this.DatasourceItem" -> which will contain your datasource Item, or the context Item if none is given.
http://marketplace.sitecore.net/en/Modules/Sub_Layout_Parameter_Helper.aspx
To find out more on how datasource works, try searching on http://sdn.sitecore.net. There is alot of documentation available that should get you in the right direction. Generally it will be enough to just add a datasource in the sublayout that you can access in your sublayout.
When you read a datasource from a sublayout all it will do is check if the datasource field on that sublayout is filled and will return you information regarding this datasource. So when you add a new component to a page using the page editor (for example a sublayout for a news article) and you have a datasource template defined and filled in during adding this components, you will see that when you check the presentation details on that page a sublyaout with a datasource has been added. The datasource will point to a folder in which you will find an item based on the datasource template you specified on your sublayout. You should also double check this, cause if no datasource is present on the added sublayout it will be obvious you can't access it from your code.
If you are using Sitecore 7 update 1 you can actually now use the attributes. From the Release Notes:
To make it easier to get the data source for a sublayout from
code-behind, the data source is now transferred to the sublayout
control in a "sc_datasource" attribute. (320768)
To get the data source from code, simply refer to
this.Attributes["sc_datasource"];

In Sitecore how to open a custom Sitecore app by right clicking on a content item?

I want to be able to right click on a content item in Sitecore and then select something like "Run My App" in the context menu. Then in the app that runs I need to be able to reference the content item that was right clicked. Is this possible?
Yes you can do this, its not as hard as it sounds.
You want to drop into the Core database and open up the content editor. The right click menu is defined within the sitecore/content/Applications/Content Editor/Context Menus/Default
The items within that folder are what you see when you right-click an item in the tree. So you can add a new item there with a template of Menu Item.
If you look at the existing ones, most of them send a message to the Sitecore Desktop. These messages are the commands defined in /App_Config/Commands.config. I can't see anything in there that would just launch another Sitecore application, so you would need to create a new command to do that. To create one, just inherit from the Sitecore.Shell.Framework.Commands.Command class. That passes in a CommandContext which will holds a collection of Items.
public class DemoCommand: Command
{
#region Overrides of Command
/// <summary>
/// Executes the command in the specified context.
/// </summary>
/// <param name="context">The context.</param>
public override void Execute(CommandContext context)
{
Assert.ArgumentNotNull(context, "context");
var parameters = new NameValueCollection();
if (context.Items != null && context.Items.Length == 1)
{
var item = context.Items[0];
parameters["id"] = item.ID.ToString();
}
Context.ClientPage.Start(this, "Run", parameters);
}
#endregion
public CommandState QueryStat(CommandContext context)
{
Assert.ArgumentNotNull(context, "context");
return CommandState.Enabled;
}
protected static void Run(ClientPipelineArgs args)
{
Assert.ArgumentNotNull(args, "args");
SheerResponse.CheckModified(false);
SheerResponse.Broadcast(
SheerResponse.ShowModalDialog(
"[Path to your application here]"
),
"Shell");
}
}
To get the item passed over, in your message call - just pass the variable $Target.
So the field Message in the Menu Item would be something like:
item:runMyApplication(id=$Target)
Hope that makes sense :)