ProfileSitecore APIBlogLists Tools Help
December 05

Pluggable DataEngine?

Recently, we had a question on plugging a custom DataEngine into Sitecore:
 
 
While the DataEngine itself is not pluggable, the individual commands making up the engine is. That allows you to override any command in the engine. To illustrate what the engine actually does, here is the code for DataEngine.GetItem:
 
    public Item GetItem(ID itemId, Language language, Version version) {
      GetItemCommand command = Commands.GetItemPrototype.Clone();
 
      command.Initialize(itemId, language, version);
 
      return command.Execute();
    }
 
All methods look like this (with different command prototypes).
 
To override the behaviour of the GetItemCommand, all you need to do is to assign your own class to the GetItemPrototype property. In V5.3, you have to do this in code (in a hook, for instance). In V5.3.1 you will be able to do it directly from web.config.
 
For the hook, you can use something like this:
 
  public class MyHook : IHook {
    #region IHook implementation
 
    public void Initialize() {
      Database database = Factory.GetDatabase("master");
 
      database.Engines.DataEngine.Commands.GetItemPrototype = new MyGetItemCommand();
    }
 
    #endregion
  }
 
Set up the hook in web.config like this:
 
  <hooks>
    <hook type="MyNamespace.MyHook, MyAssembly"/>
    ...
  </hooks>
 
The command implementation should look something like this:
 
  public class MyGetItemCommand : GetItemCommand {
 
    protected override Item DoExecute() {
      // Do your stuff here and return an item or null.
      // Optionally, you can call base.DoExecute();
    }
 
    public override GetItemCommand Clone() {
      MyGetItemCommand command = new MyGetItemCommand();
      command.Engine = Engine;
      return command;
    }
  }
 
There is a number of other methods you can override, but DoExecute is the one that does the actual work.
 
Note that if you override any of the event generating commands (such as SaveItem), the events will still be fired. If you wish to take over the event handling, you should also override the CanExecute and Executed methods.
 
Also, note that no security checking is performed at this level. The DataEngine is called from the ItemProvider (via ItemManager) which handles securit. If you wish to alter the way security is applied, this might be a better place to hook in (which can be done by using the ItemManager.Provider property).
 
 

XSLT security

In V5.3 it is possible to completely disable security for all descendants of WebControl (including XslFile). Simply set the property 'DisableSecurity' to 'true' on the control.

For XSLT files, we have created two new XSL controls that can be used to enable and disable security for specific sections in an XSLT file.

An example is provided below:

<xsl:template match="*" mode="main">
  <h2>Security enabled</h2>
  <sc:enableSecurity>
    <xsl:for-each select="item">
      Child <xsl:value-of select="position()"/><br/>
      <sc:text field="@name"/><br/>
      <br/>
    </xsl:for-each>
  </sc:enableSecurity>

  <h2>Security disabled</h2>
  <sc:disableSecurity>
    <xsl:for-each select="item">
      Child <xsl:value-of select="position()"/><br/>
      <sc:text field="@name"/><br/>
      <br/>
    </xsl:for-each>
  </sc:disableSecurity>
</xsl:template>


The <sc:enableSecurity> surrounds its containing statements with a
Context.Security.EnterState(SecurityState.Enabled) and a Context.Security.ExitState().

The <sc:disableSecurity> surrounds its containing statements with a
Context.Security.EnterState(SecurityState.Disabled) and a Context.Security.ExitState().

After preprocessing, the code will look like this:

  <xsl:template match="*" mode="main">
    <h2>Security enabled</h2>
    <xsl:if test="true()">
      <xsl:value-of select="sc:EnterSecurityState(true())" />
      <xsl:for-each select="item">
      Child <xsl:value-of select="position()" /><br />
     
<xsl:value-of select="sc:fld('@name', .)" disable-output-escaping="yes" />=
      <xsl:value-of select="sc:fld('title', .)" disable-output-escaping="yes" /><br /><br /></xsl:for-each>
      <xsl:value-of select="sc:ExitSecurityState()" />
    </xsl:if>
    <h2>Security disabled</h2>
    <xsl:if test="true()">
      <xsl:value-of select="sc:EnterSecurityState(false())" />
      <xsl:for-each select="item">
      Child <xsl:value-of select="position()" /><br />
      <xsl:value-of select="sc:fld(
'@name', .)" disable-output-escaping="yes" />=
      <xsl:value-of select="sc:fld('title', .)" disable-output-escaping="yes" /><br /><br /></xsl:for-each>
      <xsl:value-of select="sc:ExitSecurityState()" />
    </xsl:if>
  </xsl:template>

November 27

<sc:image> enhancements in V5.3

<sc:image> now supports the following attributes (bold indicates default values):

field => The name of the image field (same as V5.2).

select => The xpath to the item. (same as V5.2 with '.' as the default value).

allowStretch => Allow stretching the image beyond its original size? Legal values: [true | false]. Same as the 'as' parameter for media URLs.

backgroundColor => Background color for the border added when an image is strecthed beyond its original size (and allowStretch=false). Legal values: Color names (ie. red, blue, etc.) and HTML hex color codes (ie. CE55E2). Same as the 'bc' parameter for media URLs.

database => The name of the database to pull the image from? Legal values are any of the defined database names. The default value is the content database of the current site (if no content database is defined, the regular site database is used). Same as the 'db' parameter for media URLs.

disableMediaCache => Disable the media cache for this request? Legal values: [true | false]. If true, the image will always be retreived from the database, bypassing the media cache. Same as the 'dmc' parameter for media URLs.

height => Height of the image to display. Legal values: Any positive integer. Same as the 'h' parameter for media URLs.

language => Language of the image to display. Legal values: Any valid language name. Same as the 'la' parameter for media URLs.

maxHeight => Maximum height of the image to display. Legal values: Any positive integer. Same as the 'mh' parameter for media URLs.

maxWidth => Maximum width of the image to display. Legal values: Any positive integer. Same as the 'mw' parameter for media URLs.

scale => Scale factor for the image to display. Legal values: Any positive floating point number (note that the decimal separator must always be a dot, as in 3.4). Same as the 'sc' parameter for media URLs.

thumbnail => Request a thumbnail image? Legal values: [true | false]. This can be used for displaying representations of media types other than images (ie. pdf, flash, etc.). Same as the 'thn' parameter for media URLs.

version => Version of the image to display. Legal values: Any positive integer. Same as the 'vs' parameter for media URLs.

width => Width of the image to display. Legal values: Any positive integer. Same as the 'w' parameter for media URLs.

Note that you can also use the shorthand names of these parameters (ie. w, h, thn, etc.).

 

Test

This is a test.
December 06

Linking items and databases

The following will apply to the release build of Sitecore 5.1.1
 
In Sitecore you can create special 'proxy' items that serve as links between different items. The items being linked may come from different databases.
 
For instance, say I have the following structure:
 
  A
  |-B
  |-C
    |-D
    |-E
      |-F
   
Now I want to expose E and its children below B such that E can be found both below B and below C.
 
The way to do it is:
  1. Start the Sitecore Shell
  2. Select 'Deactivate proxies' from the database menu (in the lower right corner next to the clock)
  3. Open the Content Editor
  4. Navigate to B
  5. Create a new item below B from the template 'Proxy'
  6. Fill in the field 'Target item' with the ID of E
  7. Save
  8. Select 'Activate proxies' from the database menu
E will now appear below B and its data and children will be shown when it is selected. The E below B is shown in a different color to signify that it is only a 'shadow' of the real E.
 
  A
  |-B
    |-E'
      |-F'
  |-C
    |-D
    |-E
      |-F

 
All operations on the E shadow item (E') will be redirected to the real E. For instance if you change any data in E' and select Save then the data will be saved to E. E' has no data of its own.
 
Even the Delete operation works on the real E so be careful!
 
There are a few exceptions to the rule of redirection:
  1. If you copy the root of a shadow tree to another location, it is the underlying proxy item that is copied
  2. If you move the root of a shadow tree to another location, it is the underlying proxy item that is moved
  3. If you delete the root of a shadow tree, only the proxy item will be deleted.

Linking across databases

To make links between databases, follow the same instructions as above, but specify a database name in the 'Target database' field of the proxy item. When proxies are activated, the shadow items will be retrieved from the target database.
 
Please note that to protect the host database, all shadow items will be given unique (but static) IDs. Therefore you can link the same items multiple times in the same host database without ID collisions.

Children

It is possible to exclude the children of a linked item by selecting 'Exclude children' on the proxy item.

API support for linked items

The shadow ID will be exposed in the Item.ID property. If you need the 'real' ID of an item, you can use:
 
  Item.InnerData.Definition.ID
 
Also, there are some properties in the RuntimeSettings object that supports working with linked items. Note that the settings only applies when proxies are activated.
  • Item.Runtimesettings.IsShadow: Specifies if an item is a shadow item.
  • Item.Runtimesettings.IsProxy: Specifies if an item is a proxy (ie. it is the root of a shadow tree).
  • Item.Runtimesettings.IsVirtual: Specifies if an item is either a shadow or a proxy
  • Item.Runtimesettings.IsExternal: Specifies if an item is from another database than the host database
  • Item.Runtimesettings.OwnerDatabase: The database that owns the item. The Item.Database property will always return the host database. To get the 'real' database owning an item use this property instead.
In a future version we will expose more of the 'shadow' API.