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;
    this.name = 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!");
    custFigures.push(custFigure);
 
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;
}
</style>


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.beginPath();
   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);
   ctx.fill();

   //Fig center
   ctx.beginPath();
   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);
   ctx.fill();

   //Fig right
   ctx.beginPath();
   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);
   ctx.fill();
}


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">  
  <record>  
  <artist sex="female">Madonna</artist>  
  <title>Like a prair</title>  
  </record>  
  </xsl:variable>  
  <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">  
 </xsl:template>   

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">  
  </xsl:if>  
 </xsl:template>  

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
_spBodyOnLoadFunctionNames.push("rewriteNavigationLinks");

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;
  }
 }
}
/script

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

E.g.
http://intranet.foo/somepagename.aspx?pid=000#openinnewwindow

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
Problem:
When searching from MySite you get “The page you're looking for doesn't exist”
Reason:
The search URL is wrong and SharePoint cannot find the pages that display the search results.
Solution:
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"$
ssa.Update()

 
Cheers,
Morten

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 >
  5.  
  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 >
  10.  
  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 >
  15.  
  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 >
  29.  
  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 >
  34.  
  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"/>
  4.  
  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. -->
  2.  
  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:

Bad

  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:

Bad

  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 >
  31.  
  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. -->
  33.  
  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 >
  41.  
  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)"/>

OutPut:

  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 >
  32.  
  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. -->
  34.  
  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 >

Tuesday, August 7, 2012

How to create an XSLT template

This is the second post in my flash post series on XSLT. We'll start off with some simple examples and move up to advanced as we get the most important components in place.

   1:  <-- The most basic thing you should know about is how to create and call a template. 
   2:  A template is a procedure that is executed when a certain criteria is met. 
   3:  That we will come back to.
   4:   -->
   5:   
   6:  <!-- First off is the template. A template is the most basic element in an XSLT sheet.
   7:  This perticular template targets the XML root node, but gives no output.-->
   8:   
   9:    <xsl:template match="/">
  10:    </xsl:template>
  11:   
  12:  <!-- The following template targets any node and attribute, 
  13:  but gives no output.-->
  14:   
  15:      <xsl:template match="@* | node()">
  16:      </xsl:template>
  17:    
  18:  <!--Now, for the first two, they are executed no matter how the source is structured. 
  19:  The next two act a little differently. While the one matching "title" is executed 
  20:  whenever the engine finds a title node, the template named "mySpecialTemplate" 
  21:  is executed ONLY when called. For this example I'm basically calling it from 
  22:  inside the first template to show how it is done. A template can be called from 
  23:  inside any template at any time.-->
  24:    
  25:  <!-- This template targets all nodes of the type title -->
  26:   
  27:      <xsl:template match="title">
  28:          <xsl:call-template name="mySpecialTemplate" />
  29:      </xsl:template>
  30:    
  31:  <!-- This template has a name and is executed on command -->
  32:   
  33:      <xsl:template name="mySpecialTemplate">
  34:      </xsl:template>


Sunday, August 5, 2012

XSLT transformations with .Net

How the transformation works with .Net.

Using .Net and C# you can do XSL transformations using XslCompiledTransform(). As input to the XSLT engine we use an XSLT sheet, settings (optional), parameters (optional), an XML source and the output path.

Note: Please note that if you need to use XSLT 2.0 or XPath 2.0 you should use a third party XSLT engine.

   1:  // C# code - using .Net 4.0
   2:   
   3:  // We want to enable document() functions and script() inside the XSLT code. 
          In order to allow this in using .Net we include this in the settings. 
          This gives us a bit more power as far as .Net XSLT support goes.
   4:  var settings = new XsltSettings(true, true);
   5:   
   6:  // This is the XSLT engine object
   7:  var xslTransform = new XslCompiledTransform();
   8:   
   9:  // We load the XSLT and settings to the engine.
  10:  xslTransform.Load(XSLTSheetPath, settings, new XmlUrlResolver());
  11:   
  12:  // As there is no way of generating e.g. date objects inside XSLT 1.0 
          (the only one supported by .Net) we do this outside the code and include 
          it as a parameter.
  13:  // Argument list (Params)
  14:  var xslArg = new XsltArgumentList();
  15:  // Grabbing current DateTime
  16:  DateTime time = DateTime.Now;
  17:  // Create a parameter which represents the current date and time.
  18:  xslArg.AddParam("date", "", time.ToString("s"));

Now, as we create the result file we want the transformed output to populate, we apply the source XML, 
arguments (params) and XML writer to the XSLT engines Transform() function. This is when/where the 
transforation is performed and the end of any C#/.Net involvement for now.


   1:  // Transform the file.
   2:  using (XmlWriter w = XmlWriter.Create(XMLResultPath))
   3:  {
   4:      xslTransform.Transform(XMLSourcePath, xslArg, w);
   5:  }
   6:   
   7:  // The entire transforming class could look like this:
   8:  using System;
   9:  using System.Diagnostics;
  10:  using System.Globalization;
  11:  using System.Xml;
  12:  using System.Xml.Xsl;
  13:   
  14:  namespace XSLTGenerator
  15:  {
  16:      class XMLTransformer
  17:      {
  18:          public void TransformXmlUsingXSLT(string XMLSourcePath, 
                   string XSLTSheetPath, string XSDSchemaPath, string XMLResultPath)
  19:          {
  20:              try
  21:              {
  22:                  // Creating settings to enable document() and script()
  23:                  var settings = new XsltSettings(true, true);
  24:   
  25:                  var xslTransform = new XslCompiledTransform();
  26:   
  27:                  // Load XSLT stylesheet
  28:                  xslTransform.Load(XSLTSheetPath, settings, new XmlUrlResolver());
  29:   
  30:                  // Create the XsltArgumentList.
  31:                  var xslArg = new XsltArgumentList();
  32:                  
  33:                  DateTime time = DateTime.Now;
  34:                  
  35:                  // Create a parameter which represents the current date and time.
  36:                  xslArg.AddParam("date", "", time.ToString("s"));
  37:                  // Create a parameter for GUID
  38:                  xslArg.AddParam("id", "", new Guid().ToString());
  39:   
  40:                  // Transform the file.
  41:                  using (XmlWriter w = XmlWriter.Create(XMLResultPath))
  42:                  {
  43:                      xslTransform.Transform(XMLSourcePath, xslArg, w);
  44:                  }
  45:              }
  46:              catch (Exception e)
  47:              {
  48:                  Debug.WriteLine(e.Message);
  49:              }
  50:          }
  51:      }
  52:  }

The next entry will create some basic building blocks 


Thursday, July 12, 2012

Future entries...

Hi there!

Long time - no blogging. That is no good. I've realized that if I am to have a blogg, I might as well write from time to time. (However, don't shoot me if I doze off again ;)

I'll be posting a series of flash posts - this time about XSLT. My plan is to cover the basics and then move up to more advanced as we go along. Each post will handle small use cases and have a common theme for you to keep up.

So, feel free to drop by in the coming weeks. I'll make an effort of keeping my promise this time ;)

- Morten

Thursday, November 25, 2010

You can Git there too :)

The ways that I work have changed in several areas over the last two years. Not only am I working with more complex systems, but I need to share what I do with a lot of people as well, and in order to collaborate we need to keep the state of our work in sync.
 
In short - what’s needed for this to work is a content management system. While there is nothing special about that, the system that I'm getting to know is better and more available than most of the other systems out there.   I am talking about Git. Now some might arrest me for calling it a CMS, so I'll quickly correct myself by stating that it is a revision control system. Regardless of that I thought it was a pain at first when I started using it.

The fact that it mainly was designed with Linux in mind didn't exactly help a Windows guy as I am, but I've actually found quite a few quirks that make my work a lot easier. These I will come back to in later posts. For now I'll stick to describing the concept.   Despite what some of my friends’ think I am not an ultra geek, thus I do not like to dive too far down into the thickest manuals and books. A lot of the material written about Git is good, but huge.

Simple descriptions on the concept itself, is not very available. (I might be a poor googler though :) ) So now I will try to explain how it works in a few bullet points.   Regardless of platform you keep your work in a directory on your computer.

When you install Git in this directory, it will map the content of the directory and add this information to a ".git" directory.   When Git is installed, you start working on the content. You add a few lines in a file here; you add a binary file there. Even if you save the file you are working on, Git only knows that something has changed. It does not know what you have changed, only that the files you have touched have changed.

To tell Git what to save, you commit your work. If you change two files and run the commit command Git will take a snapshot of the changes made. It will not record the state of the complete file, only the change. The snapshot receives an ID called a SHA1, and it represents a point in history and the state of the work at this point. As the number of these commits grows, and the content is changed by many different people, the changes are applied in the correct order dispensing only the changes in the content up until the last point synced.  

There are numerous ways of illustrating this, but I will try doing it as simple as possible.   We have users Jane and Jo. They are working on the same web site, and are using Git to synchronize their work.   Both Jane and Jo started with the same directory. They cloned this directory of the server, and started working at point A. Jane made three commits. That means that she changed the content several times, and run the commit command three times. Jo did his work in two commits. All in all, we have five registered changes in the system. Git is oblivious about any work that they have not committed yet. The only thing that matters is the work that is committed.  

The time line is like this:   Jane committed changes at points A, B and F. Jo committed changes at points C and D. Now comes the tricky part. To be able to keep their local versions in sync with the repository, they need to pull down the changes from the repository. That means that if they did not pull down the changes in the order that they appeared, their local versions would be old.

A (Jane) ----- B (Jane) ---------------E (combined) ------ F (Jane) ------
\ /
------ C (Jo) ------ D(Jo) ----B/C/D(merge)



Let’s say that Jo pulled down Jane’s changes at point A. That means that the version he started working on had everything up until point A. He then started working on the changes that eventually would turn out to be points C and D. In the meantime Jane committed point B.   At point A Jane worked on foo.html. This change is reflected in Jo's local repository. Now, at point C Jo also changed foo.html. This change was based on the state of the repository at point A. However, Jane also made some more changes to foo.html at point B. This means that When Jo wants to push his changes back to the repository after committing at point D; his version does not contain Jane's changes at point B.

These changes have to be merged into his local repository before he can push his own changes on to the server. If the changes made in commit B and C does not overlap and conflict, the merge will happen and Jo can push the changes to the server. If there is a conflict between the changes, Git will complain and he will have to choose which version to use.  

Tricky? Well, it probably is. Just consider yourself blessed that Git usually are able to solve most problems and merges if the people using it follow good procedures.   I will follow up on this post with small (yes, small) posts on how to use Git in more detail. However, I will finish up this one with a famous quote; "If I had more time, I would have written less." #foo

Cheers, Morten

Thursday, October 1, 2009

Design flash post...

Hi there! Just including a link to the Qt Labs blog. Designing documentation is not that different from designing applications and arm chairs. It all about usability and style:) Have a look: http://labs.trolltech.com/blogs/2009/09/28/giving-the-doc-a-facelift/
So until next time, happy designing/coding! :)

Friday, September 11, 2009

Designing and programming - Part 2

This part of the series will handle the creative part of the cycle. You might loosely categorize the steps of the design process in three different stages. First is the creative methods - this stage contains methods that drives the design project forward adding new ideas and features to the design. However, systemizing the ideas and filtering them is also part of this stage. The next stage contains different methods of implementation. This is where the ideas meet the matter - where ideas become code and components. You get the idea:) The third and last stage is perhaps the most crucial one. This is where you test and evaluate your results. It is now that you have to decide whether the implementations meet with the requirements and visions of the design. The outcome of this stage will determent if the prototype is ready for some real world testing, also called a beta.
Anyways, after clearing that up, the creative stage is what this part of the series will be all about.

The Creative Stage

First of all, we need a general idea about what we want to create. Such idea is usually already there when the designer sits down to start working (kind of a give-away - really:). The next step will be to find out which ways it would be sensible to develop the ideas further. This might differ from project to project. Designing a website would require other methods than designing a tool for handling great amounts of information. However, for this project I've mainly decided to use the following methods:
  • Defining general idea
  • Brainstorming
  • Technology research through literature
  • Stating objectives
Defining the idea
Definition: We want to define the problem or find our mission, if you will. What do we want to create?
Solution: In this project, we want to create a web tool. The web provides many different types of media and ways of communicating. There is also a jungle of different tools handling these resources and providing services/methods to use them. The idea is to create a tool that gathers many of these tools into one application.

The tool should be able to receive and handle different kinds of web content. This includes handling communication as well. This means a cross between a browser, an editor and a communication tool.

Brainstorming
Definition: Brainstorming is mainly a social method, gathering a group of people spinning off ideas with the definition as a starting point. The main purpose is to come up with as many ideas as possible (almost no matter how crazy they are:), and writing them down. It is possible to do this alone as well, but the results might be richer if many minds have been to work. The rules are clear; create ideas, do not criticize any ideas(that's for later) and write them down.
Solution: Only I participated in this stage. Since this is a one-man show there is really no choice, but that doesn't mean that the method cannot be used. The result of the session is written in the table below. It divides the tool into three modules and places the different features into each of these.

Component/Feature Description Dependencies
Browser, View The browser needs a viewing window to display the graphic content from the web. It must read text, images and preferably several animation plugins. This requires implementation of a web API.
Browser, Navigation The browser must provide the user with navigation such as, back, forward, stop, reload, home etc. It must also have a complete history function. This requires implementation of a web API.
Browser, View The browser window should open in a new top level window or in a tab. This requires implementation of a windowing API.
Browser, Tools Further, the window should have a menubar, toolbar, statusbar, addressbar to provide actions for the user. This requires implementation of a window tool API.
Browser, View On hovering a window tab, a preview of the window should pop up. This requires implementation of a web API and an event handler.
Browser, View On hovering a link for five seconds, a preview of the destinated site should pop up. This requires implementation of a web API and an event handler.
Browser, View History should appear as a collapsible tree based on domain This requires the web(navigation) API and an API displaying lists.
Browser, Tools Normal functions as open, save, search, close, exit, edit, print, source, help, about, zoom, tips, select all copy, cut, paste, view functions (expand, full page, minimize) This requires an API for handling text and media.
Browser, Tools Print/download pagetree. The tree contains of the current page and linked documents two to four levels down. The tree should be checkable. This requires a dialog and printing API.
Browser, Tools Bookmarks: Bookmarks should be organized in a table. Links should be movable, delete and editable. Folders should also be possible to use. This requires a dialog and item view API.
Browser, View Enable sending a page to a different window. (i.e) send the search result to a side window to click the links and open them in a separate window. Might be interesting to use a search line edit and list the result in a page on the side redirecting the pages opened to the main view. This requires a web and a windowing API.
Component/Feature Description Dependencies
Editor, View/Edit Enable the user to analyze the web content. This content should include HTML, CSS, JS and XML etc. The code should be color-coded and the editor should be keyword aware, i.e. able to tell content from code. The code values should be editable on the fly. This requires a web API, a text editor API and logic functions.
Component/Feature Description Dependencies
Communication, Chat/Messaging Chat/news part should be docked on the side of the main window. This requires implementation of a windowing API that can handle docking of sub windows.
Newsfeeds, Tools Rss in separate window. List news and make them clickable. This requires a web API.
Communication/Multimedia, Tool Enable the user to download and upload files. More specifically podcast and mp3. This requires a web API and a media API.

Subjects to investigate:
Component Feature/Technology Description Investigate
Application Threads To make certain parts of the tool run smoothly, threads might be improve performance. Threads and need for such.
Application Mouse gestures The user should be able to use mouse gestures to navigate or use the gestures with tools. This requires an event handler API.


Technology research through literature
Definition: This method covers much of the research part. The goal is to map what kind of tools to use to be able to implement the ideas emerged in the previous stage.
Solution: Since this is a project with a rather limited work force (I'm the only one:) it would be sensible to use a framework providing predesigned elements, thus reducing the amount of code to write. Qt from Nokia is such a framework that can provide the functionality and elements I need for this design. There are several other frameworks out there as well, but out of loyalty and my knowledge about it, I've decided to use Qt. There are a number of different perks involved with using Qt as well. Qt is cross-platform, meaning the code can be written for several platforms. Qt's rich modules also provide me with a selection of different technologies enabling me to stick to fewer systems and the trouble of integrating them together. The Webkit module and network module is such examples.
Many of the features require customizing the very bricks that make up the web as it is. HTML, CSS and JavaScript are all major actors in the design and will need to be integrated into some of the tools features.

Stating objectives
Definition: This method is all about systemizing the different conditions related to such a tool. When you're finished digging for ideas and know what tools are available, then this is the stage where the big plan is written and the road ahead is mapped. All external factors like environment, context and requirements must be stated now. Use cases and conditions should also be stated at this stage, together with a good overview of available resources and a time plan.
Solution:

Now as I said, this is where your plan comes together. Yet, since this is not a project any external requirements, (there's no boss breathing down my neck ;) I'm not going to create a restraining schedule. However, I do need some kind of plan. In the following table, I will state most of the necessities and requirements of the project and a solution on how to implement the tool.

Requirement Solution
Web API Qt Webkit will cover most of the requirements related to the web interface. In addition, there will be a need for AJAX and knowledge of the central web technologies and their syntax.
Windowing API Qt provides a rather large windowing API. This includes docking of windows, toolbars, statusbars etc and tabbed windows. It will be sufficient for this project, so that is what I'll start with.
Event and Signal handler API Qt provides a large event handler API. This will be enough to create event handlers for both keyboard and mouse.
Text handling API Qt provides a large API for handling text. This means both text and strings as strings of code.
Dialog API Qt provides a good dialog API and it can handle a lot of different dialogs.
Item view Qt also provides a good item view API. This includes lists, tables and trees.
Paint and print API Qt provides a large API for both painting and printing. This can also use graphics hardware to render images and windows faster. This might be handy when displaying previews while keeping the application running smoothly.
Summary:
So that is at least the short version of that first run through the creative processes. Having to go back to these steps multiple times is and will be necessary to develop and update ideas both old and new. Creativity usual means a lot of work. At least when you've been able to be very creative. Including all ideas in this post makes no sence, so I'm keeping a backlog including the things I have not written down here. This way the chance of "loosing" ideas will be less.

Now, this is not a template of how a creative process should be run, but it should give a picture of how it could be. The important part is that you follow this mantra; develop ideas - develop product - test results.

So, as always you are welcome to leave comments or questions. The purpose of this series is not to be academic, but if you have views or comments, I would love to read them.