Sydney Umbraco Meet-Up - Post CodeGarden Recap

by ElijahGlover 5. July 2011 06:01

Peter Gregory is back once again in Sydney for level 1 and 2 certifications, we thought it would a great time to host a meet-up and fill-in those who couldn’t attend CodeGarden.

Agenda

  • Shannon Deminick from the Umbraco HQ on V5
    Shanon will demo v5 and talk about the progress being made on v5
  • Aaron Powell from Readify on v5 hive and data
    Aaron will give a intro to working with data through Hive
  • Peter Gregory from the Umbraco HQ on v4 future
    Is it the end? - Find out about future plans for v4
  • Peter Gregory from the Umbraco HQ on Deli
    Find out how to commercialise your packages for Umbraco
  • Shannon Deminick from the Umbraco HQ on v5 packages
    Shannon will give an intro to building packages for V5 and a Jump start

When and where

Wednesday 20th July, 6pm – onwards.
TheFARM Digital, Suite 101, 4 – 14 Buckingham St Surry Hills
Please register your interest on (http://our.umbraco.org/events/sydney-umbraco-meet-up) so we can ensure that we have plenty of beer to go around.

Who is welcome?

Everyone!

  • If you’re taking the Level 1 and/ or Level 2 that week then come on down.
  • If you’re currently using Umbraco then come on down. 
  • If you’re just plain interested in what the hell this Umbraco thing is then come on down!


See you there!

Tags:
Categories: Umbraco

Searching Umbraco using Razor and Examine

by Shannon Deminick 15. March 2011 05:51

Since Razor is really just c# it’s super simple to run a search in Umbraco using Razor and Examine.  In MVC the actual searching should be left up to the controller to give the search results to your view, but in Umbraco 4.6 + , Razor is used as macros which actually ‘do stuff’. Here’s how incredibly simple it is to do a search:

@using Examine; @* Get the search term from query string *@ @{var searchTerm = Request.QueryString["search"];} <ul class="search-results"> @foreach (var result in ExamineManager.Instance.Search(searchTerm, true)) { <li> <span>@result.Score</span> <a href="@umbraco.library.NiceUrl(result.Id)"> @result.Fields["nodeName"] </a> </li> } </ul>

That’s it! Pretty darn easy.

And for all you sceptics who think there’s too much configuration involved to setup Examine, configuring Examine requires 3 lines of code. Yes its true, 3 lines, that’s it. Here’s the bare minimum setup:

1. Create an indexer under the ExamineIndexProviders section:

<add name="MyIndexer" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine"/>

2. Create a searcher under the ExamineSearchProviders section:

<add name="MySearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine"/>

3. Create an index set under the ExamineLuceneIndexSets config section:

<IndexSet SetName="MyIndexSet" IndexPath="~/App_Data/TEMP/MyIndex" />

This will index all of your data in Umbraco and allow you to search against all of it. If you want to search on specific subsets, you can use the FluentAPI to search and of course if you want to modify your index, there’s much more you can do with the config if you like.

With Examine the sky is the limit, you can have an incredibly simple index and search mechanism up to an incredibly complex index with event handlers, etc… and a very complex search with fuzzy logic, proximity searches, etc…  And no matter what flavour you choose it is guaranteed to be VERY fast and doesn’t matter how much data you’re searching against.

I also STRONGLY advise you to use the latest release on CodePlex: http://examine.codeplex.com/releases/view/50781 . There will also be version 1.1 coming out very soon.

Enjoy!

Categories: Umbraco | Examine | .Net

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:

Adobe releases preview of “Wallaby”: Flash FLA conversion to HTML5

by David Langridge 9. March 2011 04:47

Adobe has just released a preview build of their tool (Codename “Wallaby”) for converting a Flash FLA to HTML5.

Skimming the release notes briefly reveals that the tool is really only useful for converting a timeline animation with simple button interactions.
The tool seems to rely heavily on SVG(Scalable Vector Graphics) and CSS3 to achieve its limited functionality. Actionscript of any kind is unsupported.

It seems that there are a few issues with cross browser support for some of the supported features but it’s definitely an interesting product to keep your eye on.

Check the Adobe Labs page to get the preview and more information.

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:

Consume Json REST service with WCF and dynamic object response

by Shannon Deminick 11. February 2011 06:26

This was my first shot at WCF and though I saw how nice it could be, i failed miserably… well, I’m actually not too sure. I tried all sorts of things but no matter what couldn’t get WCF to behave and return the actual response you would get if you just consumed the service with the WebClient object. Here’s what I tried and assumed that this ‘should’ work but the result was always an empty dictionary:

Note: this demo is based off of the @Task project management tool’s REST API.

Define the contract:

[ServiceContract] public interface IAtTaskService { [OperationContract] [WebGet( UriTemplate = "/api/login?username={username}&password={password}", RequestFormat = WebMessageFormat.Json)] IDictionary<string, object> Login(string username, string password); }

Run the code:

public IDictionary<string, object> DoThis(string username, string pword) { using (var cf = new WebChannelFactory<IAtTaskService>( new Uri("https://mycompaniesurl.attask-ondemand.com/attask/"))) { var s = cf.CreateChannel(); var token = s.Login(username, pword); return token; } }

The above seemed really nice to be able to consume services but the result was always empty. I tried using strongly typed objects in the result, made sure it wasn’t an HTTPS issue, used the normal WCF configuration approach, etc… but couldn’t get it to work.

The ‘Fix’

I quite like the way that WCF has UriTemplates and you can just attribute up an interface and then make strongly typed calls to access your services so i decided I’d just make that work with my own implementation. Again, perhaps I was ‘doing it wrong’ or whatever, but the below implementation is pretty cool and also lets you get JSON results as a dynamic object :)

Define the contract:

This is pretty much the same as above, but we have a dynamic response

[ServiceContract] public interface IAtTaskService { [OperationContract] [WebGet( UriTemplate = "/api/login?username={username}&password={password}", RequestFormat = WebMessageFormat.Json)] dynamic Login(string username, string password); }

The JsonRestService base class

I created a class that lets you specify you contract service as a generic argument and then provides you with a method called “Send” which is defined a:

protected dynamic Send(Func<T, dynamic> func)

This class will manage all of the http requests and use the WCF attributes applied to your contract to generate the correct URLs and parameters (source code at the bottom of this article)

Define a standard service

So to consume the REST services, we just create a ‘real’ service class such as:

public class AtTaskService : JsonRestService<IAtTaskService>, IAtTaskService { public AtTaskService(string serviceUrl) : base(serviceUrl) { } public dynamic Login(string username, string password) { return Send(x => x.Login(username, password)); } }

As you can see, the “Login” method just calls the underlying “Send” method which uses a strongly typed delegate. The Send method then inspects the delegate and generates the correct URL with parameters based on the WCF attributes.

Using the service

So now, to use the new service we can do something like:

[TestMethod] public void AtAtask_Login() { //Arrange var svc = new AtTaskService("https://mycompanyname.attask-ondemand.com/attask/"); //Act var token = svc.Login("MyUserName", "mypassword"); //Assert Assert.IsTrue(token != null); Assert.IsTrue(token.data != null); Assert.IsTrue(token.data.userID != null); }

Too easy!

As I mentioned earlier, I would have assumed that WCF should handle this out of the box, but for the life of my I couldn’t get it to return any results. Whether it was a request issue or a parsing issue, or whatever i have no idea. In the meantime, here’s the source code for the JsonRestService class which will allow you to do the above. The source requires references to Json.Net and Aaron-powell.dynamics

JsonRestService source

Disclaimer: I made this today in a couple of hours, I’m sure there’s some code in here that could be refactored to be nicer

public class JsonRestService<T> { public string ServiceUrl { get; private set; } public JsonRestService(string serviceUrl) { ServiceUrl = serviceUrl; } /// <summary> /// Queries the WCF attributes of the method being called, builds the REST URL and sends the http request /// based on the WCF attribute parameters. When the JSON response is returned, it is changed to a dynamic object. /// </summary> /// <param name="func"></param> /// <returns></returns> protected dynamic Send(Func<T, dynamic> func) { //find the method on the main type that is being called... i'm sure there's a better way to do this, //but this does work. //This will not work if there are methods with overloads. var methodNameMatch = Regex.Match(func.Method.Name, "<(.*?)>"); if (!methodNameMatch.Success && methodNameMatch.Groups.Count == 2) { throw new MissingMethodException("Could not find method " + func.Method.Name); } var realMethodName = methodNameMatch.Groups[1].Value; var m = typeof(T).GetMethods().Where(x => x.Name == realMethodName).SingleOrDefault(); if (m == null) { throw new MissingMethodException("Could not find method" + realMethodName + " on type " + typeof(T).FullName); } //now that we have the method, find the wcf attributes var a = m.GetCustomAttributes(false); var webGet = a.OfType<WebGetAttribute>().SingleOrDefault(); var webInvoke = a.OfType<WebInvokeAttribute>().SingleOrDefault(); var httpMethod = webGet != null ? "GET" : webInvoke != null ? webInvoke.Method : string.Empty; if (string.IsNullOrEmpty(httpMethod)) { throw new ArgumentNullException("The WebGet or WebInvoke attribute is missing from the method " + realMethodName); } //now that we have the WCF attributes, build the REST url based on the url template and the //method being called with it's parameters var urlTemplate = webGet != null ? webGet.UriTemplate : webInvoke.UriTemplate; var urlWithParams = GetUrlWithParams(urlTemplate, func); var url = ServiceUrl + urlWithParams; //Do the web requests string output; if (httpMethod == "GET") { output = HttpGet(url); } else { //need to move the query string params to the http parameters var parts = url.Split('?'); output = HttpInvoke(parts[0], httpMethod, parts.Length > 1 ? parts[1] : string.Empty); } //change the response to json and then dynamic var stringReader = new StringReader(output); var jReader = new JsonTextReader(stringReader); var jsonSerializer = new JsonSerializer(); var json = jsonSerializer.Deserialize<Dictionary<string, object>>(jReader); return json.AsDynamic(); } /// <summary> /// Updates the url template with the correct parameters /// </summary> /// <param name="template"></param> /// <param name="expression"></param> /// <returns></returns> private static string GetUrlWithParams(string template, Func<T, dynamic> expression) { //parse the template, get the matches foreach (var m in Regex.Matches(template, @"\{(.*?)\}").Cast<Match>()) { if (m.Groups.Count == 2) { var m1 = m; //find the fields based on the expression(Func<T>), get their values and replace the tokens in the url template var field = expression.Target.GetType().GetFields().Where(x => x.Name == m1.Groups[1].Value).Single(); template = template.Replace(m.Groups[0].Value, field.GetValue(expression.Target).ToString()); } } return template; } /// <summary> /// Do an Http GET /// </summary> /// <param name="uri"></param> /// <returns></returns> private static string HttpGet(string uri) { var webClient = new WebClient(); var data = webClient.DownloadString(uri); return data; } /// <summary> /// Do an Http POST/PUT/etc... /// </summary> /// <param name="uri"></param> /// <param name="method"></param> /// <param name="parameters"></param> /// <returns></returns> private static string HttpInvoke(string uri, string method, string parameters) { var webClient = new WebClient(); var data = webClient.UploadString(uri, method, parameters); return data; } }
Tags: , ,
Categories: .Net

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

uSnapshot… coming soon!

by Aaron Powell 21. January 2011 11:08

A while ago Shannon and I blogged about a project we were working on called Snapshot which was essentially a way to export flat ASP.Net websites from an Umbraco install.

Since then, TheFARM has launched a few websites using development versions of Snapshot and we’ve been working towards getting a version of Snapshot ready for which anyone could purchase and use.
There have been some hurdles along the way such as legality around ownership, how to release it as a commercial product and my moving on from TheFARM. But finally … this has culminated in something exciting…

uSnapshot is coming!

That’s right sports fans, we’ve renamed Snapshot to uSnapshot and we’re going to be working on finishing v1.

But we realised that we don’t know how everyone wants to use uSnapshot, so we’re throwing open the doors. Today we’ve launched the uSnapshot Beta Program!

We’re looking for people who are interested in helping us beta test uSnapshot as we work towards a v1 release, help us find bugs and ultimately work on a final feature set for the release.

So if you think that uSnapshot may be something that you (or your company) may be interested in please sign up.

Have a look at the uSnapshot site for full details and benefits regarding the beta program.

Categories: Umbraco | uSnapshot

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