Nibble

Archive for the 'howto' Category


Converting Linebreaks 3

When using the textbox multiple datatype in umbraco you might want to convert the linebreaks into html <br> tags. This can be done just by checking a checkbox in the insert umbraco field dialog when inserting a field on your template. Just look for the convert linebreaks checkbox.

image

 

image 

 

In xslt you can also do this by using the umbraco library method umbraco.library.ReplaceLineBreaks(System.String)

So that would like a this:

<xsl:value-of select=”umbraco.library:ReplaceLineBreaks(data [@alias = ‘youralias’])”/>

XSLT previous,next example 10

Say you have a structure like this on your site.

xslt

Multiple content items of the same documenttype, like news items. And you want to display a previous and a next link on those news items.

This can be done with some xslt. Here is an example:

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE xsl:stylesheet [ &lt;!ENTITY nbsp “&#x00A0;”> ]>
<xsl:stylesheet 
    version=”1.0″ 
    xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” 
    xmlns:msxml=”urn:schemas-microsoft-com:xslt”
    xmlns:umbraco.library=”urn:umbraco.library”
    exclude-result-prefixes=”msxml umbraco.library”>
 
<xsl:output method=”xml” omit-xml-declaration=”yes” />
 
<xsl:param name=”currentPage”/>
 
<xsl:template match=”/”>
 
<!– The fun starts here –>
 
<xsl:for-each select=”$currentPage/ancestor-or-self::node [@nodeTypeAlias = ‘NewsPage’]/node”>
 
<xsl:if test=”$currentPage/@id = current()/@id”>
 
 <xsl:call-template name=”prevnext”>
    <xsl:with-param name=”count” select=”count($currentPage/ancestor-or-self::node [@nodeTypeAlias = ‘NewsPage’]/node)”/>
    <xsl:with-param name=”itemindex” select=”position()”/>
  </xsl:call-template>
</xsl:if>
 
</xsl:for-each>
 
</xsl:template>
 
<xsl:template name=”prevnext” >
<xsl:param name=”count” />
<xsl:param name=”itemindex” />
 
<xsl:if test=”$itemindex > 1″>
<a href=”{umbraco.library:NiceUrl($currentPage/ancestor-or-self::node [@nodeTypeAlias = ‘NewsPage’]/node[$itemindex-1]/@id)}”>
Previous</a>
</xsl:if>
 
<xsl:if test=”$itemindex &lt; $count”>
<a href=”{umbraco.library:NiceUrl($currentPage/ancestor-or-self::node [@nodeTypeAlias = ‘NewsPage’]/node[$itemindex +1]/@id)}”>
Next </a>
</xsl:if>
 
</xsl:template>
 
</xsl:stylesheet>

The Key is to know how many nodes(newsitems) there are and what the position of the current node is (first, second, .. last) because you don’t need to display a previous link if it’s the first item or a next link if it’s the last.

UPDATE:

Petr Snobelt mailed me the following snippet, which shows another technique (no for-each loop, so should be faster)

<xsl:if test=”count($currentPage/preceding-sibling::node) != 0″>
previous
<a href=”{umbraco.library:NiceUrl($currentPage/preceding-sibling::node[1]/@id)}”>
 <xsl:value-of select=”$currentPage/preceding-sibling::node[1]/@nodeName”/>
</a>
<br />
</xsl:if>
 
<xsl:if test=”count($currentPage/following-sibling::node) != 0″>
next
<a href=”{umbraco.library:NiceUrl($currentPage/following-sibling::node[1]/@id)}”>
 <xsl:value-of select=”$currentPage/following-sibling::node[1]/@nodeName”/>
</a>
</xsl:if>

Custom document type icons/thumbnails 2

When creating or editing a  document type you are able to select an icon and a thumnail image from a dropdown.

shopdocumenttype

The icon will show up in the content section and the thumbnail will be used in the ‘Create Page’ dialog. Giving different document types a different icon/thumbnail is a good way to keep the content section a bit more editor friendly.

It’s also verry easy to add your own custom icons/thumbnails the only thing you need to do is add your images to the folders where these images are stored

Thumbnails:

\umbraco\images\thumbnails

Icons:

\umbraco\images\umbraco

So to add this icon shop  to the icons dropdown I just need to copy it into the right directory. Afterwards it will show up in the icon dropdown and I can use this on my document types.

customicon

Why Umbraco rocks - alternative templates 76

The main building blocks of umbraco are as you know document types and templates. When creating a document types the umbraco interface will give you the options to also create a templates that is then setup as the default template on that document type. If you open up the details of a document types you’ll be able to see the ‘allowed templates’ part on the info tab.

image

Document types aren’t limited to 1 template and this is great! You can easily swith to an ‘alt template’ by simply editing the url of your page.

So if you would have a homepage.aspx and you want to apply templatex on it you can do this by changing the url to

homepage/templatex.aspx

another option is this

homepage.aspx?alttemplate=templatex

In the beginning I didn’t use alternative templates that much but it’s a great way to keep your content section clean.

For example an email to a friend page, instead of making this a new documenttype and adding it to the content en then passing the id of the page you want to email…

You can simply add an email to a friend template and call it up as an alternative template, that way you won’t need to pass the nodeid because you are still on the same node !

Creating a youtube macro for umbraco (with xslt extension) 19

I got this request from Bernie.

He wanted a way to insert youtube videos into the richtexteditor by only supplying the link to the video (like http://www.youtube.com/watch?v=fruHQhNe-UM)

When inserting the macro you would get this screen, only asking for the link.

image

After hitting ok it will insert the embed code and the video will be visible on the page.

I’ll go through the different steps I did to develop this macro.

First take a look at the embed code supplied by youtube.

<object width=”425″ height=”344″>
<param name=”movie” value=”http://www.youtube.com/v/fruHQhNe-UM&hl=en&fs=1″></param>
<param name=”allowFullScreen” value=”true”></param>
<embed src=”http://www.youtube.com/v/fruHQhNe-UM&hl=en&fs=1″ 
type=”application/x-shockwave-flash” allowfullscreen=”true” width=”425″ height=”344″>
</embed>
</object>

The src attibute of the embed tag will contain the location of the video. When you compare this to the url

url: http://www.youtube.com/watch?v=fruHQhNe-UM

src: http://www.youtube.com/v/fruHQhNe-UM&hl=en&fs=1

You’ll notice that the important part is the video id. So we will need to get the video id out of the url and insert this into the src attribute of the embed code.

I did this by creating an xslt extension ( you can probably do this without the extension but this was the fastes way for me).

So I made a youtube class

public class YouTube
    {
        public static string getVideoId(string url)
        {
            Regex testYouTube = new Regex(@”(\?v=)(\w[\w|-]*)”);
 
           
            foreach (Match tempMatch in testYouTube.Matches(url))
            {
               
                return(tempMatch.Value.Substring(3, tempMatch.Value.Length - 3));
            }
 
            return “”;
        }
    }

 

And hooked this up in umbraco so I could use it as an xslt extension ( you do this by exposing your class in the \config\xsltExtensions.config file ).

With that in place it’s time to create the xslt file ( with macro )

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE xsl:Stylesheet [ &lt;!ENTITY nbsp “&#x00A0;”> ]>
<xsl:stylesheet 
    version=”1.0″ 
    xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” 
    xmlns:msxml=”urn:schemas-microsoft-com:xslt”
                xmlns:YouTube=”urn:YouTube”
    xmlns:umbraco.library=”urn:umbraco.library”
    exclude-result-prefixes=”msxml umbraco.library YouTube”>
 
 
<xsl:output method=”xml” omit-xml-declaration=”yes”/>
 
<xsl:param name=”currentPage”/>
<xsl:variable name=”url” select=”//YoutubeUrl”/>
<xsl:template match=”/”>
 
 
<object width=”425″ height=”355″>
<param name=”movie” value=”http://www.youtube.com/v/{YouTube:getVideoId($url)}&amp;hl=en”></param>
<param name=”wmode” value=”transparent”></param>
<embed src=”http://www.youtube.com/v/{YouTube:getVideoId($url)}&amp;hl=en” type=”application/x-shockwave-flash” wmode=”transparent” width=”425″ height=”355″></embed>
</object>
 
</xsl:template>
 
</xsl:stylesheet>

 

This will return the embed code and get the video id from the url (wich is a parameter of the macro ) by calling the xslt extension.

Macro parameters look like this:

image

Adding a language selector to your multilingual umbraco site 37

Create mutlilingual sites with umbraco, there are several approaches in doing this, the one I use the most is to have multiple ‘top level’ nodes (I’ll make a screencast of this in a future post). So for each language you would have a top level node.

The content tree would look like this:

languageselectorcontent

I would like to add a language selector on the site, a dropdown with all languages that will redirect to the selected langauge homepage. How to do this ?

languageselector

I’ll first add a new property to the top level node document type. This will store the text that is displayed in the dropdown.

languageselectordocumenttype

Next step is to create a new xslt file (with macro).

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE xsl:Stylesheet [ &lt;!ENTITY nbsp “&#x00A0;”> ]>
<xsl:stylesheet 
    version=”1.0″ 
    xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” 
    xmlns:msxml=”urn:schemas-microsoft-com:xslt”
    xmlns:umbraco.library=”urn:umbraco.library”
    exclude-result-prefixes=”msxml umbraco.library”>
 
 
<xsl:output method=”xml” omit-xml-declaration=”yes”/>
 
<xsl:param name=”currentPage”/>
 
 
            
 
<xsl:template match=”/”>
<form>
<select name=”langselection” onchange=”loadPage(this.form.elements[0])” target=”_parent._top” >
<option selected=”selected”>– Please select –</option>
 
  <xsl:for-each select=”$currentPage/ancestor::root/node”>
         
         <option value=”{umbraco.library:NiceUrl(@id)}”><xsl:value-of select=”data [@alias = ‘language’]”/></option>      
    
  </xsl:for-each>
</select>
</form>
 
</xsl:template>
 
</xsl:stylesheet>

This will output the html code for the dropdown. The most important part is the for-each loop, wich will loop all top level nodes, add the url of the top level node as a value of the dropdown option and add the content of the language property as the displayed text of the drop down option.

Now you can add the macro to your template, but you’ll also need to add a little javascript.

<script language=“JavaScript”>
 
function loadPage(list) {
 
  location.href=list.options[list.selectedIndex].value
 
}
 
</script>

Debugging .net usercontrols 5

After adding custom .net usercontrols to your umbraco site, you might want to debug them.

Only thing you need to do is attach to the w3wp.exe process with visual studio.

image

Just Tools/Attach to process or ctr+alt+p, then select w3wp and hit attach.

Creating custom datatypes using the umbraco usercontrol wrapper 20

I showed how easy it is to add custom .net usercontrols to your umbraco site frontend (http://www.nibble.be/?p=12). It is also very easy to add .net usercontrols wich you can use as custom datatypes. There are 2 ways of doing this, one being the umbraco usercontrol wrapper wich I will explain in this post.

Why add custom datatypes ? Default umbraco has around 20 datatypes, including true/false, simple editor, richtext editor,…everything for managing a basic site, but sometimes you might need to do something that you can’t do with the default datatypes.

An example shown at codegarden 07 was an ftp datatype. Other examples could be: a dropdown wich lists all files found in a specific folder, a dropdown listing data from another database, …

So how do we do this ? First reference the umbraco.editorControls assembly (can be found in the bin directory of umbraco). Then create a new usercontrol.

Your usercontrol will need to implement the umbraco.editorControls.userControlGrapper.IUsercontrolDataEditor interface

public partial class Demo : System.Web.UI.UserControl, umbraco.editorControls.userControlGrapper.IUsercontrolDataEditor  

You will need to implement the interface member value.

namespace UmbracoCreateCustomDatatypeWithWrapper
{
    public partial class Demo : System.Web.UI.UserControl, umbraco.editorControls.userControlGrapper.IUsercontrolDataEditor  
    {
        public string umbracoValue;
 
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Page.IsPostBack)
            {
                
            }
        }
 
        public object value
        {
            get
            {
                return umbracoValue;
            }
            set
            {
                umbracoValue = value.ToString();
            }
        }
    }
}

 

Now you can add controls and logic to your usercontrol. One important thing you need to know is that the umbraco save action will trigger a postback. So you will need to set the umbracovalue on postback. Just take a look at the ftp datatype…

protected void Page_Load(object sender, EventArgs e)
        {
            if (Page.IsPostBack)
            {
                if (!String.IsNullOrEmpty(uploadFile.FileName))
                {
                    string file = Server.MapPath(“/media/ftp/” + uploadFile.FileName);
                    uploadFile.SaveAs(file);
                    FileInfo fi = new FileInfo(file);
                    UploadFile(fi,
                        ConfigurationManager.AppSettings[“ftpDataTypeUser”],
                                                ConfigurationManager.AppSettings[“ftpDataTypePassword”],
                        ConfigurationManager.AppSettings[“ftpDataTypeServer”]);
                    File.Delete(file);
                    umbracoValue = “http://” + ConfigurationManager.AppSettings[“ftpDataTypeServer”] + “/” + uploadFile.FileName;
                }
            }
 
            FileName.Text = umbracoValue;
        }

Adding this usercontrol as a datatype can be done a a few simple steps, first copy the assembly to the bin directory and copy the usercontrol to the usercontrols directory.

Now login to the umbraco backend and go to the developer section.

image

There you will need to create a new datatype.

Then select umbraco usercontrol wrapper as rendercontrol and hit save.

image

You will have to choose the usercontrol ( the one just uploaded )  and the database datatype ( depending on the type of object you are returning as umbracovalue ).

Demo project: download

Creating members programmatically 41

Maybe you want to import a number of members or create a custom registration form. You can use the umbraco api to create, update and delete members

I’ll first create a ‘demo’ member type and add 2 properties.

image

Address (alias address) and City (alias city) both of the type textstring.

Owkey now I am ready to write some c# code that will create a new member.

Before I can access the umbraco member api I need to reference cms.dll and businesslogic.dll (these can be found in the bin folder of umbraco).

Now I’ll add a new usercontrol to my project where a member can register. With a couple of textboxes and a button.

image

So the code I need to execute on the click event of the button is:

first add this at the top

using umbraco.cms.businesslogic.member;
using umbraco.cms.businesslogic.propertytype;

And on the click event:

if (Member.GetMemberFromEmail(txtEmail.Text) == null)
{
                MemberType demoMemberType = new MemberType(1040); //id of membertype ‘demo’
                Member newMember = Member.MakeNew(txtName.Text, demoMemberType, new umbraco.BusinessLogic.User(0));
 
                newMember.Email = txtEmail.Text;
                newMember.Password = txtPassword.Text;
                newMember.LoginName = txtUsername.Text;
 
                newMember.getProperty(“address”).Value = txtAddress.Text; //set value of property with alias ‘address’
                newMember.getProperty(“city”).Value = txtCity.Text; //set value of property with alias ‘city’
 
                newMember.Save();
}
else
{
                //member exists
}

 

First I check if there is no other member with the email address, if the email address is not used yet I can make a new member.

Demo project: download

XSLT formatting dates 4

Recently I needed to get a date in this format : April 19th 2008

Getting a format like ‘April 19 2008′ is easy, you can just use the umbraco library method FormatDateTime. But to get to the ‘April 19th 2008′ format I needed to write a some extra xslt.

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE xsl:Stylesheet [ &lt;!ENTITY nbsp “&#x00A0;”> ]>
<xsl:stylesheet
version=”1.0″
xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”
xmlns:msxml=”urn:schemas-microsoft-com:xslt”
xmlns:umbraco.library=”urn:umbraco.library”
exclude-result-prefixes=”msxml umbraco.library”>
 
 
<xsl:output method=”xml” omit-xml-declaration=”yes”/>
 
<xsl:param name=”currentPage”/>
 
<xsl:template match=”/”>
 
<!– The fun starts here –>
 
<xsl:for-each select=”$currentPage/node [string(data [@alias=’umbracoNaviHide’]) != ‘1′]”>
<xsl:variable name=”day” select=”substring(@createDate,9,2)” />
 
<xsl:choose>
<xsl:when test=”$day = ‘01′ or $day = ‘21′”>
<xsl:value-of select=”umbraco.library:FormatDateTime(@createDate,’MMMM d’)”/>st <xsl:value-of select=”umbraco.library:FormatDateTime(@createDate,’yyyy’)”/>
 
</xsl:when>
<xsl:when test=”$day = ‘02′ or $day = ‘22′”>
<xsl:value-of select=”umbraco.library:FormatDateTime(@createDate,’MMMM d’)”/>nd <xsl:value-of select=”umbraco.library:FormatDateTime(@createDate,’yyyy’)”/>
 
</xsl:when>
<xsl:when test=”$day = ‘03′ or $day = ‘23′”>
<xsl:value-of select=”umbraco.library:FormatDateTime(@createDate,’MMMM d’)”/>rd <xsl:value-of select=”umbraco.library:FormatDateTime(@createDate,’yyyy’)”/>
 
</xsl:when>
<xsl:otherwise>
<xsl:value-of select=”umbraco.library:FormatDateTime(@createDate,’MMMM d’)”/>th <xsl:value-of select=”umbraco.library:FormatDateTime(@createDate,’yyyy’)”/>
</xsl:otherwise>
</xsl:choose>
 
</xsl:for-each>
 
 
</xsl:template>
 
</xsl:stylesheet>

First I created a variable day that retrieves the day out of the createdate and then depending on wich day it is I add ’st’, ‘nd’, ‘rd’ or ‘th’.

« Previous PageNext Page »