Archive

Posts Tagged ‘Usability’

WFFM publishing with related item, fixing missing form elements

29/10/2014 2 comments

When adding a form to a page via the page editor, Sitecore registers a reference to form element, so when you publish you can check the publish related Items checkbox, and you would expect the form to be visible on your CD-server

29-10-2014 11-22-29

However WFFM places all elements in the form as children to form element itself, and these are not added to the publishing queue because they are not related to page where the form was first added.

29-10-2014 11-23-32

So when publishing the form is correctly being published, but the fields for the forms isn’t moved from the master database to web database and the form is of course then not rendered out.

As always Sitecore has a pipeline, that you can hook into in this case the “getItemReferences” this pipelines, resolves related items and adds them to the publishing queue. So hooking into this and adding child elements for forms is actually quite easy.


public class GetFormChildElementProcessor : GetItemReferencesProcessor
{
  private readonly ID _formTemplateId = new ID("{FFB1DA32-2764-47DB-83B0-95B843546A7E}");
 protected override List<Item> GetItemReferences(PublishItemContext context)
 {
  List<Item> relatedformItems = new List<Item>();
  if(!context.Result.ReferredItems.Any())
   return relatedformItems;
  Database database = context.PublishContext.PublishOptions.SourceDatabase;
  var formItems = context.Result.ReferredItems.Where(i=>IsDerived(database.GetItem(i.ItemId).Template, _formTemplateId)).ToList();

  foreach (var form in formItems)
  {
    var formChildren = form.ChildEntries;
    foreach (var child in formChildren)
    {
      relatedformItems.Add(database.GetItem(child.ItemId));
    }
  }
  return relatedformItems;
}

 public bool IsDerived(TemplateItem template, ID templateId)
 {
  if (!(template.ID == templateId))
  {
   return Enumerable.Any<TemplateItem>(template.BaseTemplates, baseTemplate => IsDerived(baseTemplate,templateId));
  }
   return true;
 }
}

And now register the processor in the web.config  under /configuration/sitecore/pipelines/getItemReferences add it at the end.

<processor type="PT.Framework.PublishForm.GetFormChildElementProcessor, PT.Framework.PublishForm"/>

Now all the child elements to items the derives from the form element will be added to the publishing queue.

Categories: C#, Sitecore, WFFM Tags: , ,

Escaping dashes/“-” in Sitecore Queries. Datasource query Update

29/10/2014 5 comments

This is actually more an update to the post Query in Datasource location I wrote some while ago. As I was working on a new solution I often saw an error with “unterminated literal string in Query”. In my case it was actually quite simple because an item name include a dash “-”, which is an illegal character  in a query, the solution is to escape the part of the the path that contains  the “-”.  you escape it by adding “#” around the word, see the example below. 

query:/sitecore/content/some/path-with-dash/becomes 

query:/sitecore/content/some/#path-with-dash#/becomes

 The code to fix this is simple and Anders Laub wrote the version you see below.


private string EscapeItemNamesWithDashes(string queryPath)
{
  if (!queryPath.Contains("-"))
   return queryPath;

  var strArray = queryPath.Split(new char[] { '/' });
  for (int i = 0; i < strArray.Length; i++)
  {
    if (strArray[i].IndexOf('-') > 0)
    strArray[i] = "#" + strArray[i] + "#";
  }
  return string.Join("/", strArray);
}

 

The source code for using queries is also available on github , with the above enhancement.

https://github.com/istern/RenderingsDatasources

 

 

Categories: C#, Sitecore Tags: , ,

Usersessions in sitecore (logout users from backend)

07/06/2010 Leave a comment

The number of usersession that is possible to have open in sitecore depend onj the licens, which is fair enough. But the task for an administrator to end hanging usersession seems somewhat headless. The administrator have to logout, to get a list of active user sessions, and then choose to end hanging or not used sessions. This might be fine in minor solutions but I think this might pose a problem in solutions where a user with the “Is Adminstrator” flag is set to true can be hard to find. He might be working in different office or just generally be hard to get a hold of. It doesn’t require you have the “Is administrator” flag to end session but it is required to get the list of active sessions. You don’t even have to be logged in to sitecore to end active session, if presented with the option to end active session anonymous users could do so. My idea is to help local administrators with functionality to end session with out leaving the backend, or having to log out or anything like that. Since sitecore is one big tool box I will build it as shortcut in the tray of sitecore.
Okay so we start, all our work is done in the core database and it only contains minimal coding. We start with making the tray icon. In the core database we go to content/applications/Desktop/tray and add a item I will call it UserSessions the Data section of the item find the click attribute and add the command name, this will also have to go in the command file we get back to that. I also and icon for the tray I have choosen the standard user icon.
userhelper1
Now with the tray icon shortcut in place you should be able to see it in th start bar just save the item and hit F5

userhelper2

Now we will add the command to the App_Config/Commands.config add the following line

<command name=”Tray:UserSessionViewer” type=”UserHelper.UserhelperTrayCommand,UserHelper” />
I will add this little user feature helper as an application so we need to add an application and layout for the application in the core database. We start with adding the layout “core database” go to sitecore/layout/applications and add a new layout in the data section in path write the physical path to layout you will create in the next step.

suerhelper3
Next we will add the application again this is done in the core database go to sitecore/content/Applications/ and add a new application pull on the the layout we just created make sure you can see it in the layout section for the item. Also note the Id for your application, we will have to use it in the code part.
userhelper4
Okay now we are done with the configuration in sitecore now to code part.
First we will start we the Tray click command which is pretty simple note that is hardcode the id for our application and the database I getting the item from.

Now we have something that handle the click on the Tray command no we will code the popup or application window. First the frontend code for the application. The frontend code shows when the user session started and when the last request was made info need to take into account which user sessions you should end


<div>
<divLiteral">System Time</span>
<span><%# SystemTime %></span>
</div>
<div>
<asp:Repeater ID="taskRepeater" runat="server" DataSource="<%# ScheduleItems %>"
OnItemCommand="taskRepeater_ItemCommand">
<HeaderTemplate>
<table>
<thead>
<tr>
<td>
*
</td>
<td>
Task name
</td>
<td>
Is Due
</td>
<td>
Last run
</td>
<td>
Next run
</td>
<td>
Execute Task
</td>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<treven" : "odd"   %>">
<td>
<img src="/sitecore/shell/Themes/Standard/<%#((ScheduleItem)Container.DataItem).Icon%>"
alt="<%# ((ScheduleItem)Container.DataItem).DisplayName %>" />
</td>
<td>
<%# ((ScheduleItem)Container.DataItem).DisplayName%>
</td>
<td>
<%# ((ScheduleItem)Container.DataItem).IsDue%>
</td>
<td>
<%# ((ScheduleItem)Container.DataItem).LastRun.ToString("HH:mm dd/MM-yyyy")%>
</td>
<td>
<%# ((ScheduleItem)Container.DataItem).NextRun.ToString("HH:mm dd/MM-yyyy")%>
</td>
<td>
<asp:LinkButton ID="LinkButton1" Text="Execute" CssClass="SortButton" runat="server"
CommandName="Execute" CommandArgument="<%# ((ScheduleItem)Container.DataItem).ID %>" />
</td>
</tr>
</tbody>
</ItemTemplate>
<FooterTemplate>
</tbody> </table>
</FooterTemplate>
</asp:Repeater>
</div>
</div>

Now to the code behind, I am only using standard sitecore functionality nothing fancy here other then the click event for the repeater that end the selected user session.


using Sitecore.Data;
using Sitecore.Security.Accounts;
using Sitecore.Web.Authentication;

namespace Userhelper.Presentation
{
public partial class UserSessionsView : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DataBind();
}

public IEnumerable UserSessions
{
get
{
return DomainAccessGuard.Sessions;
}
}


protected void userRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
string id = e.CommandArgument.ToString();
switch (e.CommandName)
{
case "Execute":
EndSession(id);
break;
}
}

private void EndSession(string sessionID)
{
DomainAccessGuard.Kick(sessionID);
}

}
}

This is how I looks when we done

userhelperlast

The styling part is left for you. With this little userhelper you can set security on the tray icon so local administrator can see the tray icon and all other users have denied read access so only users with elevate security settings can end user sessions.