Friday, August 21, 2015

Design an awesome experience! Part two.

Focusing on the user

Our design focus when designing a service is the user, and how the service journey will affect the user. Not only must we be able to tell how the service will work and how the user will interact with it. We also need to think about what happens before and after the user has interacted with it, what knowledge is required even to use it, etc.

To answer these questions we need to understand the user needs, and how the user will experience the service. The methods used to acquire these answers might vary from interviewing the users, observing the user, or experience the service yourself. The chosen method will differ from time to time. It depends on how complex the service will be.

The main point is that you as a designer create a way to communicate with the user and map their wishes, desires, requirements etc. Remember that as little as one extra click or unnecessary text box might make your design quite cumbersome and difficult to use. I would claim that it is all about respecting your users. After all, they have better things to do than to spend all their time working on your bad design. ;)

So, keep it simple and easy to use. 


Already arguing that service design is not a one-man job, the designer must involve all relevant stakeholders on the design. Using different methods for the users to contribute to how the service should be designed not only gives you valuable data on what the user expect. It also makes change management easier when the service is deployed.

My favorite methods are using touch point cards, permanent markers and a large sheet of brown paper. Letting the users look at a large amount of pictures and writing down their immediate associations and thoughts related to the service kicks off the creative process easily. Drawing up the context on paper and composing journeys by combining pictures quickly open their eyes to possibilities that they had not thought of yet, etc. Documenting this process, I usually let people use their mobile cameras and collect the pictures after the session. 

So, let us hang on to the hour registry for a few more minutes. The stakeholders for this service is the employee, management and accounting. Designing this service, I would bring all three into the design process and bring the stack of touch point cards. Using the cards, we would collectively design the service journey by picking out cards representing ideas and documenting the ideas. I have experienced that one of the most effective ways to create these journeys is to spread the cards on the paper, drawing and writing keywords and connecting the dots. Finally documenting simply using the camera on your phone. This helps you documenting the agreed design before implementing a prototype, and the users get the feeling that they actually take part in the process, creating their own tools.

Therefore, in one small exercise you have a tool for design and documentation giving you relevant ideas for the final design, but also a side order of clever change management. 

Design an awesome experience! Part one.

The methodology behind designing service journeys provides you with great analytical tools that will fit almost any kind of experience. Working in the areas of design, development and project management this approach have been amongst my favorites for many years, but I’ve never taken the time to really document the way I use it.

Years ago, I attended a session demonstrating AT-ONEs Touch-point cards, and how simple images and text can be used to design a service or a service journey. I have kept my stack of cards and used them in every project I have worked on since.

The last few years I have dived into different methodologies and dragged more concepts into my work as I saw them fit. Now, time is overdue to tie some threads together and document my work. My next few blog posts are dedicated to this subject, and I hope that they can be helpful.
My context is based on designing web and intranet experiences, so naturally I will try to tie up this in my examples. Designing a SharePoint intranet for a medium sized company will be the case for the series.

Service design

Service design cross into most disciplines. The service itself forms the very base for the existence of each discipline in the first place. Why? Because each discipline in one way or another supports the service being provided. The point being, leaving service design solely to one person in the organization will not work so well.

However, let us not lose focus on the subject. :) How is this relevant to your company intranet?
The answer is really – what goes in your intranet? We define an intranet to be an arena for collaboration, sharing information and working with documents and workflows. The users find their tools for registering hours, sharing documents and for social interaction across the organization. All users will use a portal as their starting point, and will find their tools and content using search and navigation.

In order to design a coherent experience providing the users with content exceeding the native functionality of the intranet, we need input from the right people. Mapping different stakeholders and using them as resources for the design process helps collecting the input and set the requirements for the design.

So, here’s the case:
Sally from accounting want the company’s employees to register their hours using a new reporting system. Her requirement for the intranet is to provide a link to this system. The link must be visible and easy to find. Max, the sales manager, want to check in his hours when he is on the road, connecting via his phone. Pat from IT, requires that access to the intranet is secure so company confidential information do not get lost.

Only providing a simple service as this shows the necessity of the design properly thought through. 

Friday, March 27, 2015

Folding map effect using Oridomi

Half gob smacked I’ll just throw out one more post today. I’ve discovered Oridomi today. In a matter of minutes, I was able to add a cool feature to my page.

First, I added a static Google Map image to my page using the Google Map API for position and markers.

var customShapes = [];
<img src=",11.096837&zoom=15&size=600x400&markers=color:blue%7C59.273544,11.096837&maptype=hybrid" />
Then I put this image inside a div element that when executed folds the map up like a… yes, map ;)

Check out the code…
var customShapes = [];

var oriDomi = new OriDomi('.myoridommi', {
    vPanels: 5,     // number of panels when folding left or right (vertically oriented)
    hPanels: 3,     // number of panels when folding top or bottom
    speed: 3200,  // folding duration in ms
    ripple: 2,     // backwards ripple effect when animating
    shadingIntesity: .5,    // lessen the shading effect
    perspective: 800,   // smaller values exaggerate 3D distortion
    maxAngle: 40,    // keep the user's folds within a range of -40 to 40 degrees
    shading: 'soft' // change the shading type
var unfolded = false;
function effect() {
  //  unfolded ? jQuery(".myoridommi").hide() : jQuery(".myoridommi").slideToggle(500);
    unfolded ? oriDomi.foldUp() : oriDomi.unfold();
    unfolded = !unfolded;
document.getElementById('CanvasLoc').addEventListener('click', effect);

Fetching blogger posts using ajax.

For my showcase webpage, I wanted to show some of my blog posts as a demo. Now getting hold of rss-content is fairly easy in an rss-reader; but as JavaScript objects – not so much.

I came across different pieces and put them together in a solution that gave me a limited number of blog posts as JavaScript objects using ajax and the blogger API.

In the following snippet, I fetch the data using ajax and handle the response building an array of blog posts. Please see my inline comments...

var customShapes = [];

// First I need a container holding the data in a structured way. As I render the content, I traverse through the array handling each object
var blogPosts = [];
// As the query will change in different scenarios I keep part of the query string as an argument in the function call.
function loadBlogPostAndRender(posts) {

        url: 'http://www.someBloggerBlogUrl/feeds/posts/default?' + posts, // The blog url and the variable specifying the query arguments
        type: 'get',  
        dataType: "jsonp", // It is VERY important that you use jsonp and not json to get around cross site scripting restrictions
        success: function (data) {
            try {
                var posturl = ""; // Initiating variables
                var postcontent = "";
                var postCat = "";
                // Traversing the responce handling each post
                for (var i = 0; i < data.feed.entry.length; i++) {
                    // Getting the post url
                    for (var j = 0; j < data.feed.entry[i].link.length; j++) {
                        if (data.feed.entry[i].link[j].rel == "alternate") {
                            posturl = data.feed.entry[i].link[j].href;
                    // Fetch tags from the blog post
                    for (var k = 0; k < data.feed.entry[i].category.length; k++) {
                        postCat = data.feed.entry[i].category[k].term + " ";
                    // Fetching the content
                    if ("content" in data.feed.entry[i]) {
                        postcontent = data.feed.entry[i].content.$t;
                    } else if ("summary" in data.feed.entry[i]) {
                        postcontent = data.feed.entry[i].summary.$t;
                    } else {
                        postcontent = "";
                    // As I want to show any image from the blog post as well, I look for the first image linked up to the blog post.
                    var imgUrl = "";
                    try {
                        imgUrl = $(data.feed.entry[i].content.$t).find('img:first').attr('src');
                    } catch (error) {
                        imgUrl = ""; // If there is no image, I keep a placeholder backup
                    // As I only need part of the blog post, I use regular expressions to filter the content and substring to limit the length.
                    var re = /<\S[^>]*>/g;
                    postcontent = postcontent.replace(re, "");
                    //reduce postcontent to 200 characters
                    if (postcontent.length > 200) {
                        postcontent = postcontent.substring(0, 400);
                    // Getting the title and publication date.
                    var posttitle = data.feed.entry[i].title.$t;
                    var postdate = data.feed.entry[i].published.$t;
                    // I'm done and add the content as an object on to the array.
                    blogPosts.push({ bUrl: posturl, bTitle: posttitle, bContent: postcontent, bDate: postdate, bCategory: postCat, bImgUrl: imgUrl });
            } catch (e) {

        error: function () {
            //        writeErrorMessage("blogCanvas");
        complete: function () {
            // When the request is complete it is time to render the content. 
            // In order to start the next request with a clean slate, I empty the array.
            blogPosts = [];

Execute Canvas rendering based on scroll event.

I have been showing animations using canvas in several blog posts lately and implemented a lot of this in my own homepage. Now, if you are doing animations you need to plan how the animations should execute so that the user does not miss the whole show. :)

You might want to kick off the animation on a click, or even on a long page – start the animation once the user scrolls down to the animations position. There would be little use in an animation if the show were over when the user gets to it, right?

Now, you can hook on to the browsers events using the window object or the document object. The click event I’ve already covered in this post. For the scroll event you need to grab the window object.

The easiest way to do this is to use JQuery and extend the scroll event. In this example I’ve added a delay before kicking of the animation.

I’ve also calculated the position the user should scroll to before firing the event handler.
var target = $("#mainSectionFootprint").offset().top - 400,
    timeout = null;

$(window).scroll(function () {
    if (!timeout) {
        timeout = setTimeout(function () {
            timeout = null;
            if ($(window).scrollTop() >= target) {
        }, 250);

Friday, March 20, 2015

Resizing your canvas drawings properly using repaint

This post will be a short one attending a problem I briefly touched upon in my previous post on animation using canvas. We live in a "mobile first" world and need to pay attention to responsive designing.

Try as you might resizing your canvas using CSS you are in for a disappointing surprise. Especially if you are rendering text, it will look all chunky and broken. My solution to this problem is to calculate a factor value based on the window and canvas width. Using this value, I can multiply it with all xes and ys and lengths and widths and so on and keep the relative positions all these shapes have to each other.
var ic = window.innerWidth / (canvas.width * 1.2) > 1 ? 1 : window.innerWidth / (canvas.width * 1.2);
When adding objects I apply the factor to keep the relative positions.
var customShapes = [];

// Figures - Balls
customShapes.push({ x: ic * (canvas.width / 2 - 58),  minRadius: 0, maxRadius: ic * (3), y: ic * (canvas.height / 4 - 152), borderThickness: ic * (11), borderColor: ringBlue, color: ringBlue, runAnimation: !0, speed: 2.4 });
customShapes.push({ x: ic * (canvas.width / 2 - 117), minRadius: 0, maxRadius: ic * (3), y: ic * (canvas.height / 4 - 102), borderThickness: ic * (3),  borderColor: ringBlue, color: ringBlue, runAnimation: !0, speed: 3 });
customShapes.push({ x: ic * (canvas.width / 2 + 43),  minRadius: 0, maxRadius: ic * (3), y: ic * (canvas.height / 4 - 150), borderThickness: ic * (7),  borderColor: ringBlue, color: ringBlue, runAnimation: !0, speed: 1 });
Now, make sure to use the windows.resize event to kick off the rerendering of your canvas. The result is a world apart from the CSS approach.

Animating objects using HTML5 Canvas

Object animation using JavaScript is fairly simple once you get the hang of it. In the three previous posts I've explained how to render shapes and how to render a series of shapes. To recap some of the steps I've included the part where I create the objects.

Creating classes

I've created a generic shape class called CShape, with a set of basic properties that I find relevant for any of the shapes I'm going to render. This also includes properties relevant to animation. Each property is explained in the comments below.

// Applies to circles, boxes and lines
// X and Y coordinates
// expand (bool) growing (true) or shrinking (false)
// direction - animating going cw or ccw
// speed - animation speed
// borderThickness - border thickness
// borderColor - border color
// color - shape color
// clickZone - clickable zone with pointer cursor
// speed - animation speed
function CShape() {
    this.x = 0;
    this.y = 0;
    this.expand = true;
    this.speed = 0;
    this.borderThickness = 1;
    this.borderColor = "#FFFFFF";
    this.color = "#000000";
    this.delay = false;
    this.runAnimation = false;

Further on I've extended the CShape creating another class called CCircle. Here I've added the properties minRaduis and maxRadius as these only apply to circular shapes. The radius values will be used for animating references, growing or shrinking.

CCircle.prototype = new CShape();
CCircle.constructor = CCircle;
// Circle object - prototyped CShape
// Adds min and max radius. 
function CCircle() {
    this.minRadius = 0;
    this.maxRadius = 0;

A bit to the side, but indeed relevant to the mission we add a factor for resizing. You might know that resizing a canvas without rerendering the content might give you a poor result, so we'll do a calculation here and multiply all positions and sizes with it. I'll come back to this in a future blog post. Maybe even the next.

var ic = window.innerWidth / (canvas.width * 1.2) > 1 ? 1 : window.innerWidth / (canvas.width * 1.2);

Creating objects

Now I am ready to create some shapes. For this demo I'll create a series of small circles like you can see on my home page. I add them straight away to the array to save some steps, but you can create the objects based on the classes and then add them later if you wish.

var customShapes = [];

// Figures - Balls
customShapes.push({ x: ic * (canvas.width / 2 - 58),  minRadius: 0, maxRadius: ic * (3), y: ic * (canvas.height / 4 - 152), borderThickness: ic * (11), borderColor: ringBlue, color: ringBlue, runAnimation: !0, speed: 2.4 });
customShapes.push({ x: ic * (canvas.width / 2 - 117), minRadius: 0, maxRadius: ic * (3), y: ic * (canvas.height / 4 - 102), borderThickness: ic * (3),  borderColor: ringBlue, color: ringBlue, runAnimation: !0, speed: 3 });
customShapes.push({ x: ic * (canvas.width / 2 + 43),  minRadius: 0, maxRadius: ic * (3), y: ic * (canvas.height / 4 - 150), borderThickness: ic * (7),  borderColor: ringBlue, color: ringBlue, runAnimation: !0, speed: 1 });
customShapes.push({ x: ic * (canvas.width / 2 + 138), minRadius: 0, maxRadius: ic * (3), y: ic * (canvas.height / 4 - 120), borderThickness: ic * (15), borderColor: ringBlue, color: ringBlue, runAnimation: !0, speed: 1.4 });
customShapes.push({ x: ic * (canvas.width / 2 + 195), minRadius: 0, maxRadius: ic * (3), y: ic * (canvas.height / 4 + 53),  borderThickness: ic * (10), borderColor: ringBlue, color: ringBlue, runAnimation: !0, speed: 4 });
customShapes.push({ x: ic * (canvas.width / 2 + 99),  minRadius: 0, maxRadius: ic * (2), y: ic * (canvas.height / 4 + 152), borderThickness: ic * (6),  borderColor: ringBlue, color: ringBlue, runAnimation: !0, speed: 1.4 });
customShapes.push({ x: ic * (canvas.width / 2 - 75),  minRadius: 0, maxRadius: ic * (2), y: ic * (canvas.height / 4 + 232), borderThickness: ic * (26), borderColor: ringBlue, color: ringBlue, runAnimation: !0, speed: 2.9 });
customShapes.push({ x: ic * (canvas.width / 4 + 60),  minRadius: 0, maxRadius: ic * (2), y: ic * (canvas.height / 4 + 86),  borderThickness: ic * (12), borderColor: ringBlue, color: ringBlue, runAnimation: !0, speed: 5.4 });

Rendering shapes

Now it is time for some logic. We need a function that can render a circle based on these objects. The function below takes an object, an id and the canvas context as an argument. I choose to send in the context because I want to use the same function rendering on several canvas elements in one page. Other than that the function pretty much does what it says.

// Renders a circle based on a Circle object
function drawCircle(tmpShape, id, renderContext) {
    var tmpCircle = new CCircle();
    tmpCircle = tmpShape;
    var centerY = tmpCircle.y;
    var centerX = tmpCircle.x;
// These two lines are relevant to the rendering speed. 
// As long as the minRadius is less than the maxRadius it

// will grow according the the value of the speed property

    if (tmpCircle.minRadius <= tmpCircle.maxRadius) {
        tmpCircle.minRadius = tmpCircle.minRadius + tmpCircle.speed;
    var radius = tmpCircle.minRadius;
    renderContext.fillStyle = tmpCircle.color;
    renderContext.lineWidth = tmpCircle.borderThickness + (tmpCircle.minRadius * 0.01);
    renderContext.strokeStyle = tmpCircle.borderColor;;
    renderContext.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);

Animating the shapes

Oki, so now we can draw a circle. Now I'll add two functions. One for running the rendering based on the kind of shape, and one that runs through the array.

// Loops through the custom shape array calling renderShapes on every shape
function animationLoop() {
    var i = customShapes.length;
    while (i-- && i >= 0) {
        var customShape = customShapes[i];
  // Calling the rendering function
        renderShapes(customShape, i, context);
        if (customShapes[20].minRadius >= customShapes[20].maxRadius) {
 //checking if the shape should continue animating in the next iteration 
            keepAminationAlive = false;
    if (keepAminationAlive == true) {
  // if the shape should be reredered, the function is called again
        setTimeout(animationLoop, 50);

Now, for each object in the previous function we need to know which kind of shape to render. This is simply done by checking if the object contains one of the unique shape properties applied to the shape object. Since we are only rendering circles in this demo, this is not a problem. However, if your animation is based on several shapes like on my site ( - you have to tend to this.

// Renders one figure based on the type of figure, testing on figure specific properties. 
function renderShapes(tmpShape, id, renderContext) {
    if (!isEmpty(tmpShape)) {
        // if circle
        if (tmpShape.hasOwnProperty("maxRadius")) {
            if (tmpShape.runAnimation == true) {
                drawCircle(tmpShape, id, renderContext);
            // if line
        else if (tmpShape.hasOwnProperty("length")) {
            if (tmpShape.runAnimation == true) {
                drawLine(tmpShape, renderContext);
            // if box
        else if (tmpShape.hasOwnProperty('width')) {
            drawBox(tmpShape, renderContext);
        } else

Kicking of the animationLoop should give you a decent animation experience ;)

Rendering shapes in Canvas using objects

In a previous blog post (Painting using Canvas and JS), I explained how to paint a figure using canvas. I explained how to paint the figure inside a single function by setting coordinates and calling stroke and fill. In the following post, (Create an interactive HTML5 Canvas using event handlers.) I presented the clickable area as an object. In this, post I am going to start up by combining the two like the snippet below.

I create an object called CustFigure. It has X and Y values and a height and width. This is all we need in order to place it in the grid and to get the size of the figure, say a box.
 var CustFigure = function (x, y, height, width, label ) {
    this.x = x;
    this.y = y;
    this.height = height;
    this.width = width;
    this.label = label;
function DrawShape(Shape){
    var rectWidth = Shape.width;
    var rectHeight = Shape.height;
    var rectX = Shape.x;
    var rectY = Shape.y;

    renderContext.fillRect(rectX, rectY, rectWidth, rectHeight);

// This call is sending the object to the function DrawShape(), rendering the shape.
If you want to render many shapes, you can take the following approach. Create an array as a container for all your figures and push each instance of CustFigure in it.
var custFigures = [];

var custFigure1 = new CustFigure(10, 10, 75+10, 75+10, " Hello Nerd!");
var custFigure2 = new CustFigure(20, 20, 75+20, 75+20, " Hello Nerd!");
var custFigure3 = new CustFigure(30, 30, 75+30, 75+30, " Hello Nerd!");
Now, calling the function renderLoop, we render all the shapes in the array.
// Loops through the custom shape array calling DrawShape on every shape
function renderLoop() {
    var i = custFigures.length;
    while (i-- && i >= 0) {
        var customShape = custFigures[i];
        DrawShape(customShape, i, context);

Wednesday, January 7, 2015

Create an interactive HTML5 Canvas using event handlers.

You can use HTML5 Canvas as an alternative approach designing info graphics, branding graphics etc. Using the example in my previous blog post, I will add a clickable area on the canvas and use a JavaScript event handler to execute some logic.

This is the result of the previous example. I want to pop an alert Box when clicking inside the logo.

I need to create an object reflecting the coordinates I want my clickable zone to have. I’m also throwing in an id/name.

    var CustFigure = function (x, y, height, width, name ) {
    this.x = x;
    this.y = y;
    this.height = height;
    this.width = width; = name;

In this case I just create a global Array that I can pop the objects on to.  

    var custFigures = [];

At some point (I choose to include it in the function drawing the logo) we create the object with the desired coordinates and push it on to the array.

    var custFigure = new CustFigure(50, 50, 75+50, 75+50, " Hello Nerd!");

Now, for the final section; adding the logic to the canvas click event handler.  

   $('#xpCanvasWeb').click(function (e) {
    //Picking up the cursor coordinates
    var clickedX = e.pageX - this.offsetLeft;
    var clickedY = e.pageY - this.offsetTop;
    //You might have more than one clickable zone in your canvas. 
    //We run through the array and compare the coordinates.
    for (var i = 0; i < custFigures.length; i++) {

        if (clickedX > custFigures[i].x
            && clickedX < custFigures[i].width
            && clickedY > custFigures[i].y
            && clickedY < custFigures[i].height) {
            var name = custFigures[i].name;
            //When matching we fire of the alert box.
            alert("You clicked X=" + clickedX + " and Y=" + clickedY + name);

The result should look something like the box below.

Tuesday, January 6, 2015

Painting using Canvas and JS.

Lately I've been playing around with HTML5 and Canvas trying to render icons and graphics without the use of image files. This blog post is simply showing how to render the HTML5 logo using only code.
First up, we create a HTML5 canvas-tag where our logo will live. I’ll add some simple CSS to it for good measure, creating a circular form for our logo. We make sure to call our function rendering the logo as the page is loaded.

<canvas id="xpCanvasWeb" class="testblock" width="175" height="175"></canvas>

<style type="text/css">
.testblock {
    background: none repeat scroll 0 0 #2a2a2e;
    border: 1px solid #2a2a2e;
    border-radius: 115px;
    margin: 10px;

Now, for the rendering-function, please see my inline code. My approach towards this is to paint the logo in «layers», starting with the background and adding on layer by layer until the logo is complete. By using semi-transparent colors, we get the desired 3D-effect.

function xpCanvasWeb() {
    // We grab the canvas and context.
    var c = document.getElementById("xpCanvasWeb");
    var ctx = c.getContext("2d");

   //Adding color and filling a rect as background
    ctx.fillStyle = "#2a2a2e";
    ctx.fillRect(0, 0, 175, 175);

   // We want to be able to move our logo about without too much fuss, so we declare an x and y variable and add it in the rendering code.
   var x = 60;
   var y = 50;
   //We set the line width to 1 px.
   ctx.lineWidth = 1;

   //We begin by declaring the start of a path and setting the fill style.
   ctx.fillStyle = "#E34C26";
   //Then we move into position and start drawing
   //Fig left
   ctx.moveTo(x, y);
   ctx.lineTo(x + 5, y + 57);
   ctx.lineTo(x + 28, y + 63);
   ctx.lineTo(x + 51, y + 57);
   ctx.lineTo(x + 56, y + 0);
   ctx.lineTo(x, y);

   //Fig center
   ctx.fillStyle = "#F06529";
   ctx.moveTo(x + 28, y + 4);
   ctx.lineTo(x + 28, y + 58);
   ctx.lineTo(x + 47, y + 53);
   ctx.lineTo(x + 51, y + 5);
   ctx.lineTo(x + 28, y + 5);

   //Fig right
   ctx.fillStyle = "rgba(255, 255, 255, 0.6)";
   ctx.moveTo(x + 46, y + 12);
   ctx.lineTo(x + 10, y + 12);
   ctx.lineTo(x + 12, y + 33);
   ctx.lineTo(x + 35, y + 33);
   ctx.lineTo(x + 35, y + 42);
   ctx.lineTo(x + 28, y + 45);
   ctx.lineTo(x + 21, y + 43);
   ctx.lineTo(x + 20, y + 37);
   ctx.lineTo(x + 13, y + 37);
   ctx.lineTo(x + 13, y + 48);
   ctx.lineTo(x + 28, y + 52);
   ctx.lineTo(x + 43, y + 48);
   ctx.lineTo(x + 45, y + 26);
   ctx.lineTo(x + 19, y + 26);
   ctx.lineTo(x + 19, y + 20);
   ctx.lineTo(x + 45, y + 20);
   ctx.lineTo(x + 45, + 12);

The figure shows how the layers build up the logo for each time we call beginPath, add coordinates and call fill again.

Friday, July 4, 2014

Using parameters in XSLT

If you've read some of my previous posts, you've seen examples of using parameters when calling templates.
I earlier wrote about assigning XML structures to variables. Now we are going to use a variable as parameter for a template call.

Create the variable and send it as a parameter to your template of choice:

  <!-- Given a structure like this one... -->  
  <xsl:variable name="someVariable">  
  <artist sex="female">Madonna</artist>  
  <title>Like a prair</title>  
  <xsl:call-template name="targetTemplate">  
  <xsl:with-param name="string" select="$someVariable" />  
  <xsl:with-param name="attributeString" select="$someVariable/@sex"/>  
 </xsl:call-template name="targetTemplate">  

Grab the variable and do something that makes sense. ;)

 <xsl:template name="targetTemplate">  
  <xsl:param name="string"/>  
  <xsl:param name="attributeString"/>  
  <!-- do something -->  
  <xsl:if test="contains($attributeString, 'female')">  
   <xsl:value-of select="$string">  

Note that the variable can change its name, but the name in the "with-param" and "param" tags must match.

Happy coding! 

Thursday, June 26, 2014

Set the logo of all sites in a SharePoint 2013 site collection using PowerShell - Flash post

If you want to quickly set the site logo of a complete SharePoint 2013 site collection, enter the following:

(get-spsite http://YourSiteCollectionURL).AllWebs | foreach {$_.SiteLogoUrl = “/relative/path/to/companylogo.png”; $_.Update()}

Thats all :)

Wednesday, June 11, 2014

Open termbased navigation links in new window in SharePoint 2013

Term based navigation has been greatly improved in SharePoint 2013, but sometimes you want to open navigation URLs in a new window. However, the term store does not offer such a property so we'll solve it using JavaScript instead.

In the masterpage element add this script:

script language="JavaScript"

// Adding an entry to _spBodyOnLoadFunctionNames array so the function runs on pageLoad

function rewriteNavigationLinks() {
 // collecting anchors
 var anchorArray = document.getElementsByTagName("a");
 for (var x=0; x0) 
   oldUrl = anchorArray[x].outerHTML;
   // adding target attribute
   newUrl = oldUrl.replace(/#targetnewwindow/,'" target="_blank');
   anchorArray[x].outerHTML = newUrl;

Then in the term store append "#targetnewwindow" on the link to activate the specific link.


Friday, April 11, 2014

Configuring MySite search center settings for SharePoint 2013

I stumbled over this one the other day and I (luckily) discovered the solution by accident.

When configuring MySite in SharePoint 2013 you are prompted to give up the URL for your search center. Now, if you’ve set up an Enterprise Search Center as I’ve done redirecting you to the correct result pages will fail when doing a search from MySite. Leaving you with an “The page you're looking for doesn't exist”-error. (Yes, another of MS meaningful errors).
The error you’ll discover is that you’ve most likely entered something like http://theUrlFor/MySearchCenter on the MySite configuration, while it should have been http://theUrlFor/MySearchCenter/pages
When searching from MySite you get “The page you're looking for doesn't exist”
The search URL is wrong and SharePoint cannot find the pages that display the search results.
The solution giving you least headache is to use the SharePoint PowerShell and execute the following lines:
$ssa = Get-SPEnterpriseSearchServiceApplication$
ssa.SearchCenterUrl = "http://theUrlFor/MySearchCenter/pages"$


Wednesday, September 25, 2013

SharePoint 2013 - Design Manager - Problems connecting to network drive.

I've been working with SharePoint 2013 lately and I came across a problem trying to upload design files for the design manager.

This problem occurs when developing directly on Windows Server 2008 R2.

 When mapping the provided link to your computer like explained here (MSDN), you get an error "The network name cannot be found."

As many other problems you'll find when developing on a server this is due to a missing feature. The solution to the problem is enabling "Desktop Experience" feature.

Go to the Server Manager and click on "Features" in the left side tree structure. In the main pane click "Add Feature" and check the "Desktop Experience" box.

Follow the instructions and make sure to save your work because the Server will have to reboot on finish.

When logged in you'll find that mapping the location to your computer will work.

Sunday, September 30, 2012

XPath - the keymaster

As you might already know you won't get anywhere without XPath when working with XSLT. As scary as it might sound (at least I thought it sounded scary), it is no more than the pattern you need to learn to find the information you're looking for. Now you might argue that it can be more complicated than that, but we'll keep it simple in this blog post. We'll use the music XML structure from a previous post.

Let’s see some examples:

  1. <!-- This code will give you a copy of the XML root of the current structure. -->
  2. <xsl:template name="giveMeTheRoot">
  3. <xsl:copy-of select="//"/>
  4. </ xsl:template >
  6. <!-- This template will give you a COPY of the current node. That means that you will also get the subnodes of the current nodes as well. -->
  7. <xsl:template name="giveMeTheCurrentNode">
  8. <xsl:copy-of select="."/>
  9. </ xsl:template >
  11. <!-- This template will give you the VALUE of the current node. This will give you the ONLY the value of the current element, and ignore any subnode value. -->
  12. <xsl:template name="giveMeTheCurrentNodeValue">
  13. <xsl:value-of select="."/>
  14. </ xsl:template >
  16. <!-- For the next example we need to do some changes to the original XML. Let's say we wanted to include the date when the album was released and that we would put this information in an attribute of the record node. That would look something like this. -->
  17. < recordCollection >
  18. <record released="01.01.1982">
  19. <artist>Madonna</artist>
  20. <title>Like a prair</title>
  21. </record>
  22. <record released="01.01.2001">
  23. <artist>Gorillaz</artist>
  24. <title>Gorillaz</title>
  25. </record>
  26.     ...
  27.     ...
  28. </ recordCollection >
  30. <!-- This template will return the value of the node attribute called -->
  31. <xsl:template name="giveMeTheCurrentNodesAttribute">
  32. <xsl:value-of select="./record/@released"/>
  33. </ xsl:template >
  35. <!-- This example will show how to use XPath to compare values -->
  36. <xsl:template name="compareIwithCounter">
  37. <xsl:if test="$i &gt; $counter">
  38. <xsl:call-template name="test3">
  39. <xsl:with-param name="counter" select="$counter+1"/>
  40. <xsl:with-param name="i" select="$i"/>
  41. </xsl:call-template>
  42. </xsl:if>
  43. </ xsl:template >

XSLT - Recursion

There are a couple of things that make XSLT hard to manage and recursion is indeed one of them. There is just no way of running a traditional for loop. In order to solve this we need either a structure to iterate on, or we can create a template that calls itself with a counter and control number.

If you simply need to iterate on an XML structure, you can do a for-each loop like this:

  1. <xsl:for-each select=".//child::title">
  2. <!-- Do you thing-->
  3. </ xsl:for-each >

However, if you know that you need to iterate on a procedure "i" times, then we need to complicate things a bit.

  1. <xsl:template name="test3">
  2. <xsl:param name="counter"/>
  3. <xsl:param name="i"/>
  5. <!--We do our thing...-->
  6. <xsl:copy>
  7. <xsl:text>Hello Nerd!</xsl:text>
  8. </xsl:copy>
  9. <xsl:if test="$i &gt; $counter">
  10. <xsl:call-template name="test3">
  11. <xsl:with-param name="counter" select="$counter+1"/>
  12. <xsl:with-param name="i" select="$i"/>
  13. </xsl:call-template>
  14. </xsl:if>
  15. </ xsl:template >

To call the template we need to provide it with the starting parameters:

  1. <xsl:call-template name="test3">
  2. <xsl:with-param name="counter">0</xsl:with-param>
  3. <xsl:with-param name="i">10</xsl:with-param>
  4. </ xsl:call-template >

Make sure that you take into consideration that the if test checks if the $i is still greater than the $counter variable. If you write greater or equal you will get 10 + 1 runs of the template. Also make sure that the call comes after you've done your magic in the loop. Otherwise you just won't get anything. The template executes line by line, so if you include any code after the template call, it will execute once(!) no matter how many iterations you initially ask for.

Sunday, September 23, 2012

Working with XSLT variables

Working with variables can get you into any kind of delight or trouble. It brings in many scenarios making it tricky in ways you don't experience with other programming languages.

First of all you need to remember that xsl variables are STATIC. That means that you cannot change them once they are set. Also you need to make sure that they are in the correct scope. If you create a variable inside a template, it will only be available inside the template. However, you can create GLOBAL variables outside a template as well.

Now on to the code examples. This post is using the XML example from an earlier post on XML and XSLT.

  1. <!-- The following example creates variables in different ways. -->
  3. <!-- This variable is a simple string, hardcoded inside the variable node. -->
  4. <xsl:variable name="myString">
  5. <xsl:text>Hello Nerd!</xsl:text>
  6. </ xsl:variable >
  7. <!-- In order to print the variable we do a simple value-of call. -->
  8. <xsl:value-of select="$myString"/>

This will give us the following output:

Hello Nerd!

  1. <!-- The next variable is created by looking up the artist 'Michael Jackson' in the example XML, and assigning the record title as value to the variable. -->
  2. <xsl:variable name="myArtistAlbum" select="//record/title[../artist='Michael Jackson']"/>
  3. <!-- In order to print the variable we do a simple value-of call. -->
  4. <xsl:value-of select="$myArtistAlbum"/>

This will give us the following output:


  1. <!-- Sometimes we need to load an intire XML structure into a variable. The following exmaple loads a document by using the document() function and the filepath(./music/recordCollection.xml) as an argument. On load we set the xml files root node as the root node in the variable. -->
  2. <xsl:variable name="allArtists" select="document('./music/recordCollection.xml')/recordCollection"/>

When getting the output from this variable, we can do it in two ways.

  1. <!-- The following code gives us a result similar to the previous example. -->
  2. <xsl:value-of select="ext:node-set($myArtist)//record/title[../artist='Michael Jackson']"/>

This will give us the following output:


  1. <!-- The following example simply outputs the XML as it is inside the variable. -->
  2. <!-- <xsl:copy-of select="ext:node-set($finData)"/> -->

This will give us the following output:

  1. < recordCollection >
  2. <record>
  3. <artist>Madonna</artist>
  4. <title>Like a prair</title>
  5. </record>
  6. <record>
  7. <artist>Gorillaz</artist>
  8. <title>Gorillaz</title>
  9. </record>
  10. <record>
  11. <artist>Madcon</artist>
  12. <title>Beggin</title>
  13. </record>
  14. <record>
  15. <artist>Michael Jackson</artist>
  16. <title>Bad</title>
  17. </record>
  18. <record>
  19. <artist>Queen</artist>
  20. <title>Jazz</title>
  21. </record>
  22. <record>
  23. <artist>Muse</artist>
  24. <title>The Resistance</title>
  25. </record>
  26. <record>
  27. <artist>Duffy</artist>
  28. <title>Rockferry</title>
  29. </record>
  30. </ recordCollection >
  32. <!-- Next up we create a new variable containing an XML structure. We want to create a subset of the original XML containing only titles inside a root node. -->
  34. <xsl:variable name="titleCollection">
  35. <titleCol>
  36. <xsl:for-each select=".//child::title">
  37. <xsl:copy-of select="."/>
  38. </xsl:for-each>
  39. </titleCol>
  40. </ xsl:variable >
  42. <!-- Now when running the copy-of call we get the new XML structure printed out in the result. -->
  43. <xsl:copy-of select="ext:node-set($titleCollection)"/>


  1. < titleCol >
  2. <title>Like a prair</title>
  3. <title>Gorillaz</title>
  4. <title>Beggin</title>
  5. <title>Bad</title>
  6. <title>Jazz</title>
  7. <title>The Resistance</title>
  8. <title>Rockferry</title>
  9. </ titleCol >

Friday, September 7, 2012

Structuring the XML output.

Note: This post will be used as reference for several posts on XSLT.

If you just want to do a simple transformation where you do the same thing over and over again when a template hits, you don't really need to call templates.

Say you have a long list of records (the music kind) and you want to extract the ones by Michael Jackson, you can simply perform an if-statement inside the template.

  1. <!-- Given a structure like this one... -->
  2. < recordCollection >
  3. <record>
  4. <artist>Madonna</artist>
  5. <title>Like a prair</title>
  6. </record>
  7. <record>
  8. <artist>Gorillaz</artist>
  9. <title>Gorillaz</title>
  10. </record>
  11. <record>
  12. <artist>Madcon</artist>
  13. <title>Beggin</title>
  14. </record>
  15. <record>
  16. <artist>Michael Jackson</artist>
  17. <title>Bad</title>
  18. </record>
  19. <record>
  20. <artist>Queen</artist>
  21. <title>Jazz</title>
  22. </record>
  23. <record>
  24. <artist>Muse</artist>
  25. <title>The Resistance</title>
  26. </record>
  27. <record>
  28. <artist>Duffy</artist>
  29. <title>Rockferry</title>
  30. </record>
  31. </ recordCollection >
  33. <!-- Then you would want to have a simple template handling all records and filtering out the ones matching the artist you look for and list the artists name and album. -->
  35. <xsl:template match="record">
  36. <xsl:if test="./artist='Michael Jackson'">
  37. Artist: <xsl:value-of select="./artist" />
  38. Album: <xsl:value-of select="./title" />
  39. </xsl:if>
  40. </ xsl:template >