Sitecore – export all users that are in a role

If you’ve ever dug into the security tables of Sitecore you’ll discover its based on the aspnet membership tables which are typically stored in core.

Recently we needed to export all the users that are in a certain role – it turned out it was easier than expected.

The outcome is that when you view the members of a certain role you can now export to a csv.

export-users

There are a few things you need to update to enable the additional ‘Export’ button.

  1. Update the xaml view for the members popup
  2. Patch in the new command
  3. Create a new sitecore command for generating the export

1. Update the xaml view for the members popup

If you navigate to ‘\sitecore\shell\Applications\Security\RoleManager’ and edit ‘ViewMembers.xaml.xml’ you should be able to see 2 buttons – the new one added below:

A tip for tracking down the xaml file in question – if you fire up either fiddler/chrome developer tools/firebug and open up the members panel and have a look at the pages being loaded you should see something like:
request-url
After the ~ you can see /xaml/Sitecore.Shell.Applications.Security.RoleManager.ViewMembers.aspx – this mimics the folder structure with fullstops replaced by folders.

2. Patch in the new command

Using sitecore patch files, create the new command reference

3. Create a new sitecore command for generating the export

Now you just need the code. The example below allows for profile information to be included in the export, simply update the ProfileFields array to include the properties you want. ComputedFields allows you to amalgamate or process other fields to gather more information as needed.

Have you ever edited in the Sitecore web db by mistake?

For version 8, see v8.1 post

I think you’ll agree its rather easy to do!

From the content editor you can select which database you are using to view content:
database selector

If you select ‘core’ the tree contains quite a different set of items however the difference between master and web can be very subtle. I know I’ve run into the problem where I’ve edited web by mistake!

In order to build a bit more feedback to the user the sample script below shows how to give a bit more feedback to users:

web db

You need to edit ‘\sitecore\shell\Applications\Content Manager\default.aspx’ and add the following javascript (added after <a id=”SystemMenu” .. />):

Vary Sitecore layout by language

One challenge we faced recently was how to vary sitecore page’s layouts across multiple languages. Out the box the layout field is shared, essentially removing the ability for its content to vary by language. In single language sites this isn’t really an issue but once you introduce several languages things get a bit trickier.

In the past we experimented with simply making the field unshared – often with mixed success. All the variations of layouts language by language became rather messy rather quickly – deltas would help this but you still can end up with some languages missing out on key components. Things like language fallback can help this but the solution still didn’t feel sustainable.

With the introduction of MVC there are a heap more pipelines available, especially around the rendering of the page. The solution we arrived at was to flip the problem around a bit and selectively apply layout changes.

Let me introduce the MOLE (hmm tenuous acronym?? 🙂 – better known as ‘MVC Layout Override Extensions’.

The pipeline this taps into is:

Out the box there is one processor which simply reads xml from an item and returns the data parsed as an XElement.

Updating this logic slightly, we hijack which item is used as the source for the data, Have a look in reflector at ‘Sitecore.Mvc.Pipelines.Response.GetXmlBasedLayoutDefinition.GetFromLayoutField’:

It’s worth noting ‘ItemQuery.GetRelatedLayoutOverrideItem(item);’ is custom code which in this implementation makes use of a new link’ed field to select when an item is being ‘Mole’d.

This is probably the simplest way of selecting the override item. You could easily introduce the rules engine to give even more flexibility when choosing to override the source items layout.

What I think is really neat about this solution is editors can page edit or preview variants and then assign to any language at any point in time. If you only wanted to override one language variant, you simply only build the relationship to the variant on that given language.

As an add-on we built some ui notifications to indicate if an item was being overwritten, or was a variant in use elsewhere. Because a link field was used to create the relationship, this data is all available in the links db.

Happy mole’ing

Sitecore Related Item Publishing

In the latest release from Sitecore (7.2) a load of neat new features have been added relating to publishing. One of the major issues we’ve seen in the past is that content items are updated but then related items aren’t published correctly. The information in this post explains the updates to sitecore related item publishing.

There is a whole load of information about the updates on the sitecore blog (http://www.sitecore.net/Community/Technical-Blogs/Reinnovations/Archive.aspx) and specifically around the related items at http://www.sitecore.net/Community/Technical-Blogs/Reinnovations/Posts/2014/03/Related-Item-Publishing.aspx

During some tests, this first image shows the master db with several field types relating content. Here you can see things like RTE fields, Rendering Datasources, image fields and multilist fields.

master-db

Following a publish of the single item with the check box for ‘Publish related items’ selected, the following related items were then pushed to web:

published items

 

Pretty neat! All the related items are gathered through a new pipeline so if the out the box rules don’t catch your required scenario, simply add your own steps.

 

Sitecore Incremental publishes

Its worth noting that during further testing we’ve uncovered some subtle nuances of having the setting Publishing.PublishEmptyItems as false. See the end of the post for more details.

When you are dealing with large amounts of content across multiple languages it can often take a long time for publishes to complete, even if the amount of changes are relatively small.

Out the box you are presented with 3 options for publishing: republish, smart and incremental. This post will detail some nuances of the sitecore incremental publishes when triggered via an agent.

Why incremental?
If you are dealing with a small amount of changes but to a large db, why bother processing or publishing the whole tree. The crux of incremental publishes is that you only process the items that have changed since the last publish. This is achieved using timestamps stored in the Properties table which indicates the last point in time a publish was completed.

The Publish agent
In an out the box installation there is an agent available to trigger publishes over time: Sitecore.Tasks.PublishAgent. This is configured in the <scheduling> section of the config and by default is set to run never. Our implementation set this up as follows:

  • interval=”00:15:00″
  • <param desc=”mode (full or smart or incremental)”>incremental</param>
  • <param desc=”languages”>en-GB, fr-fr</param>

Behind the scenes the agent creates a new Publisher, passes in the parameters and then and sets Deep=true.

What’s the problem then?
Deep introduces an odd problem to incremental publishes – in theory they should be as light as possible but there are certain circumstances where changing one node (eg adding a version to a parent with lots of children) would lead to log entries indicating thousands of items had been published:

INFO  Job ended: Publish to ‘web’ (units processed: 11569)

Normal log entries would indicate that at most a hundred or so items should be published each run of the agent.

Can we stop incremental publishes triggering thousands of items?
Surely we can simply set Deep= false? If you make a custom version of the agent its simple enough to parametrize the value passed into the agent however this seemed to introduce other issues.

With the help of support we got to the bottom of a strange issue. After 2 runs of the agent (with 2 languages being published) we would see the child item would be missing the valid version.

Master db Web db after 1 run of the agent Web db after ‘parent’ is made publishable
parent (publishable in the future, en-gb only)
-child (publishable now, en-gb only)
parent (no versions)
-child (no versions)
parent (version in en-gb)
-child (no versions)

This problem was only visible once the second language was added to the publish agent settings.

The solution
Simply add the setting: <setting name=”Publishing.PublishEmptyItems” value=”false” />.

And you should end up with:

Master db Web db after 1 run of the agent Web db after ‘parent’ is made publishable
parent (publishable in the future, en-gb only)
-child (publishable now, en-gb only)
no change parent (version in en-gb)
-child (version in en-gb)

Does this introduce any problems?
Initial testing suggested these changes to the settings would solve our issues. In a multi language solution it was found that subtle problems around the publishing of children items actually caused more problems than were solved by the changes. In the end we avoided the ‘deep’ child publishing by creating a custom version of Sitecore.Publishing.Pipelines.Publish.ProcessQueue, Sitecore.Kernel. In that we then ignored the deep parameter for specific template types.

Sitecore Preview Notifications

Within page editor you can setup custom info bars to feedback more info to your users using page editor notifications. An example of this is:
notification

Custom notifications can be patched into the app via:

Where your custom code implements:

In this example, I based my implementation on Sitecore.Pipelines.GetPageEditorNotifications.GetWorkflowNotification, Sitecore.Kernel

In order to get notifications showing in preview you need to customize things slightly. The toolbar shown in preview and page editor is the WebEditRibbonForm. This is linked into the ui via:
/sitecore/shell/applications/webedit/webeditribbon.aspx
The line that ties the class and the aspx together is:

Using reflector I extracted out the existing implementation of WebEditRibbonForm and extended to work with preview:

An interesting challenge is the need to use reflection to call private static methods on the base class:

The only thing you now need to do is patch in your own custom pipeline:

Find missing Sitecore help text

In Sitecore, field names alone dont always give context to the data that editors are updating. On template fields you can set the Short Description field – this then shows the text next to the field. Some examples are:

It may be a strict requirement that help text is set on all fields, or help text on all fields matches a given pattern. The command and / or query below shows how to find missing Sitecore help text.

In the sitecore command example the code also modifies the help text to set the first letter as a capital if its lower case.

Note, there are constants available for all fields ids. The text value was used to highlight the __. The code forces the language to ‘en’ since all our templates are created in that language.

You then patch this into the application via:

Finally, you need to add a button to core and set its click to be ‘item:validatehelptext’

I thought it would be interesting to try the same thing using Sitecore Rocks Query. There are some really handy blog posts on this – have a look at Sitecore Rocks Query Examples for more info.

I like both these approaches for tracking down missing items – it’s safe to say trawling through fields manually is both time consuming, boring and error prone!

Remove unwanted language versions from Sitecore subtree

This post ties nicely into the idea thats shown in /automatically-set-the-language-of-the-content-editor

If you have a multi site solution, chances are each site has a finite set of languages available to it. In this example we have one language per site ala:

– sitecore
– Content
— English site – field with value for default language set to be ‘en’
— French site – field with value for default language set to be ‘fr-fr’

Its easy to create invalid language content under each site. This not only bloats the amount of data being stored but can also be quite misleading, its easy to edit content on the wrong language.

The code below demonstrates a Sitecore command which allows these invalid items to be purged from the tree.

It assumes the website root item has a template with a known ID (WebsiteTemplate) and on this item there is a shared droplist field: Default Language which has its source set to /sitecore/system/Languages

This is then patched into the Sitecore commands via:

You can then setup a new button in your ribbon by creating a new item in core. In this example, within the versions chunk of the ribbon:
/sitecore/content/Applications/Content Editor/Ribbons/Chunks/Versions/

You need to fill out ‘Click’ to be item:purgeversions and then choose the icon you want.

By overriding the QueryState function the button only shows if:

  • You are below a website root item
  • You are on the valid language set on the website root item <- this is really cool since it means you can only remove invalid language versions

Taking this forwards, if you had multiple languages per site you’d need to update some of the logic to deal with lists of languages rather than 1 language.

Sitecore AddVersion returns null

In a multi-lingual build we’d given the user a new toolbar button to create a copy of the given item in a given language. The logic behind the scenes would create a version of the new item in the destination language, scan the original item and copy all the field values to the destination. It would also then reset things like workflow on the destination item.

As part of this logic we’d call:

but would sometimes find itemTo would be null.

With the help of support, they pointed us towards the <sites> configuration and the following attribute:
filterItems: If true, the site will always show the current version of an item (without publishing) and advised this could be causing the issue. This setting can be manipulated programatically via setting:

So your final code would then be:

Enjoy your new versions!

Sitecore EditFrame buttons disappear

We recently had an odd scenario where Sitecore EditFrame buttons would seemingly disappear randomly. Our edit frame made use of a mixture of Field Editor Buttons (‘/sitecore/templates/System/WebEdit/Field Editor Button’) and Edit Frame Small Buttons (‘/sitecore/templates/System/WebEdit/Edit Frame Small Button’).

We never had problems with the field editor buttons just the edit frame small buttons. On these buttons the clicks are bound to Sitecore commands. Behind the scenes these commands evaluate their querystate to check if they should be visible, disabled or active:

The buttons had a mixture of commands, some custom and some out the box. Examples of the out the box commands were:

Note, to find the code that runs for these commands, have a look in /App_Config/commands.config and search for the specific command name.

After debugging into our custom commands vs the out the box commands we found things like item:movedown has the following checks:

The check that was catching us out was the if (Command.IsLockedByOther(item)) clause.

I’d never have thought to check an item locks as being the cause of EditFrame buttons not showing!!! The more I think about it I can see why the check is there – things like sort order are stored as fields against an item so if they are locked, you shouldn’t be able to edit them. From a UI perspective, it appears edit frame buttons don’t distinguish between CommandState.Disabled and CommandState.Hidden.