Nibble

Archive for the 'howto' Category


Getting started with Umbraco is easy! 2

The getting started with umbraco post is the most visited one on this blog. I thought I would make an update since getting started with umbraco got a lot easier recently because there are 9 free videos on umbraco.tv outlining the basics for both site builders and developers. Learn about the basis building blocks like document types, templates and macros and also see how easy it is to use .net user controls.

You can find the free umbraco foundation videos on umbraco.tv

For site builders:

For developers

These should be your first stop when diving into Umbraco!

Adding a new/custom section to umbraco, sample project 9

Simon Justesen, has a great post describing how to add new sections and trees inside umbraco (part 1, part 2).

To make it easier to get started, I thought I would provide some starter sourcecode for a demo custom section.

You can download the sourcecode here

Steps to get this running on your umbraco installation:

- Copy the assembly (CustomUmbracoSection.dll) to the \bin directory

- Copy the file custom.gif to \umbraco\images\tray\ directory

- Make a ‘custom’ directory in \umbraco and copy the editCustom.aspx page to \umbraco\custom directory

- Insert a new row in the umbracoApp table

INSERT INTO [umbracoApp]
           ([sortOrder]
           ,[appAlias]
           ,[appIcon]
           ,[appName])
     VALUES
           (9
           ,‘custom’
           ,‘custom.gif’
           ,‘custom’)

- Insert a new row in to umbracoAppTree table

INSERT INTO [umbracoAppTree]
           ([treeSilent]
           ,[treeInitialize]
           ,[treeSortOrder]
           ,[appAlias]
           ,[treeAlias]
           ,[treeTitle]
           ,[treeIconClosed]
           ,[treeIconOpen]
           ,[treeHandlerAssembly]
           ,[treeHandlerType])
     VALUES
           (0
           ,1
           ,0
           ,‘custom’
           ,‘custom’
           ,‘custom’
           ,‘.sprTreeFolder’
           ,‘.sprTreeFolder_o’
           ,‘CustomUmbracoSection’
           ,‘Trees.LoadCustomTree’)

- Update the \umbraco\config\create\UI.xml file, add:

  <nodeType alias=”initcustom”>
      <header>Custom</header>
      <usercontrol>/create/simple.ascx</usercontrol>
      <tasks>
        <create assembly=”CustomUmbracoSection” type=”Tasks.CustomTasks” />
        <delete assembly=”CustomUmbracoSection” type=”Tasks.CustomTasks” />
      </tasks>
  </nodeType>

After these steps are completed you will have to enable the new section for your user.

image

Then it should show up as the last icon in the sections (called custom, with a HAL’s camera eye icon).

image

In the custom section you’ll find this:

image

So just a sample node that will open a demo edit page.

Displaying a random image/banner on your umbraco site 9

First some info on the setup:

After installing runway to get a basic site up and running I created a folder in the media section and added several images

randompicturemediajpg

On my homepage document type I added a ‘media picker’ property called ‘Pictures’. There I’ll select the media picture folder.

randompicturecontent

All that’s left now is to write some xslt that will select a random image from the media folder.

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE xsl:Stylesheet [ &lt;!ENTITY nbsp “&#x00A0;”> ]>
<xsl:stylesheet 
    version=”1.0″
    xmlns:msxsl=”urn:schemas-microsoft-com:xslt”  
    xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” 
    xmlns:msxml=”urn:schemas-microsoft-com:xslt”
    xmlns:umbraco.library=”urn:umbraco.library”
    xmlns:myFuncs=”urn:my-scripts” 
    exclude-result-prefixes=”msxml myFuncs umbraco.library”>
 
 
<xsl:output method=”xml” omit-xml-declaration=”yes” indent=”yes”/>
 
<xsl:param name=”currentPage”/>
 
<xsl:variable name=”imageRoot” 
    select=”$currentPage/ancestor-or-self:: node[@level = 1]/data [@alias = ‘Pictures’]”/>
 
<msxsl:script implements-prefix=”myFuncs” language=”JavaScript”> 
<![CDATA[
 
var myArray = new Array();
 
function random(){     
    var index = Math.floor(Math.random() * myArray.length);    
    return myArray [index];
}
 
function addtoArray(item){
    myArray.push(item);
}
 
]]>
 
</msxsl:script> 
 
<xsl:template match=”/”>
 
<!– start writing XSLT –>
 
<xsl:call-template name=”buildArray”>
<xsl:with-param name=”arrayNodes” 
    select=”umbraco.library:GetMedia($imageRoot, ‘true’)/node/data[@alias=’umbracoFile’]”/>
</xsl:call-template>
 
<xsl:value-of select=”myFuncs:random()”/>
 
</xsl:template>
 
<xsl:template name=”buildArray”>
<xsl:param name=”arrayNodes”/>
    <xsl:for-each select=”$arrayNodes”>
        <xsl:value-of select=”myFuncs:addtoArray(string(./text()))”/>
    </xsl:for-each>
</xsl:template>
 
</xsl:stylesheet>

This snippet will output the relative url of a random picture from inside the selected media folder ( like /media/44/dsc00033.jpg ).

RandomPicture xslt: download

Only log in umbraco members when they have been approved 15

A common thing when dealing with members on your site is that they need to be approved after registration before they can access the protected area on your site.

This post describes a simple way of doing that.

On the umbraco member type I have a True/false property with the alias active. If this is set to true on the member he is an ‘active’ member and is allowed to log in.

activeproperty

 

The only thing that is needed is to override the ValidateUser method of the UmbracoMembershipProvider. So make a custom class, inherit from umbraco.providers.members.UmbracoMembershipProvider and override the method (make sure to reference umbraco.providers).

Instead of just checking if there is a member with the supplied loginname and password we’ll add some extra code that will check if the member has his active property set to true. If that is the case we return true, in all other cases we return false.

 

namespace Nibble
{
    public class CustomMemberShipProvider : umbraco.providers.members.UmbracoMembershipProvider
    {
        public override bool ValidateUser(string username, string password)
        {
            umbraco.cms.businesslogic.member.Member m =
                umbraco.cms.businesslogic.member.Member.GetMemberFromLoginNameAndPassword(
                username, EncodePassword(password));
 
            if (m == null)
            {
                return false;
            }
            else
            {
                try
                {
                    if (m.getProperty(“active”).Value.ToString() == “1″)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
 
                }
                catch
                {
                    return false;
                }
             
            }
            return (m != null);
        }
    }
}

 

Final step is to modify the web.config so that our custom membership provider is used instead of the default umbraco one. So Just change the type attribute on the umbraco membership provider to the type of the custom membership provider.

<add name=”UmbracoMembershipProvider” type=”Nibble.CustomMemberShipProvider”
 enablePasswordRetrieval=”false” enablePasswordReset=”false” requiresQuestionAndAnswer=”false”
 defaultMemberTypeAlias=”CobraMember” passwordFormat=”Hashed” />

 

That’s it, now the asp:login control will only login the member if he has his active property set to true.

Installing Umbraco Packages 0

I recently got a comment from a person that downloaded a package but didn’t know what steps to take to installing it.
So here is a small how to.

After you have successfully logged into umbraco go to the developer section (section menu is on the bottom left, if you don’t see the developer icon you don’t have permission to view that section).

installingpackages1

Then expand the Packages tree

installingpackages2

Since we’ll install a local (downloaded) package select ‘Install local package’, the install local package page will load.

installingpackages3

Then just choose the package from your machine and hit the load package button (it won’t be installed yet) .

Now (if it’s a valid package) you’ll see the next step. Here you’ll need to accept the license and hit the install package button

installingpackages4

If the package contains a custom usercontrol with some custom installation steps that will be loaded next (like in this case with the datefolder package).

installingpackages5

Once these custom steps have been completed (if there are any) the package should be installed.

You should now be able to view the installed package in the ‘installed packages part’ of the packages tree.

installingpackages7

There you’ll also be able to uninstall the package.

Creating custom umbraco datatypes revisited 3

Umbraco v4.0.1 introduces the abstract dataeditor class to make it easier to build custom datatypes.

So I tried to port the char limit datatype that I showed in the ‘creating custom umbraco datatypes’.

This is how it looks:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
 
namespace charLimitAbstractDataEditor
{
    public class DataType: umbraco.cms.businesslogic.datatype.AbstractDataEditor
    {
 
        private charLimitPrevalueEditor _prevalueeditor;
      
        private CharlimitControl m_control = new CharlimitControl();
 
 
        public override Guid Id
        {
            get
            {
                return new Guid(“a5dd5b89-74f5-4ed3-b855-f98ae07ea1ec”);
            }
        }
        public override string DataTypeName
        {
            get
            {
                return “CharLimit (AbstractDataEditor)”;
            }
        }
 
        public override umbraco.interfaces.IDataPrevalue PrevalueEditor
        {
            get
            {
                if (_prevalueeditor == null)
                    _prevalueeditor = new charLimitPrevalueEditor(this);
                return _prevalueeditor;
            }
        }
        public DataType()
        {
 
            base.RenderControl = m_control;
            m_control.Init += new EventHandler(m_control_Init);
            base.DataEditorControl.OnSave += new umbraco.cms.businesslogic.datatype.AbstractDataEditorControl.SaveEventHandler(DataEditorControl_OnSave);
        }
 
        void m_control_Init(object sender, EventArgs e)
        {
            m_control.Text = base.Data.Value != null ? base.Data.Value.ToString() : “”;
            m_control.Limit = Convert.ToInt32(((charLimitPrevalueEditor)PrevalueEditor).Configuration);
            
        }
 
        void DataEditorControl_OnSave(EventArgs e)
        {
            base.Data.Value = m_control.Text;
        }
       
    }
}

 

So you just need to inherit from umbraco.cms.businesslogic.datatype.AbstractDataEditor and override the Guid and the DataTypeName property.

If you also need a custom PrevalueEditor (datatype settings) you will also need to override the PrevalueEditor property.

Next step is to set the RenderControl in the constructor, the rendercontrol is just a custom control.

In this case it’s the CharLimitControl

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI;
 
namespace charLimitAbstractDataEditor
{
    public class CharlimitControl: System.Web.UI.WebControls.Panel
    {
        private TextBox txtCharLimit;
        private Label lblLimitInfo;
 
        protected override void OnInit(EventArgs e)
        {
 
            base.OnInit(e);
 
            txtCharLimit.Text = this.Text;
            txtCharLimit.TextMode = TextBoxMode.MultiLine;
            txtCharLimit.Rows = 10;
            txtCharLimit.Columns = 40;
            txtCharLimit.CssClass = “umbEditorTextFieldMultiple”;
            txtCharLimit.Attributes.Add(“onkeyup”, string.Format(“limitChars(this, {1}, ‘{0}’)”, “charlimitstatus” + this.ClientID, Limit.ToString()));
 
            lblLimitInfo = new Label();
 
            lblLimitInfo.Attributes.Add(“id”, “charlimitstatus” + this.ClientID);
 
 
            this.Controls.Add(txtCharLimit);
 
            this.Controls.Add(new LiteralControl(“<br/>”));
            this.Controls.Add(lblLimitInfo);
 
 
            string functionlimit = “function limitChars(textarea, limit, infodiv)”;
            functionlimit += “{”;
            functionlimit += “var text = textarea.value;”;
            functionlimit += “var textlength = text.length;”;
            functionlimit += “var info = document.getElementById(infodiv);”;
 
            functionlimit += “if(textlength > limit)”;
            functionlimit += “{”;
            functionlimit += “info.innerHTML = ‘You cannot write more then ‘+limit+’ characters!’;”;
            functionlimit += “textarea.value = text.substr(0,limit);”;
            functionlimit += “return false;”;
            functionlimit += “}”;
            functionlimit += “else”;
            functionlimit += “{”;
            functionlimit += “info.innerHTML = ‘You have ‘+ (limit - textlength) +’ characters left.’;”;
            functionlimit += “return true;”;
            functionlimit += “}”;
            functionlimit += “}”;
 
            ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), “limitChars”, functionlimit, true);
        }
 
        private int _limit;
        public int Limit
        {
            get
            {
                return _limit;
            }
            set
            {
                _limit = value;
            }
 
 
 
        }
 
        public string _text;
        public string Text
        {
            get
            {
                return txtCharLimit.Text;
            }
            set
            {
                if (txtCharLimit == null)
                    txtCharLimit = new TextBox();
                txtCharLimit.Text = value;
            }
        }
    }
}

 

On init I just pass the stored value and the prevalue editor configuration to the custom control.

        void m_control_Init(object sender, EventArgs e)
        {
            m_control.Text = base.Data.Value != null ? base.Data.Value.ToString() : “”;
            m_control.Limit = Convert.ToInt32(((charLimitPrevalueEditor)PrevalueEditor).Configuration);
            
        }

 

Last step is to subscribe to the base.DataEditorControl.OnSave event and set the base.Data.Value (in this case to the custom control Text property)

        void DataEditorControl_OnSave(EventArgs e)
        {
            base.Data.Value = m_control.Text;
        }

 

Download sourcecode

Fetching the nodeid in a custom datatype 2

Just a quick tip following the custom datatypes posts (Creating custom umbraco datatypes , Storing parseable xml data in a datatype ).

When creating a datatype you might at some point need to have the current document’s nodeid. Like if you want to insert some extra data in a custom table.

Since the datatypes are also used by autoform/doc2form , liveediting and not only in the umbraco backend the best approach is to fetch it like this:

((umbraco.cms.businesslogic.datatype.DefaultData)_data).NodeId

Storing parseable xml data in a datatype 6

As a follow up on the creating custom umbraco datatypes post I’ll show how to store parseable xml data in a datatype.

By default all propertry values get saved inside a cdata section(in the /data/umbraco.config file, wich has all published content).

Like in this example, a property with the alias test will look like this.

<data alias=”test”><![CDATA[1051;1052;1054]]></data>

But in some cases you would want to override this behavior, especially when you want to store xlm data.

Like the related links datatype in umbraco v4. This will store it’s links as child nodes of the data node.

<data alias=”links”>
        <links>
          <link title=”Same page” link=”http://www.google.com” type=”external” newwindow=”1″ />
          <link title=”Other page” link=”1051″ type=”internal” newwindow=”0″ />
        </links>
</data>

To do this the first step is to create a new class that inherits from umbraco.cms.businesslogic.datatype.DefaultData and overrides the ToXMl method.

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
 
namespace umbraco.editorControls.relatedlinks
{
    public class RelatedLinksData : umbraco.cms.businesslogic.datatype.DefaultData
    {
        public RelatedLinksData(umbraco.cms.businesslogic.datatype.BaseDataType DataType) : base(DataType) { }
 
        public override System.Xml.XmlNode ToXMl(System.Xml.XmlDocument data)
        {
            if (this.Value != null) {
                XmlDocument xd = new XmlDocument();
                xd.LoadXml(this.Value.ToString());
                return data.ImportNode(xd.DocumentElement, true);
            } else {
                return base.ToXMl(data);
            }
        }
 
    }
}

 

Final step is to alter the class that implements the umbraco.interfaces.IDataType interface (the one with the guid) so that the new class is used instead of the default one. So just change

public override umbraco.interfaces.IData Data
        {
            get
            {
                if (_baseData == null)
                    _baseData = new umbraco.cms.businesslogic.datatype.DefaultData(this);
                return _baseData;
            }
        }

   

To (depending on how the class is named, in this case it’s RelatedLinksData)

public override umbraco.interfaces.IData Data
        {
            get
            {
                if (_baseData == null)
                    _baseData = new RelatedLinksData(this);
                return _baseData;
            }
        }

Creating custom umbraco datatypes 21

A couple of months ago I did a blog post about Creating custom datatypes using the umbraco usercontrol wrapper , I mentioned in that post that there was also an other way of creating a custom datatype. So in this post I’ll try to show you how to create a datatype using the 3 classes way. One of the main differences between this approach and the wrapper is that you’ll be able to have settings for your datatype.

I made a very basic datatype, the char limit datatype I’ll just show how I created that one.

First step would be to create a new project in visual studio (I tend to start a new class library, but web application should also be fine) and reference the necessary umbraco assemblies (so make sure you have those, just download v4).

Here is how the solution explorer looks when the char limit solution is opened.

customdatatype

The umbraco assemblies that needs to be referenced are businesslogic, cms, interfaces, umbraco.Datalayer and umbraco.editorControls (you can find these in the bin directory of umbraco).

As you can notice in the solution explorer the projects contains 3 files.

  • charLimitDataEditor.cs
  • charLimitDataType.cs
  • charLimitPrevalueEditor.cs

These are 3 classes (that’s wy I call it the 3 classes way) implementing the necessary umbraco interfaces.

I’ll start by showing the contents of charLimitDataType.cs

using System;
using System.Collections.Generic;
using System.Text;
 
namespace Nibble.Umb.Datatypes.CharLimit
{
    public class charLimitDataType : umbraco.cms.businesslogic.datatype.BaseDataType, umbraco.interfaces.IDataType
    {
        private umbraco.interfaces.IDataEditor _Editor;
        private umbraco.interfaces.IData _baseData;
        private charLimitPrevalueEditor _prevalueeditor;
 
        public override umbraco.interfaces.IDataEditor DataEditor
        {
            get
            {
                if (_Editor == null)
                    _Editor = new charLimitDataEditor(Data, ((charLimitPrevalueEditor)PrevalueEditor).Configuration);
                return _Editor;
            }
        }
 
        public override umbraco.interfaces.IData Data
        {
            get
            {
                if (_baseData == null)
                    _baseData = new umbraco.cms.businesslogic.datatype.DefaultData(this);
                return _baseData;
            }
        }
        public override Guid Id
        {
            get { return new Guid(“71518B4E-B1A5-11DD-A22C-8AAA56D89593″); }
        }
 
        public override string DataTypeName
        {
            get { return “Char Limit Textarea”; }
        }
 
        public override umbraco.interfaces.IDataPrevalue PrevalueEditor
        {
            get
            {
                if (_prevalueeditor == null)
                    _prevalueeditor = new charLimitPrevalueEditor(this);
                return _prevalueeditor;
            }
        }
    }
}

 

This is basicly where you give the datatype it’s name and unique id. The name will show up in the rendercontrol dropdown of the edit datatype page.

customdatatype2

Each datatype needs to have a guid, when creating a new datatype make sure you change this to a unique one.

Next is the charLimitPrevalueEditor.cs file

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using umbraco.DataLayer;
using umbraco.BusinessLogic;
using umbraco.editorControls;
 
namespace Nibble.Umb.Datatypes.CharLimit
{
    public class charLimitPrevalueEditor : System.Web.UI.WebControls.PlaceHolder, umbraco.interfaces.IDataPrevalue
    {
        #region IDataPrevalue Members
 
        // referenced datatype
        private umbraco.cms.businesslogic.datatype.BaseDataType _datatype;
 
      
        private TextBox _txtLimit;
 
        public charLimitPrevalueEditor(umbraco.cms.businesslogic.datatype.BaseDataType DataType)
        {
 
            _datatype = DataType;
            setupChildControls();
 
        }
 
        private void setupChildControls()
        {
            
            _txtLimit = new TextBox();
            _txtLimit.ID = “txtLimit”;
            _txtLimit.CssClass = “umbEditorTextField”;
 
 
            Controls.Add(_txtLimit);
 
        }
 
 
 
        public Control Editor
        {
            get
            {
                return this;
            }
        }
 
 
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (!Page.IsPostBack)
            {
                
                if (Configuration.Length > 0)
                {
 
                    _txtLimit.Text = Configuration;
 
                }
                else
                {
                    _txtLimit.Text = “100″;
                }
 
 
            }
 
 
        }
 
        public void Save()
        {
            _datatype.DBType = (umbraco.cms.businesslogic.datatype.DBTypes)Enum.Parse(typeof(umbraco.cms.businesslogic.datatype.DBTypes), DBTypes.Ntext.ToString(), true);
 
 
            string data = _txtLimit.Text;
 
            SqlHelper.ExecuteNonQuery(“delete from cmsDataTypePreValues where datatypenodeid = @dtdefid”, 
                    SqlHelper.CreateParameter(“@dtdefid”, _datatype.DataTypeDefinitionId));
            SqlHelper.ExecuteNonQuery(“insert into cmsDataTypePreValues (datatypenodeid,[value],sortorder,alias) values (@dtdefid,@value,0,”)”, 
                    SqlHelper.CreateParameter(“@dtdefid”, _datatype.DataTypeDefinitionId), SqlHelper.CreateParameter(“@value”, data));
 
        }
 
        protected override void Render(HtmlTextWriter writer)
        {
            writer.WriteLine(“<table>”);
            writer.Write(“<tr><th>Character Limit:</th><td>”);
            _txtLimit.RenderControl(writer);
            writer.Write(“</td></tr>”);
            writer.Write(“</table>”);
        }
 
        public string Configuration
        {
            get
            {
                object conf =
                   SqlHelper.ExecuteScalar<object>(“select value from cmsDataTypePreValues where datatypenodeid = @datatypenodeid”,
                                           SqlHelper.CreateParameter(“@datatypenodeid”, _datatype.DataTypeDefinitionId));
 
                if (conf != null)
                    return conf.ToString();
                else
                    return “”;
 
            }
        }
 
        #endregion
 
        public static ISqlHelper SqlHelper
        {
            get
            {
                return Application.SqlHelper;
            }
        }
    }
}

This class is used to setup the datatype settings (something you can’t do when using the wrapper method). In this case it shows a textbox wich will be used to set the character limit. On save it will store this value (using the datalayer) in the database.

customdatatypes3

Last one is charLimitDataEditor.cs

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using umbraco.interfaces;
 
namespace Nibble.Umb.Datatypes.CharLimit
{
    public class charLimitDataEditor : System.Web.UI.UpdatePanel, umbraco.interfaces.IDataEditor
    {
 
        private umbraco.interfaces.IData _data;
           
        private string CharLimit;
 
        private TextBox txtCharLimit;
        private Label lblLimitInfo;
 
        public charLimitDataEditor(umbraco.interfaces.IData Data, string Configuration)
        {
            _data = Data;
 
            if (Configuration.Length > 0)
            {
                CharLimit = Configuration;
            }
            else
            {
                CharLimit = “100″;
            }
        }
 
        public virtual bool TreatAsRichTextEditor
        {
            get { return false; }
        }
 
        public bool ShowLabel
        {
            get { return true; }
        }
 
        public Control Editor { get { return this; } }
 
        public void Save()
        {
 
            this._data.Value = txtCharLimit.Text;
            
        }
 
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
 
 
            txtCharLimit = new TextBox();
 
            txtCharLimit.Text = _data.Value.ToString();
            txtCharLimit.TextMode = TextBoxMode.MultiLine;
            txtCharLimit.Rows = 10;
            txtCharLimit.Columns = 40;
            txtCharLimit.CssClass = “umbEditorTextFieldMultiple”;
            txtCharLimit.Attributes.Add(“onkeyup”, string.Format(“limitChars(this, {1}, ‘{0}’)”, “charlimitstatus” + base.ClientID, CharLimit));
 
           
 
 
            lblLimitInfo = new Label();
            
            lblLimitInfo.Attributes.Add(“id”, “charlimitstatus” + base.ClientID);
            
 
            base.ContentTemplateContainer.Controls.Add(txtCharLimit);
 
            base.ContentTemplateContainer.Controls.Add(new LiteralControl(“<br/>”));
            base.ContentTemplateContainer.Controls.Add(lblLimitInfo);
 
 
            string functionlimit = “function limitChars(textarea, limit, infodiv)”;
            functionlimit += “{”;
            functionlimit += “var text = textarea.value;”;
            functionlimit += “var textlength = text.length;”;
            functionlimit += “var info = document.getElementById(infodiv);”;
 
            functionlimit += “if(textlength > limit)”;
            functionlimit += “{”;
            functionlimit += “info.innerHTML = ‘You cannot write more then ‘+limit+’ characters!’;”;
            functionlimit += “textarea.value = text.substr(0,limit);”;
            functionlimit += “return false;”;
            functionlimit += “}”;
            functionlimit += “else”;
            functionlimit += “{”;
            functionlimit += “info.innerHTML = ‘You have ‘+ (limit - textlength) +’ characters left.’;”;
            functionlimit += “return true;”;
            functionlimit += “}”;
            functionlimit += “}”;
 
            ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), “limitChars”, functionlimit, true);
 
        }
      
    }
}

This one is used for the actual datatype dataeditor, so the control you will get in the content section of umbraco.

customdatatypes4

This class inherits from the updatepanel class and implements the umbraco.interfaces.IDataEditor. So on init you need to add the controls, in this case a textbox and a literal (for the info text on character limit) and fetch the saved data. And in the save method you can set what value needs to be saved.

Feel free to experiment with the sourcecode.

Download sourcecode

A look at the related links datatype in umbraco v4 16

A couple of weeks ago I released the related links package for umbraco v3. Recently the related links datatype has also been added as a default datatype in umbraco v4 (a more polished version).

I recorded a screencast wich will show you how to use the datatype in v4.

relatedlinksdatatype

Next Page »