Experience Sitecore ! | All posts tagged 'StackOverflow'

Experience Sitecore !

More than 200 articles about the best DXP by Martin Miles

StackOverflow: Sitecore Development on Mac using C#

Recently came across a question on StackOverflow "Getting started developing with Sitecore CMS on a Mac using C#".

This topic is quite interesting as I am working with Sitecore entirely from my own MacBook for the past few years so I've decided to share my experience with the community.


Being a follower of Apple products I got a top spec MacBook Pro 15" and was willing to make it my primary computer that is always with me and which I can instantly open and start coding. After trying to find the best approach to run the entire Windows server ecosystem on Mac, I turned to virtualisation. The best solution I've found is Parallels Desktop and it brings me better experience than I would expect to get working on a native Windows machine. So what makes this approach so effective?

  • Virtual machine is a file / directory on a disk drive, so copying / archiving allows me to persist current state of each virtual machine with the ability quickly backup and restore.
  • Derived from pervious: I have few pre-configured VMs with Visual Studio, SQL Server, IIS and and Sitecore as well as all development tools I may require. I can immediately return to work even in case of malware preventing me from doing that.
  • Parallels Desktop has tight integration between host and virtual machines. Shared clipboard and resources, it is possible to drag-drop files between Finder and Explorer. Many other sweeties as well are available with Parallels Desktop like Coherence mode, when windows entirely "melts" into mac, with Start button in the doc.
  • Ability to run multiple virtual machine in parallel - as many as your host Ma machine's performance allow.
  • All virtual machines are connected to host mac and each other by a virtual network, so now I am able to create web farms and clusters, sometimes entirely reproducing production environment configuration. Also it is possible to run bridge to external network so virtual machines get network parameters from external DHCP server and will be able to use corporate resources like source control etc. as normal machines would do.
  • Adequate performance and immediate response combined with well thought default settings make it easy to start.
  • Full screen mode entirely simulates usual windows experience
  • Ability to run other operation systems, for example you would want to run a Linux VM with MongoDB at the same network.
The only negative point about Parallels is that it is not free, the rest pretty perfect.

I would especially recommend Parallels Desktop to those who are just beginning working with Sitecore, as their chances to break anything by mistake are high enough, so the ability to create a restore point at every single moment is very beneficial for them.  

StackOverflow: Sitecore 8.1 bug - Launchpad brings HTTP 500 errors and several icons including FXM are missing

Question: today I have came across a question on StackOverflow regarding new 8.1 installation, I couldn't pass by:

I am installing Sitecore 8.1 with SIM and get several JavaScript errors coming from ajax request returning HTTP 500 errors when open my launchpad. Looking in the developers tools shows the message:

http://sitecore81/sitecore/api/ao/aggregates/all/786FBA3A4573445EA74504E3CA5E48C1/all?&dateGrouping=by-week&&dateFrom=26-07-2015&dateTo=26-10-2015&keyGrouping=collapsed

http://sitecore81/sitecore/api/ao/aggregates/all/7A9A483F195D4F96AD88473CD6854C4F/all?&dateGrouping=by-week&&keyTop=5&keyOrderBy=visits-Asc&dateFrom=26-07-2015&dateTo=26-10-2015&keyGrouping=by-key

"An error occurred when trying to create a controller of type 'AnalyticsDataController'. Make sure that the controller has a parameterless public constructor."
"at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"


That results to several icons missing from Launchpad, for example FXM.

That is exact point of my confusion I've experienced previous week, when Sitecore 8.1 was released. The explanation is below:

Previously in Sitecore 8.0, there was a very confusing situation, when many new features introduced in 8.0 required license for 8.0. Running those features with a license from one of previous Sitecore version did not block those features in UI from working, but still disabled them from inside of CMS. That lead to some confusing situations like I have described in one of my previous blog posts (see: blog post about FXM and question on StackOverflow) when user without appropriate license ran FXM and couldn't add parent placeholder - no relevant error message was said.

Now since 8.1, Sitecore decided to perform very reasonable structural changes to separate CMS from xDB and Analytics with licensing model. They introduces a new CMS-only mode when Sitecore can run without xDB and Mongo, just CMS features. Those who require to use xDB and Analytics in 8.1 now need to request explicit license allowing those features (using this URL). Otherwise their Sitecore instance will default to CMS-only mode. Sitecore download page contains a warning message regarding those changes:

Sitecore 8.1 now requires a license with the “Sitecore.xDB” key to enable all features of the Experience Platform. If your license file does not contain this key, Sitecore will default to Experience Management (CMS-only) mode. Any customers or partners with a license to Experience Platform should contact their account manager or login to SPN if they are missing this key.
But what about javasript errors? Well, that is definitely a bug. I have previously contacted Sitecore support in order to report a bug (issue Id 451464). Even if you explicitly enable CMS-only mode in Sitecore.xDB.config - you'll still get those AJAX errors. It looks that corresponding SPEAK controls try to call to Entity Services (web API) and it returns generic 500-error (internal server error) code, instead of something more specific like 403 (forbidden) and proper handling that code in JavaScript on client side.

Hope Sitecore fixes that shortly!

Update: I have received confirmation that having a license for xDB in 8.1 this issue does not occur.

StackOverflow: How to use Redirect Module in Sitecore

One guy recently posted a question on StackOverflow on how to use Redirect Module. So I decided to reply about that, but thought it is a good topic for a blog post.

First of all, he probably meant a Sitecore Redirect Module from Marketplace. I have heard multiple complaints on that one and that it doesn't work as expected, moreover it seems to be discontinued.

Luckily, there are many forks of that one on the internet, as ability to control 301 redirects right from Sitecore is well in demand. I want to suggest probably the best fork I found and am successfully using myself - done by Chris dams and Max Slabyak. Why?

  • module is developing with time - just recently there was new version 1.4 that introduced ability to specify various status codes
  • good documentation included
  • sourcecode is available on Github under MIT license - feel free to use imn your commercial projects
How to get it: all you need including sources, packages for all versions and documentation is available from GitHub by this link.


Let's now create a sample redirect from a virtual URL of non-existing page to some page item in Sitecore.

We want everyone who tries accessing http://our.sample.website/pagename (note that there is no pagename item in Sitecore) to be redirected to another existing page that sits at /sitecore/content/Home/landingPage in Sitecore. For the first time, for sure, as 301 redirects are cached in user's browser and next time he/she would be taken directly to landing page (by browser).

  1. Under /sitecore/system/Modules/Redirect Module folder in Sitecore create a new redirect pattern called Pagename Test
  2. Set requested expression to ^/pagename/?
  3. Leave response status code equal 301
  4. Set source item to the actual page item serving that redirect request
  5. Do not forget to publish redirect pattern (and module itself if not yet)

A screenshot below shows how it looks in Sitecore:


Hope you find that useful!

StackOverflow 2 questions on Multi-Site configuration: Multisite Best Practice for setting up Visual Studio Project and Manage web.config in multisite solution

Got to answer two question about multi-site configuration working with Sitecore:

1. Sitecore Multisite Best Practice for setting up Visual Studio Project (link to original question)

I'm seeking an advise on best practice that has worked for creating a asp.net MVC visual studio solution that supports multisite (multi tenant). One thing we would like to do is minimize the regression defects so that developer don't modify the wrong website code base etc.
That the solution needs to support more than 8 web sites.

2. Manage web.config in sitecore multisite solution (link to original question)

We have a multisite solution with individual visual studio solutions for each websites. Then we have master solution to build/deploy all websites.
Firstly, not sure whether it's a best practice to include web.config in Visual Studio solution. But I think all the nuget packages needs web.config to add their settings.
As a result, we have web.config for each solution. However when we deploy from master web.config gets overwritten by each sites. Could someone please suggest how this issue can be fixed?

Answers:

I have got one more alternative to address that. Currently working on a huge project, with dozens of developers and quite bureaucratic process of deployments, we have introduced the following approach:

  1. Project consists of multiple logical subparts, which in fact are individual websites.
  2. Each of those websites we set up as an MVC Area with own controllers, views etc
  3. Most important - we set up MVC Areas as individually pluggable DLLs. So each of that websites is a separate project under solution, with its own resources and statics; on build everything is copied under their required paths and DLL goes to the \bin folder.
  4. One more class library for shared (by all websites) resources, it is being referenced only by those sites, that need that functionality
  5. In Sitecore, we have the same strict principles - the content, layouts, renderings are isolated as higher as possible, no individual content may be re-used (unless from shared resources folder).

This approach serves us almost a year already and has proven for its agility, much easier deployment and fairly less code merge conflicts. If you are working under just one site - you don't need to re-compile and re-deploy everything - just replace one dll at bin folder.

Thus, combining that with your question, Approach 1 would be an answer.

References (more to read):

Regarding managing configuration, I would advise for each website (under its individual project) to create it's own App_Config/Include folder and create _project_name_.config within that folder in order to keep all site-specific settings there (for further merge into resulting config).

On build you set up (for each individual project) that file to be copied into main SITECORE_INSTANCE_WEB_ROOT\App_config\Include folder along with the rest of include patch config files.

Hope someone finds that helpful!

StackOverflow: Including MVC in existing Sitecore Project

Recently one chap has asked a question oh how to include MVC into existing Sitecore project. A guy coming from classical ASP.NET MVC background experienced confusion with MVC implemented in Sitecore (here's an original link on StackOverflow). I decided to give a comprehensive answer on how MVC work with Sitecore:


Answer: In the very simplest way, you need to have the following:

  1. Item for your page, the one that has URL; that is as normal in Sitecore
  2. That page Item should have Layout assigned. From Presentation --> Details menu select at least a layout on that stage. If you do not have layout yet, you need to create a layout definition item under /Layout/Layouts folder and associate it with certain *.cshml file. Also mention that layout should have a placeholder where you will "inject"your rendering.

    @Html.Sitecore().Placeholder("Main")
    
  3. You need to create a Controller Rendering under /Layout/Renderings folder in Sitecore. Make sure you set Controller and Controller Action fields to your controller name and action method name. enter image description here

  4. Finally, go again to Presentation --> Details --> Edit --> Controls and add your newly created rendering into a placeholder that you have on your layout *.cshtml file. enter image description here

That's all done.


StackOverflow: Is it possible to change a Page to branch?

Another question I have explained on StackOverflow - (original link on StackOverflow):

Is it possible to change the Template of a page to Branch Template? When I try in Sitecore 7.0 UI it gives a error message stating to "Select a Template".

Is there any other way to change an Item's Template to be a Branch Template?

Answer: You cannot just substitute a template of an item with a branch template. You might be probably confused by mutual term template they both use and the fact the both exist undet /sitecore/templates node, however they are absolutely different in their internals.

Branch templates are just template sub-nodes that are being copied in instantiation. You may still use tokens and they would apply for every single item in a branch. But each of the items from a branch would still origin from certain individual template.

enter image description here

Thus, you cannot just do Configure --> Change on an item and then select a branch template instead of ordinary template, that's why Branches node is highlighted with grey color and even if you try to select any - sitecore will tell you "please select a template".

enter image description here

What you can do is just to re-create your item from branch template and (assuming) previous item now becomes a part of your branch - you may simply manually copy all the presentation details. However an ID of that item would differ with an ID of initial item (unless you manually replace original item into a branch instantiated)

I previously wrote an article on how to copy presentation detail manually between items, it will help you with your case:

https://blog.martinmiles.net/post/copying-presentation-details-manually

Sitecore 8: Federated Experience Manager - what is all about?

One of the greatest features of Sitecore 8 is Federated Experience Manager (FXM). What is FXM about and how can it help us?

Previously we had Page Editor - the tool allowing content editors to author and save content inline, right on the page. It also offered other flexible options to operate with non-visible content of features that cannot be edited inline (ie. Edit Frames), also do customisation (A/B multivariate testing), personalisation on rule-based criteria and much more. So far, so good.

In Sitecore 8, Page Editor was replaced with a new feature called Experience Editor (EE). EE is not just a rename for Page Editor, despite it does all the same old good features, it brings great new opportunities in chain with FXM.

With FXM it is now possible to customise any other website page, not only those coming from Sitecore, but even any PHP or just static HTML. And further on, with EE it is now possible to do all good old Page Editor features, such as replace content on external website, create placeholders and append sitecore components there, apply personalisation, set goals etc.

Sounds fantastic and impossible? Not as much - all that is working out box now, and moreover is very simple. Let's take a look on how that works and what is involved.


FXM is an applications shipped out of box and is available from Launchpad - just a usual SPEAK application. As soon as it loads, you'll get a management screen to register external websites. Clicking Add External Website will load you the following screen:


What is required on that step is to provide a hostname for external website and add one line of code into external website pages - a javascript reference for a beacon:


So, it stands obvious that you need to have an access to modify the code of pages on that website. Normally you'd do that for all pages, so it makes sense to modify some master layout or any sort of global header.

One important thing to note: external html should be properly formed, otherwise there will be an error. Saying properly formed I mean just opening and closing tags for html head and body, as minimal as:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head></head>
    <body></body>
</html>
After that done - it becomes possible to open that external website with Experience Editor. And here you can perform:
  • tracking of external website into xDB
  • create placeholders before, after or instead certain html elements on external website
  • having Sitecore-controlled placeholders it is now possible to append components from Sitecore there
  • components from Sitecore can be literary everything, even WFFM forms (however not yet in current version)
  • cleaning up, replacing or extending original content from external website
  • apply customisation and / or personalisation to external content, controllable from Sitecore
  • set goals


It is essential to understand that those features work due cross site scripting called CORS, so certain limitations should be taken off, other wise it won't work

After site has been created at /sitecore/system/Marketing Control Panel/FXM/External you need to open that node and create a rule in order to match the same domain. Without doing that it would work only in Experience Editor, but not on the live website.



When opening external website it in Experience Editor, click on Add Placeholder button twice (to get it activated), then click first paragraph. You will see it identified as div with three options on how to insert a Sitecore-controllable placeholder: before, after or replace that div element. Let's choose after, in order to implement sitecore controllable rendering in between those two paragraphs on external website:

After choosing where exactly to implement a placeholder, you'll be prompted to enter placeholder name and select parent website:


Note: licensing is important to mention. FXM works only with new license issued with Sitecore 8, so if you have license file from one of previous versions, it would not have appropriate permission (Sitecore.Federated Experience) for running FXM. For some reasons Sitecore did not implement obvious message telling that you are not able to set a placeholder externally because of license. I spent decent time previously trying to understand why that did not work for me. Please find more details in my answer on StackOverflow for that question.

Once done, there will be last screen, showing newly created placeholder exactly in between those two paragraphs and offering to append a rendering to it:


To make things easier, I have just slightly modified Sample Rendering that comes with Sitecore, so that it now looks like that:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:sc="http://www.sitecore.net/sc"
  xmlns:sql="http://www.sitecore.net/sql"
  exclude-result-prefixes="sc sql">
  <xsl:output method="html" indent="no" encoding="UTF-8"  />

  <xsl:template match="*">
    <div>
      <h3>FXM-powered placeholder</h3>
      <span>This content comes from Sitecore and is editable with Experience Editor. 
      Other cool features as personalization are also available with FXM.</span>
      <br/><br/>
    </div>
    
  </xsl:template>
</xsl:stylesheet>
That's mostly done! Do not forget to publish your site definition (under FXM node) with children (there will be placeholder item we've just created) to content delivery environment in order to work there. Let's now test it! I enter http://external into a browser and get exactly what expected - there is a sitecore controllable placeholder in between the paragraphs and it has a rendering being set into it:



Opening that in any dev. tools like Firebug will show the following nice and clean code has been rendered:


StackOverflow: Need clarity on Sitecore template values, standard values, and branch templates

One more question from a developer startin with Sitecore, who had a point of confusion between templates, standard values and branch templates (link to the original question on StackOverflow).

When creating a data template: what is the difference between just filling in the values on the template, and adding standard values? Don't both become default values whenever you create an instance of that template? If I want to make sure each item of a template has a certain value, which should I use and why? When is it appropriate to just fill out the value on the template, as opposed to adding standard values?
Branch templates: I need to create a group of items whenever a single item is created, and it sounds like branch templates are perfect for this. However, I recently read that instantiated items from a branch template stop inheriting the moment they're created.

For example, I have a branch template called Store, and create an item based off of this called Walmart. I then add features to the Store by adding new items, but Walmart doesn't get those changes? If this is problematic to my situation. I really need to keep all instantiated items in line with the branch template, and give them the new features. If my understanding is correct, how can I get around this?

I decided to answer and it seems to be a pretty good explanation:

Templates. For mature .NET developer it would make sense to think about templates as about C# classes - they define the data structure for the items that would be created on that particular template. Like classes in C# they may be inherited, but unlike in C# multiple inheritance is supported with them. Official documentation on templates is quite descriptive and handy: https://sdn.sitecore.net/upload/sitecore7/70/data_definition_api_cookbook_sc70_a4.pdf

Standard Values is a kind of blueprint prototype item for your template. You create some default values that will be auto-filled as soon as you create an item of that particular template. Standard Values item is a child item of a template definition item. You may also use tokens - dynamic values like $name, $parentname, $date, $time, $now, $id and others (you may also create your own tokens). Please read more about standard values: http://goo.gl/uUZJZf

enter image description here

Branch templates allow you to re-produce a sub-tree on instantiation, not just one item, but also some children (and children of those children) as you specify in branch template itself. As on screenshot below, whatever is selected within red frame will be created as a result of branch template instantiation:

enter image description here

Also, Sitecore items can't inherit from values set in a branch template. They will always default to the values in the original template's standard values. This is a limitation of branches (as described in this SO question: http://goo.gl/PSElYy)

As far as I understood your case, you should have a branch template called Store (somewhere underneath /sitecore/templates/Branches) and within that item reproduce exact structure that will be created on when template is used to replicate into a new branch in your content. Again, you may use tokes all around branch template (at any level) - they would be replaced with actual values. Likewise, when you use your Store branch template to create Walmart, you may auto set its display name to Walmart by using $name token.

StackOverflow: How to edit template content properties via sitecore rocks?

I have recently came across a question on StackOverflow I couldn't pass by. Here's original question:

Is it possible to edit content property via sitecore rocks plugin for VS ? for example Item Buckets section?


I knew that is not quite obvious so would want to share the answer:

Sure, that is possible. As I understood you right, you have an item with its fields loaded right hand side in Sitecore Rocks, you you do see custom fields but do not see fields coming from Standard Template, including Bucketable.

In that case just do right mouse click somewhere on the right hand side part, where your fields are and select Standard Fields from context menu. This will show those fields.



Hope someone might find that helpful!

original question on StackOverflow

StackOverflow: Adding route in Application_Start

One more question I could not pass by on StackOverflow (link to original question):

I am using sitecore 7.5 and I need to add new route in application_start in order to use it in ajax call but when I run the application it seems that sitecore deals with the route as content item any help please.

Below in my answer:

Here is the code that creates a route for you. In global.asax.cs you will call RegisterRoutes from App_Start event handler:

    protected void Application_Start()
    {
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }

And there you specify your route as:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.MapRoute(
             name: "test",
             url: "mvc/Forms/{action}/{id}",
             defaults: new { controller = "Forms", action = "Test", id = UrlParameter.Optional }
           );
    }

You will have /mvc/ prefix in this case that will handle your route to specifies controller, so you will call it as:

/mvc/Forms/Test/{you_may_pass_some_optional_GUID_here}

This will route to FormsController class action method Test(string id) but you may omit id parameter

A bit of attention: Please note that setting route in Application_Start is not the best way of doing that; much better is to implement mapping routes at Initialize pipeline, as it fits Sitecore architecture:

public class Initialize
{
    public void Process(PipelineArgs args)
    {
        MapRoutes();
    }

    private void MapRoutes()
    {
        RouteTable.Routes.MapRoute(
                "Forms.Test", 
                "forms/test", 
                new
                {
                    controller = "FormsController",
                    action = "Test"
                },
                new[] { "Forms.Controller.Namespace" });
     }
}

The rest of implementation: Also I have previously wrote an article in my blog about how to implement ajax call to a route, that will guide you through the rest of the implementation process:

https://blog.martinmiles.net/post/editing-content-on-a-cd-server

Update: Please also make sure your config has a handler to handle your prefix, see below:

<customHandlers>
    <handler trigger="~/mvc/" handler="sitecore_mvc.ashx" />
Hope someone finds this helpful!