BLOG - Filter: Umbraco
Update of Umbraco Tag Cloud Package
Dienstag, 08. Dezember 2009, Christoph Ertl

tag cloud It was time for an update of the Tag Cloud Package introduced with the post Tag cloud for Umbraco CMS blog package. The bug removed is about having only two tags which caused a weight of -2147483648 for one of the tags.


If you already using this package just download and replace the TagCloud.dll.

If you are new to the package read the original post about my package at the introducing post Tag cloud for Umbraco CMS blog package.

Feedback is welcome.

Related Links in Umbraco
Freitag, 19. Juni 2009, Christoph Ertl

related_documents_buttonRelated links can be very useful to give the visitor an easy way to find additional information. This could be a page on your site or even a link to an external site.
How can this be realized with Umbraco?

A built in functionality is not available addressing this issue.

But there's already an extension package available. It's called Related Links. The package provides a property type allowing to add multiple internal and external links to a document.

I really feel confident with Umbraco and it's flexibility. Hence, I always think twice before installing a package.

Working with built in Features

With a few steps we can solve this issue using built in features and even get more flexibility.

Create a document type

To solve this we introduce a new document type called "Alias" with two properties "Node" and "Url". For easier editing we add a tab called "Settings" and assign the properties to this tab.

Properties of Alias Node

We want to add documents of this type to other documents. Therefore we must set the Alias document type as "Allowed child nodetype" of the document type where want the aliases to add to.

Set as allowed child node type

Create an xslt file with macro

To render the links we create an XSLT file ListAliases.xslt with the corresponding macro.
In this xslt stylesheet we iterate over all child nodes and set the href attribute according to the kind of link.

<xsl:for-each select="$currentPage/node [@nodeTypeAlias = 'alias']">
 
<
xsl:sort select="@sortOrder" order="ascending"/>
 
<
li><a>
   
<
xsl:attribute name="href">
     
<
xsl:choose
       
<
xsl:when 
         
test="string(./data [@alias = 'toUrl']) = ''"

         
<
xsl:value-of select="umbraco.library:NiceUrl(./data [@alias = 'toNode'])"/>
       
</
xsl:when>
       
<
xsl:otherwise>
         
<
xsl:value-of select="./data [@alias = 'toUrl']"/>
       
</
xsl:otherwise>
     
</
xsl:choose>
   
</
xsl:attribute>
   
<
xsl:value-of select="@nodeName"/>
 
</
a></li>
</
xsl:for-each>

Use the macro

The last step is to use the macro in the template where the related links should be displayed.

...
<h2>Related</h2>
<?UMBRACO_MACRO macroAlias="ListAliases" ></?UMBRACO_MACRO>

Working with the solution

Sample contentTo create related links we now just have to add a child node of type Alias to our document for each related link we need.

In this child nodes just set the Node or the url to link to.

In this example we have two related links - one external (Umbraco) and one internal (My Blog).

Settings of external link  Settings of internal link

The resulting page could look like the following

Rendered content

Key Benefits

  • First of all. A document type is the main feature of Umbraco and therefore this solution should work for all future releases and for all installations. See also CMS structure granularity - not only in Umbraco.
  • You can decide when to publish and when to remove the link by using the built in functionality available for all nodes.
  • This solution is very extensible. You could add additional properties to the Alias document type for instance:
    • an image to be displayed next to the link
    • a  flag for a special sort criteria
    • a description which is displayed with the tooltip of the link.
    • You could introduce a document type called "Alias group" for grouping the links in for instance "Related" and "Depends on".
    • You could even manage your links at the root of your content tree to reuse them at different nodes.

CMS structure granularity - not only in Umbraco
Sonntag, 14. Juni 2009, Christoph Ertl

publish_buttonWhat is the content? What is the structure of the content? What is a document type? What is a property of a document type? How can I reuse documents? Flexibility versus usability? How to avoid different appearance of same kind of data? How to extend the system on the fly?

These are some questions that come along when designing the internal structure of a CMS based website. Depending on your CMS some of them will be addressed with built in features, some of them could be done with some effort and some of them may not be solvable.

Here I want to show a very simple case study concerning what could/should be a document type.

The site

We want to create a site providing news items. To keep it simple we forget about authors, date to appear, date to disappear, categories and so on.

I will use the naming of the Umbraco CMS for this case study.

Straight forward Solution

Our document template (NewsItem) contains only one dynamic property called "Content" of type "Rich text editor". The title of the article is the node name itself.

Really simple. Let's write articles. Create a new content node with a meaningful name. Fill in your text in the Content area. Publish it. Ready.

The authors of the content will write text, insert some pictures and everything will be fine. Style sheets are defined well, so all articles look just the same.

Content without structure

After a while you will realize that the authors add a section for related links to external resources in the content text. Some of them write a heading called "References" listing all links with a bullet list others add a bold text named "Related" and provide the links with a comma separated list.

The result are articles formatted in many different ways destroying the corporate identity of the site.

different_style

Approach 1

The first approach would be to tell the authors that they should use a heading, call it "References" and to list the links using a bullet list. Maybe it would solve the problem if the authors work really consistent. Let's face it. Don't event think about this approach. You are using a CMS!

Approach 2

The next approach would be to add a property called "References" of type "Rich text editor" to our document type. This property would be used to write the links (again using a bullet list). The difference would be that the designer can decide how to call this section and where to place it. Even the formatting could be easier changed. Still not happy? Right.

The authors must still ensure that the formatting of the links is consistent (bullet list). Changes of the formatting could only be done by rewriting each article (ok, style sheets would also help for some situations).

The solution

The solution in terms of a CMS is to introduce another document type called "LinkItem" containing a property "Url" of type "Text string". The Friendly name of this link would be again the name of the node. This LinkItem is then declared as a "Allowed child node type" of the "NewsItem" type.

To add related links to a news item the authors add one child node of type LinkItem for each link.

Benefits

With this solution the authors now can again force their energy to write content and to provide related links. The designer can decide where to place the links, how to format them and even if they should be hidden in a special situation.

That's why we use a CMS. Isn't it?

Url Rewriting in Umbraco - Friendly Tag Filter
Samstag, 15. November 2008, Christoph Ertl

After finishing the Tag Cloud package the next step to improve my web site was to get rid of the ugly query URLs when filtering blog posts by tag.

The Goal

Instead of

/blog.aspx?filterBy=TagName

I wanted something like

/blog/tag/TagName

Why ?

  1. As we all - techies of course - know search engines are not happy with URLs like this
  2. I also had the impression that Google AdSense didn't distinguish the pages correctly.
  3. I personally don't like URLs containing query parameters on a web page as they are not user friendly.
  4. Some kind of perfectionism

The Solution

It's that simple that I was not sure if it's being worth posting. But it took me a while to find the solution. Like in most cases. It's easy if you know where and how to do it. It would be easier if the feature would be mentioned in the feature list or online help. However, here it is:

In the file /config/UrlRewriting.config one can place rules for rewriting URLs. Just add a rule like this.

<add name="tagfilter"
  virtualUrl="^~/blog/tag/(.*).aspx"

 
rewriteUrlParameter="ExcludeFromClientQueryString"
  destinationUrl="~/blog.aspx?filterBy=$1"

 
ignoreCase="true"

/>

A detailed description how it works can be found in the file itself.

One important thing is that without reconfiguring the IIS Server the URL must end up with .aspx. So the new URL looks like this

/blog/tag/TagName.aspx

which is very straight forward as all other nodes are also referenced using the aspx extension.

References

  • This Umbraco feature is powered by the ASP.NET UrlRewritingNet component which can be found at http://www.urlrewriting.net/
  • A Post where the feature is at least mentioned.
  • A Post from Warren where he points to some problems using this feature.

Sort Umbraco Nodes by sortOrder property
Donnerstag, 07. August 2008, Christoph Ertl

Today I added two nodes, changed the sorting and published the whole bunch. The first look at the resulting page was surprising because the sort order seemed to be totally confused.

After a while I realized that I reached the count of 11 nodes and the node with the sortOrder = 10 was displayed after the one with sortOrder = 1.

Got it? The property is compared as string.

The problem is that XSLT handles values as string unless you declare what type should be used.

So instead of sorting nodes with

<xsl:sort
  
select="@sortOrder"
  
order="ascending"
/>

you have to set the data-type to be used for comparison

<xsl:sort
  
select="@sortOrder"
  
order="ascending"
  
data-type="number"
/>

Tag cloud for Umbraco CMS blog package
Sonntag, 08. Juni 2008, Christoph Ertl

A view weeks ago I created the list of categories for my blog. After a while I was wondering if a tag cloud wouldn't be more intuitive and more fancy. Of course it is.

So I started to create my first Umbraco package. But before creating the package the cloud itself must be implemented.

The Tag Cloud

To get an idea what a tag cloud is and what it's based on have a look at Wikipedia.

Algorithm

There are a lot of posts and notes about tag clouds and how to calculate the weight of the tags. After reading a lot of these articles and trying some solutions myself I kept these two posts in mind.

As a result I use an logarithmic algorithm which should be fast enough and the quality of the result should be ok. Most of the posts are talking about calculating the font size, but I just calculate the weight of the tag. The font size (or color) itself is provided using stylesheets which provides a very wide range of displaying the tag cloud.

Appearance

As already mentioned this package only calculates the weight. So the appearance can be set using stylesheets. In this context the color, font size and weight are interesting. To get a usable tag cloud some points must be considered:

  • The different weights must be visual distinguishable.
  • At least when moving the mouse over a tag it should get an underline to see what's the whole name of the tag (See "ASP.NET Dynamic Data").
  • The tags should appear in alphabetical order which is done automatically.

Tag Cloud sample 
Example of one tag cloud (6 weights) using different appearances. Just fonts, Just color and a combination where 3 font sizes and 6 colors are used.

The Package

The Umbraco package is a very simple package containing

  • the dll with the calculation and rendering logic
  • an xslt file called TagCloud.xslt (at least the link to the aspx page must be corrected in this file)
  • a macro called TagCloud

Usage

As you can see in the XSLT file which is part of the package just call the Method RenderTags().

string RenderTags(XPathNodeIterator nodes, string propertyAlias, string entryPattern, int nrOfWeightRanges)

  • nodes: The nodes containing the tags to count.
  • propertyAlias: The alias of the dynamic property containing the tags. In the default installation of the blog package the alias is "categories".
  • entryPattern: The pattern used for rendering the tag. 
    Sample: <a href="blog.aspx?filterBy={0}" class="tc{1}" title="{2}">{0}</a>
    There are three placeholders available:
    • 0: The tag text (used for link text and the url)
    • 1: The calculated weight (here used for setting the stylesheet class)
    • 2: The amount of occurrence (here used for displaying as tooltip)
  • nrOfWeightRanges: With this parameter you can set how many weight ranges should be used. Having the problem with the distinguishableness in mind this should be at most a value of 5 or 6.

To get the appearance working you have to add classes for each weight in the stylesheet according to the number of weight ranges.

a.tc1 { font-size:100%; text-decoration:none; }
a.tc2 { font-size:110%; text-decoration:none; }
a.tc1:hover, a.tc2:hover { text-decoration:underline; }
...

Download

You can download the TagCloud Package here.

Usage outside of Umbraco

This package is not restricted to be used within Umbraco. Just add a reference to TagCloud.dll into your project and use the TagCloudCalculator class.

// create an instance of the TagCloudCalculator class
// passing the nrOfWeightRanges as parameter

TagCloudCalculator
cloud = new TagCloudCalculator(6);
foreach(string tag in myTags) {
 
cloud.Count(tag);
  // use this call if you already know the count
 
// cloud.Count(tag, count);
}
string html = cloud.Render(@"<a href=""blog.aspx?filterBy={0}"" class=""tc{1}"">{0}</a>");

List categories of Umbraco blog
Sonntag, 18. Mai 2008, Christoph Ertl

I'm not sure if I deleted the xslt file or am just kind a blind. But I found nothing providing me a listing of all available categories and their count of occurrence. So here is my solution.

First of all we have to know the id of the data type used for the categories. Execute the following statement against the database and note the resulting dataTypeId.

SELECT dataTypeId FROM cmsPropertyType
WHERE alias =
'categories'

The resulting id (in my case: 1094) is used in the xslt macro to get all predefined values. The macro iterates over all predefined values of the dataType with the id 1094 and counts all nodes of type umbracoBlogPost containing this predefined value.

<xsl:for-each select="umbraco.library:GetPreValues(1094)/node()">
<
xsl:sort />
<
a>
  <
xsl:attribute name="href">
    <
xsl:text>/blog.aspx?filterBy=</xsl:text><xsl:value-of select="current()"/>
  </
xsl:attribute>
  <
xsl:value-of select="." />
</
a> (<xsl:value-of select="count($currentPage/ancestor-or-self::node/descendant-or-self::node [@nodeTypeAlias = 'umbracoBlogPost' and string(data [@alias='umbracoNaviHide']) != '1' and contains(./data [@alias='categories'], current())])" />)

  <br/>

</xsl:for-each>

To get the macro work properly you have to use the id of the dataType as described above and correct the url to point to the page supporting the filterBy parameter.

How to change the creation date of an Umbraco CMS node
Freitag, 09. Mai 2008, Christoph Ertl

This is not a common task, that's why Umbraco doesn't support that directly. But sometimes it's useful to correct the creation date of a page to get consistent data.

In my case I moved old blog entries to my Umbraco blog and created posts out of notes I've taken in the past and wanted them both to occur in a correct timeline.

Ok, here we go:

The node ID

First we must know the id of the node we want to change. There are several ways to accomplish that:

  1. In the Umbraco UI move the mouse over the node you want to change and have a look at the URL displayed in the status bar (Internet Explorer).
    It's javascript:openContent(1111) where 1111 is the id of the node. This also works with the toolbar buttons (save and publish) of the content editor.
    At the end we have to publish this node so this is the preferred way.
  2. The other way is to find the node using an SQL statement. The field text represents the name of the node:
    SELECT * FROM umbracoNode WHERE text = 'nodename'
    To get all nodes where the name starts with the word CMS use the LIKE keyword combined with the wildcard character %.
    SELECT * FROM umbracoNode WHERE text LIKE 'CMS%'

Set the creation date

UPDATE umbracoNode
SET createDate = '20080430 18:00' -- see side note
WHERE id = 1111 -- id as evaluated before

This statement changes the creation date of the node but does not affect the rendering of this node. That's because Umbraco renders nodes using an internal XML structure which is generated while publishing a node.

Publish the Node

Republish the node to ensure that the XML structure is generated.
This task could also be done via an SQL statement, but I prefer using the built in functionality of the CMS.

The node now is rendered as expected.

Side notes

  • Using the ISO format for the date value ensures that the Microsoft SQL server correctly handles the value independent of the culture of the server.
    The ISO format is yyyymmdd hh:mm
  • Don't forget to use the owner of your db in the SQL statement
    e.g. SELECT * FROM owner.umbracoNode

Umbraco Upgrade from 2.1.1 to 3.0.3
Freitag, 02. Mai 2008, Christoph Ertl

Yesterday I decided to upgrade the CMS of my website to the newest version of Umbraco to get support for Windows LiveWriter. I used the book  "Install umbraco 3.0 on Windows Server 2003" from the Umbraco documentation page.

If you just upgrade, not all steps are necessary, therefore my steps were:

  • Backup files and database (optional but very recommended ;-)
  • Install .NET runtime 2.0
  • Install MSXML (just to be sure)
  • Install Ajax Extensions (just to be sure)
  • Copy the files to the webserver (change settings in web.config according to the old web.config)
  • Change the website in IIS to use .NET Framework 2.0
  • Set up umbraco from the web browser

That was easy und worked fine, but after checking the webpages I found two errors:

1.Error parsing XLST file

At the page displaying blog posts I got the following error:

"Error parsing XSLT file: \xslt\DisplayCategories.xslt"

and at the post page itself

"Error parsing XSLT file: \xslt\WordpressPosts.xslt"

The solution can be found here. Just a small correction in the javascript part and all works fine.

2.Failure when storing the xslt file via web interface

When I then started to change my blogs appearance I got the following error when storing the xslt file:

"FAILURE[object Object]"

Error Dialog

That failure was caused by an ownership permission problem. In my case I assigned permissions to the NETWORK user and everything worked fine. A detailed post about that problem and the solution can be found here.

CMS - Die Qual der Wahl
Sonntag, 06. April 2008, Christoph Ertl

Dass man heutzutage eine private Homepage hat ist ja nicht mehr ungewöhnlich. Was mich aber besonders freut ist, dass mein Vater mit über 70 Jahren auch eine Homepage möchte.
Immerhin hat er einige Jahrzehnte als Maler sein Privatleben bestritten und die Kunstwerke wollen ja auch präsentiert werden. Neben den Ausstellungen, die er immer wieder macht, ist natürlich das Internet ideal. Und mit dem Computer und somit auch dem Internet beschäftigt er sich ja ohnehin.
Nach einigen Abenden mit Diskussionen und Anregungen ist seine Seite jetzt online.
Also wer an Kunst und im speziellen an Malerei interessiert ist, hier geht's zur Seite www.hansjoerg-ertl.net

Die Auswahl des CMS

Um die Seite zu realisieren und weiterhin auch pflegen zu können sollte natürlich ein CMS her. Aber welches? Folgende Anforderungen standen bei der Wahl im Vordergrund:
  1. Klare Trennung von Inhalt und Präsentation
  2. Einfache Handhabung für denjenigen der den Inhalt pflegt
  3. Einfache Korrektur der Struktur und Präsentation über das Internet (verteiltes Arbeiten)
  4. kostenlos

Punkt 1 sollte implizit klar sein wenn man von einem CMS spricht, darum habe ich mich also vorerst gar nicht gekümmert. Aufgrund Punkt 2 war die Idee eines Clientseitigen CMS naheliegend auch wenn das Punkt 3 eigentlich ausschließt. Aber strukturelle Änderungen sind ja nur im Vorfeld zu erwarten und bei einer privaten Seite keine Sache die sofort erledigt werden muss.

Clientseitiges CMS

Ein clientseitiges CMS kann von der Usability her am besten mit der von anderen Programmen gewohnten Oberfläche und der damit verbundenen Interaktion aufwarten.

Nachdem ich mir etliche dieser Programme angesehen habe, bin ich zu der Überzegung gelangt, dass zumindest in diesem Fall die Nachteile (lokales Bearbeiten der Struktur) nicht durch die Vorteile (komfortableres UI) aufgewogen werden.

Serverseitiges CMS

Damit bleibt nur die Variante des serverseitigen CMS. Für den Umfang der Seite vielleicht ein wenig überdimensional. Aber immerhin kann man den Vorteil der Dynamik dann ja auch nutzen.
In diesem Bereich habe ich mich nicht mehr umgesehen, weil ich dbzgl. schon vor langer Zeit die Wahl getroffen hatte. Und zwar für Umbraco.

Umbraco

Die Wahl auf Umbraco fiel damals aus folgenden Gründen:

  1. Die Oberfläche zur Verwaltung und auch zur Pflege der Inhalte ist dank AJAX bereits sehr komfortabel.
  2. Klare und einfache Struktur der Oberfläche bzw. dem zugrundeliegenden Konzept.
  3. Das System ist extrem flexibel. Eine klare Trennung zwischen Struktur und Inhalt mit zusätzlicher Möglichkeit verschiedene Präsentatoren (Templates) zu verwenden und diese auch zu verschachteln.
  4. Ist in Microsoft .NET realisiert und verwendet den Microsoft SQL Server, was meinem gewohnten Arbeitsumfeld entspricht und mir als Software Entwickler somit sehr entgegenkommt. Obwohl ich bis dato keine Notwendigkeit hatte, diese Tatsache für mich zu nutzen. Ich konnte bisher alles mit den Bordmitteln des Systems und extra Packages lösen.
 
Beim Realisieren der Webseite war ich dann erneut begeistert wie einfach und schnell das mit Umbraco umgesetzt werden konnte.
Für die Grundstruktur habe ich vielleicht 25 Minuten benötigt. Die Details beim Design sind da eher ein Aufwand, aber das hat ja nichts mit dem CMS zu tun.
 
Es gibt - wie soll es anders sein - eine unüberschaubare Menge an CMS am Markt, die sich in unterschiedlichsten Kritieren unterscheiden. Die Wahl ist da sicherlich nicht einfach. Da sollte im Vorfeld auch sehr genau definiert werden, was das System leisten soll und welche Anforderungen in Zukunft zu erwarten sind. Zum Vergleich der Systeme gibt es verschiedene Websites allerdings sollte auf jeden Fall deren Aktualität der Informationen überprüft werden.