Auto Sort package for Umbraco released

by SaschaWolter 9. March 2011 17:33

After sorting 150 nodes manually in the Umbraco backend I thought to myself that it can’t be too hard to write some kind of automatic sorting dialog. First I thought about adding some options to the existing sort dialog, which would swirl the child nodes in the list around to the editors content, yet that seemed like too much effort to just sort the nodes, the editor would still have the option to do some manual ordering using the built-in Umbraco sort after the automatic sort. The next idea was to add another option to the context menu, then ideally open up a sub menu so you could just go ‘Auto sort –> descending’ and it would go off. Apart from the fact that it would be quite a bit of work to get that sub menu working (I recently read somewhere that it’s probably coming in version 5 Smile, looking forward already) it had a couple of additional downfalls: the sort might be triggered by accident and it would be quite difficult to get additional options in there, e.g. the field you want to sort by. That pretty much left the option to give Auto Sort it’s very own popup window.

The options I ended up with in the end are the following:

  • The field to sort the nodes by. Currently supported are
    • node name
    • id
    • creation date
    • note type alias and
    • custom fields (you have to provide the alias of your custom property);
    additionally for content nodes there are also
    • update date
    • release date
    • expiry date and
    • creator name
    to choose from. (default: node name)
  • Sort either ascending or descending (default: ascending)
  • Include grand children in the sort or not. Including grand children will sort ALL children and grand children by the field you have selected recursively. (default: exclude grand children)
  • Include all unpublished nodes in the sort, or choose to exclude them. (default: include)
  • If you exclude unpublished nodes from the sort you will need to provide the location of the unpublished nodes, either at the top of the list or at the bottom (default: top)

Once the first sort using node name was working it was a nearly a breeze to make the additional options work as well. Some issues occurred with regards to the differences between content and media nodes, but nothing that a couple of if-else statements couldn’t handle. Here are some screen shots:

 

 

The trickier bit was then to add support for multiple languages. The respective keys had to be added to the specific language xml files in /umbraco/config/lang. The Package Actions Contrib package by Richard Soeteman (essential for each Umbraco package builder) contains the fantastic AddLanguageFileKey action by Chris Houston, which would have done the deed yet would also have been a bit cumbersome since I had to add like 20 keys for each language, and also I wanted to add my own area in the language files. So I extended the custom package action to take a list of key-value-pairs and the name for a new are to create the section in the specified language file [note to self: send the code to Richard Soeteman so he can add it to the contrib package]. At the time of writing there are only 2 languages missing thanks to the community, which is absolutely awesome, I’ll include them shortly in the package. Credit goes to the following translators:

  • kows for the Dutch version
  • Patrik Wibron for the Swedish version
  • Mike for the French version
  • Morten Balle for the Dansk version
  • ricardo for Italiano and Spanish (double high five!)
  • Korean version anyone?
  • Norwegian maybe?

I hope you enjoy the package and that it makes your life even easier than developing web sites with Umbraco already is. Skål!

Tags:
Categories:

Linq2Umbraco driver for LINQPad

by SaschaWolter 24. February 2011 06:55

Having used Linq2Umbraco for a while now to retrieve Umbraco data in custom DALs I really needed a way to build queries and execute them against the Umbraco web site’s data without each time compiling the application and maybe even firing up the debugger. Enter LINQPad by by Joseph Albahari, a fantastic program which has pretty much replaced SQL Server Management Studio on my workstation for querying databases. Although you can query the Umbraco database of your web site LINQPad can’t natively operate on an UmbracoDataContext, which is what Linq2Umbraco is using when you export the Umbraco document types to .Net and which you will be using when querying the data in the DAL. So it would be really helpful if you can use the UmbracoDataContext directly in LINQPad as you can use these queries 1:1 in your code. Thankfully LINQPad can be extended to work with custom DataContexts, all that needs to be done is to write a custom data context driver as described here. The documentation is exceptionally good and after a short while the first Linq2Umraco driver for LINQPad was ready and is now free to download:

Download TheFarm Linq2Umbraco Driver for LINQPad 1.0 (16.08kb)

The driver has been compiled against LINQPad 2.31 using .Net 3.5, so it should work fine on both current versions of LINQPad (.Net 3.5 and 4). The umbraco.Linq.Core.dll, which the driver needs as it contains the UmbracoDataContext, will be dynamically loaded. The driver assumes that it exists in the same directory as the dll which contains the custom Linq2Umbraco DataContext. The dynamic loading has 2 advantages:

  • The size of the driver is only 16kb! Smile No need to pack all the dlls in there as they are all present in your Umbraco installation anyway. And this way the driver isn’t bound to one specific Umbraco version.
  • LINQPad requires it’s driver assemblies to be strongly signed, and .Net requires every referenced assembly to be strongly signed as well. However umbraco.Linq.Core is not strongly signed, and although I managed to strongly sign the assembly by using a little tool it did create havoc to the Umbraco installation, so dynamically loading the assembly magically resolves all that headache!

Following is a quick demonstration of the driver in use. I’ve created a small test Umbraco installation with a couple of document types and content nodes:

demo_doctypes

demo_content

The doc types contain just a couple of standard fields like text string, data,  plus one Ultimate picker instance on the Products page (checkbox list, saved as comma delimited string). Now I’ll export the document types to .Net by right clicking on ‘Document Types’, the popup window will be populated like this:

demo_export

It doesn’t matter if you choose POCO with or without abstractions. It is also very advisable to install Matt Brailford’s fantastic AutoExport2DotNet package, it will perform an export to .Net every time you modify the document types.

After downloading and renaming the UmbracoDataContext files I’ll include them in the custom DAL like so:

demo_solution_explorer

As you can see at the moment the DAL project doesn’t contain anything else but the two automatically generated files plus the necessary link to umbraco.Linq.Core. The Umbraco 4.6.1 test installation is showing up right next to it, I need the /App_Data/umbraco.config file from it later.

Now let’s start up LINQPad and add a connection using the custom driver:

demo_add_connecton

Clicking on View more drivers… will reveal the following dialog, where Browse… let’s you select the custom LINQPad driver:

demo_add_driver

Opening the driver will shortly lead to the message ‘Driver successfully loaded’, the driver will now appear in the list of drivers from above:

demo_driver

After hitting ‘Next’ the following dialog will appear:

demo_dialog

Here the properties for the Linq2Umbraco connection are set.

  • Path to custom assembly: This is the assembly that contains the exported UmbracoDataContext, in this case it’s TheFarm.DAL.dll
  • Full name of custom type: A popup window will present you a list of all UmbracoDataContexts in the assembly, in 99% of the cases there will only be one and in this case it’s the TheFarmDemoDataContext as specified above
  • /Appdata/umbraco.config: The umbraco.config file of the Umbraco installation found in /App_Data.
  • Surpress lazy secondary queries: UmbracoDataContext uses the AssociationTree class to list children, e.g. the class Products will contain a list of ProductCategories. When querying Products you will most likely not want to generate a list of all ProductCategories for each Product, Surpress lazy secondary queries will tell the program to stop evaluating these expressions as well.

After hitting OK the connection will be added to LINQPad and you can start querying the custom UmbracoDataContext:

demo_query1

Notice here the output of TopProducts (Ultimate picker), Introduction (Richtext editor) and PricesValidUntil (date). ProductCategorys and Productss are the above mentioned children and grand children which are here surpressed with ‘Surpress lazy secondary queries’. Another example:

demo_query2

You can also easily create custom Linq Extension methods e.g. in the DAL and use them in your queries like so:

demo_query3

[Credits for the ToCSV extension go to Muhammad Mosa.]

TheFarm Linq2UmbracoDataContextDriver 1.0.lpx (16.08 kb)

Categories: .Net | Umbraco

Embedded Content v 1.1 out now

by SaschaWolter 14. February 2011 09:27

I’ve just released a new major version of Embedded Content, a data type for Umbraco developed here at TheFARM. Quite a considerable amount of work went into developing this release and includes the following improvements:

  • Properties can now be made mandatory and can additionally be validated against a provided regular expression
  • Visual improvements
  • You can now choose in the prevalue editor which additional information apart from the name and the alias of a field you want to display in the list. E.g. if you want to see with one glance which of the fields are mandatory and which ones are not you can just turn it on in the interface. The selected options will also be saved when you saved the data type, so you don’t need to change it every time you edit the data type.
  • To enable the use of additional symbols the prevalue schema had to change. Included in the package is an automatic upgrader though which will be executed after you’ve installed the new version (this is only relevant of course if you’ve used the data type pre-1.1).
  • There have been a range of bug fixes, and I want to especially thank Michael Rutherford and Geoff Beaumont of the Umbraco community for providing very helpful feedback in the beta phase of v 1.1!

Here are some screenshots:

EC14_thumb[2]

EC23_thumb[2]

 

Upgrading from pre-1.1 to 1.1:

The best way to upgrade to version 1.1 is to completely uninstall the package (without touching any of your Embedded Content data types, document types or content nodes where it is used!) and install version 1.1 of Embedded Content. After installation is complete you will be asked to upgrade the schema of your existing Embedded Content data types to the new version. The only thing to be aware of here is that you won’t be able to downgrade again, so please make sure you have a database backup at hand for this option.

 

I hope you enjoy using the Embedded Content data type and like the improvements as much as I do! Smile

Tags:
Categories:

Creating code-behind files for Umbraco templates

by SaschaWolter 28. January 2011 12:04

I’ve always had this idea in my head that one of the downfalls of using Umbraco when coming form standard ASP.Net web application was the missing code-behind files. You know, when you create a new web application and add an .aspx page to it it conveniently comes with a .cs and design.cs file. Most of the time I would even let the code-behind file inherit from my own custom Page/MasterPage implementation, e.g. a SecuredPage that comes with various properties and methods to handle authentication. Although Umbraco uses regular masterpages (if you haven’t turned it off in the web.config) all you get in the backoffice is the actual page template. Now, don’t get me wrong: I love the way Umbraco let’s you edit all aspects of your site via the backend and gives you the utmost flexibility and 100% control over the output, presented in a refreshingly simple manner. Yet sometimes you need a bit more, and it’s just another clear plus for Umbraco that you are able do the following without ever having to modify the core.

The 'aha' moment that it is actually quite easy to add code-behind files to Umbraco masterpages came to me when I had to port a quite big ASP.Net website to Umbraco. The website had grown organically over the years with lots of custom templates, user controls, etc. The site also had multi-language support, all of which was handled in the code-behind files of the pages. The goal was to get it over to Umbraco as quick as possible, then rework the functionality bit by bit. So I started by creating a new Umbraco site and ‘wrapped’ it in a web application project in Visual Studio.

 

1-28-2011 5-00-55 PM

[Please refer to the comments below to find more information on how to set this up in Visual Studio.]

After adding a couple of document types and templates in Umbraco the masterpages folder looks something like this:

1-28-2011 5-28-34 PM

The Root.master file is the main master page, Page1.master and Page2.master are nested master pages in Umbraco. I’ve included all three of them in the solution. Now it’s time to create the code-behind file: right-click on the masterpages folder and add three C# classes and name them Root.master.cs, Page1.master.cs and Page2.master.cs. The result should be something like this:

1-28-2011 5-29-38 PM

Visual Studio automatically groups them together, fantastic. Yet they are not really hooked up yet, VS does the grouping just based on file names. The master directive on Root.master currently looks like this:

<%@ Master Language="C#" MasterPageFile="~/umbraco/masterpages/default.master" AutoEventWireup="true" %>

To hook up the cs file we need to add the CodeBehind and Inherits attributes like so:

<%@ Master Language="C#" MasterPageFile="~/umbraco/masterpages/default.master" AutoEventWireup="true" CodeBehind="Root.master.cs" Inherits="Umbraco_4._6._1.masterpages.Root"%>

You should get an error at this point as the compiler complains that Root is not convertible to System.Web.UI.MasterPage, so we need to fix this in the cs file as well by making the class partial (necessary if you want to later add designer files as well) and inheriting from System.Web.UI.MasterPage. An empty Page_Load message can’t hurt as well:

using System; namespace Umbraco4_6_1.masterpages { public partial class Root : System.Web.UI.MasterPage { protected void Page_Load(object sender, EventArgs e) { } } }

You should now be able to switch between both files by pressing F7 in Visual Studio. Let’s try to add a Property and reference that from the template:

public string Message { get; set; } protected void Page_Load(object sender, EventArgs e) { Message = "All the best from your code-behind file!! :)"; }

and something like this on the template:

<div> <%= Message %> </div>

Now we just need to compile the project and navigate to a content page that uses the Root template to see the message.

 

Adding designer files

[As Simon Dingley pointed out below there is an even easier way to create the designer files: right-click on the master.aspx page and select "Convert to web application", which will create the .designer file for the selected item.]

We can also add a designer file to the duo to make things even better. After adding Root.master.designer.cs, Page1.master.designer.cs and Page2.master.designer.cs the solution looks like this:

1-28-2011 5-49-22 PM

Visual Studio is now rightfully complaining that it got duplicate definitions for the classes and even suggests to add the partial keyword, which we will quickly do. After that is all working and compiling nicely we need to give Visual Studio control over the designer files. That is easily accomplished by slightly modifying each .master file (e.g. by adding a single space to an empty line) and saving it, VS will do the rest for you. The most important thing this will do for you is to reference all controls you add to the template so they are available for use in the code-behind file.

Now let’s try to modify the message value from the code-behind of Page1 by adding

protected void Page_Load(object sender, EventArgs e) { ((Root) Master).Message = "Hello from the nested master page!"; }

to it. Browsing to any Umbraco page that uses the Page1 template will now show the new message.

Categories: .Net | Umbraco

Presenting a new Umbraco data type: Embedded Content

by SaschaWolter 20. January 2011 14:51

 

Are you looking for a way to create content on a node that uses the build-in Umbraco data types, yet let’s the content editor decide how many fields he actually needs? Do you want your content editors to be able to order the fields as they see fit? Are you tired of having to create ‘data’ sub nodes just so you have the data in Xml format for easy transformation? Or are you just looking for a version of the Repeatable Custom Content that works with Umbraco 4.5+?

 

Then it is time to open the curtain for another Umbraco data type grown here at the FARM called Embedded Content (version 1). In short it allows you to add content to a node with pretty much the same outcome as if you were using data sub nodes. For example see this implementation of specifications for a product:

- Product

  - Product specifications

    - Package measurements (value: 200cm x 15cm x 150cm)

    - Package weight (value: 5.3 kg)

    - Available colors (value: yellow, red, blue)

Pretty much the same can be achieved with the Embedded Content data type by creating a new instance of it, adding 2 properties ‘name’ and ‘value’ to it and adding it to the product node. You will then be able to add as many ‘name-value-pairs’ as you like to the control (as you are able to create as many sub nodes as you want) and sort them to your liking (again same as with the sub nodes). Yet it is all embedded in the product node and it gets all saved as Xml in the backend. You can use a range of basic Umbraco data types for the Embedded Content properties, at the moment these are

  • Textstring
  • Textbox multiple
  • True/false
  • Content picker
  • Media picker
  • Simple editor
  • Date picker

After installing the package you will first have to create a new data type with a name of your choice, and then set it to use to 'Embedded Content'. After saving you will be able to add custom properties to the datatype, you can also edit, delete or re-order them. In the following example I have created a new Embedded Content data type with 5 properties:

EmbeddedContent-DatatypeList

Image 1: An Embedded Content data type instance with 5 properties.

 

EmbeddedContent-DatatypeCustomization

Image 1: Add a new property to the control.

 

Here is a quick overview of the individual options:

Name the name of the property, just for the editor
Alias this is the name of the Xml node when data for this schema gets saved (see below for an example)
Type the type of this property
Description a short description for the purposes of the editor
Show in title? if ticked then this property will be displayed in the content list which the content editor sees

 

EmbeddedContent-DatatypeReorder

Image 3: Re-order the properties

 

Now it is time to use the Embedded Content data type on a document type, create a new node and add some content to the control:

EmbeddedContent-ContentAdd

Image 4: Add a new entry to the list

 

EmbeddedContent-ContentReorder

Image 5: Reorder the content list

 

Here is the Xml data which gets saved to the database:

<productSpecification>
  <data>
    <item id="1">
      <name propertyid="1">Package measurements</name>
      <value propertyid="2">200cm x 15cm x 150cm</value>
      <mediaItem propertyid="3" />
      <contentItem propertyid="4" />
      <validFrom propertyid="5" />
    </item>
    <item id="2">
      <name propertyid="1">Packaged weight</name>
      <value propertyid="2">5.3</value>
      <mediaItem propertyid="3" />
      <contentItem propertyid="4" />
      <validFrom propertyid="5" />
    </item>
    <item id="3">
      <name propertyid="1">Available colors</name>
      <value propertyid="2">yellow, green, blue</value>
      <mediaItem propertyid="3">1062</mediaItem>
      <contentItem propertyid="4">1065</contentItem>
      <validFrom propertyid="5">2011-01-14 00:00</validFrom>
    </item>
  </data>
</productSpecification>

 

You can now easily transform this e.g. with XSL:

EmbeddedContent-SampleXslt

Image 6: A simple xsl:for-each statement to loop through the properties

 

The output on a sample page would then be something like this:

EmbeddedContent-ContentOutput

Image 7: sample output

 

In conclusion this is a really flexible and and highly customizable data type which allows you to quickly add a complex type (so to speak) to a content node, giving the content editor as much flexibility as possible concerning the number of items and ordering. As such I am sure it will come in handy for a broad range of tasks and I am really pleased that we can make this data type available for everyone working with Umbraco. Enjoy!

 

Last but not least a couple of things to note:

  • Please stay clear of ‘;’ in the description when defining properties, it will mess up the property definition string (there is also a warning on the control)
  • Although it is possible to change the properties of an Embedded Content type when it is already in use it should be handled with the utmost care. Changing the order of properties will be absolutely fine, changing the control type of the individual properties will pretty much work like it works with the fundamental Umbraco data types. Everything else is a bit risky to say the least…
Tags:
Categories: .Net | Umbraco