Sitecore, Uncategorized

Log files piled up? Cleanup agent log pattern fix.

In Sitecore 7.x they added some new standard logs to the solution.

  • Log – All-purpose, general Sitecore log.
  • WebDAV – Log for WebDAV activity.
  • Search – Activity from searches performed using Sitecore search providers.
  • Crawling – Activity from crawling performed by Sitecore search providers.
  • Publishing – Activity from publishing performed by Sitecore servers.
  • Fxm – Activity from Federated Experience Manager. If you are not using FXM, this log will be empty.

One thing they forgot, was to update the Cleanup agent’s log pattern.

<remove folder="$(dataFolder)/logs" pattern="log.*.txt" maxCount="20" minAge="7.00:00:00" />

This pattern will only match files starting with “log.”. The new log files prefixes with their name:

logs

Without the proper patteren, teh cleanup agent will never delete any of the new log files. To fix this you will need to update the pattern, to match the new Sitecore  standard log names:

<remove folder="$(dataFolder)/logs" pattern="*log.*.txt" maxAge="30.00:00:00" />

This is fixed in Sitecore 8.0 – update 1, however it is still a issue on solutions running older versions of Sitecore.

Advertisements
Sitecore

Sitecore and Events? Creating your own events and how to use them.

Using events can be useful when you need to run multiple operations on a item, if something changes or happens in your solution.

In Sitecore you can use the Sitecore.Events.Event namespace to create your own events, execute them when you need to and add event listeners as needed.

Registering the event:

<sitecore>
  <events>
    <event name="customevent:post">
       <handler type="Business.Pipelines.Events.PostEvent, Business" method="OnPost" />
    </event>
  </events>
</sitecore>

All you need to add an event, is to add your own config element with the name of your event, pointing at the implementation.

Implementing the event:

public virtual void OnPost(object sender, EventArgs args)
{
   var parameters = Event.ExtractParameters(args);            
   _users = parameters.Length > 0 ? parameters[0] as IEnumerable<User> : null; 
   _itemContext = parameters.Length > 1 ? parameters[1] as Item : null;
}

When implementing the event, you can access any parameters provided when raising the event. In this case we need a list for users along with a item.

Raising the event:

Sitecore.Events.Event.RaiseEvent("customevent:post", TargetUsers, item)

After the event have been raised, Sitecore handles everything needed to call your listeners.

Sitecore

Custom Frontend ribbon buttons – Sitecore 8.x

When adding custom ribbon buttons to Sitecore 8.0 and 8.1, a lot have changed since 7.x. Before 8.x you created ribbon buttons by adding the button items in the core database, while creating new “command” for them to execute.

In 8.x they changed the Experience Editor interface to use speak only, while keeping the Content editor interface using sheer UI. This require you to configure seperate buttons for the Content Editor and Experience Editor. The Content Editor buttons can be created like in 7.x. However the Experience Editor buttons require a whole new set of things for them to run.

While creating a translate module for Sitecore, we needed to enable translate buttons in the Experience Editor.

ex-buttons

 

Like in pre Sitecore 8, the buttons is created in the Core database, within the WebEdit node. This alone will not display them in the Experience Editor in Sitecore 8.
buttons

To display the buttons we need to add a rendering to the items and setup the presentation details accordingly. Each button need to have a unique ID, a click event and a PageCodeScriptFileName set. It is alot easier to set these properties using Sitecore Rocks:

rendering-settings

The PageCodeScriptFileName is where we point to our JS file, which contains the “command”. The command contains some dependencies and a function which can execute our custom behavior.

define([
    "sitecore",
    "/-/speak/v1/ExperienceEditor/ExperienceEditor.js",
    "/-/speak/v1/ExperienceEditor/TranslationUtil.js"
], function (Sitecore, ExperienceEditor, TranslationUtil) {
    Sitecore.Commands.TranslateItem = {
        canExecute: function (context) {
            return true;
        },
        execute: function (context) {
            ExperienceEditor.PipelinesUtil.generateRequestProcessor("ExperienceEditor.TranslateItem", function () {
                alert("Item sent to translation.");
            }).execute(context);
 
        }
    };
});

In our case we would like our button to execute some serversided code, which is why we use the PipelinesUtil to generate a RequestProcessor. This will execute a  Experience Editor speak request. These requests are defined in a config within the sitecore node:

  <!-- Experience editor button pipelines-->
<sitecore>
    <sitecore.experienceeditor.speak.requests>
      <request name="ExperienceEditor.TranslateItem" type="Module.Pipelines.ExperienceEditor.TranslateItem, Module" />
      <request name="ExperienceEditor.TranslateHierarchy" type="Module.Pipelines.ExperienceEditor.TranslateHierarchy, Module" />
      <request name="ExperienceEditor.TranslateBundle" type="Module.Pipelines.ExperienceEditor.TranslateBundle, Module" />
    </sitecore.experienceeditor.speak.requests>
</sitecore>

Using request pipelines provides us with enough context to extract and manipulate the context item. In our case we can extract the context item, process it to translation, and return a empty response value :

public class TranslateItem : PipelineProcessorRequest<ItemContext>
{
    public override PipelineProcessorResponseValue ProcessRequest()
    {
       this.RequestContext.ValidateContextItem();
       Item item = this.RequestContext.Item;
       if (item == null)
       {
            Log.Info("No item to translate in context.");
            Sitecore.Context.ClientPage.ClientResponse.Alert(Dictionary.GenericError);
            return new PipelineProcessorResponseValue();
       }
 
       // Add item to Queue
       QueueHelper.AddToQueue(item, QueueTypes.Translation);
 
       return new PipelineProcessorResponseValue();
     }
}

This should give you a basic implementation to work with. There is a lot of possibilities in the new speak setup, while this is just a simple “command” button click, like before 8.0