Umbraco @ MIX10 Wrap Up

Thursday, March 18, 2010 by Paul Sterling

As the umbraco team heads home we consider what MIX means for umbraco - and its all good.  MIX is a fantastically exciting event for web developers and especially for those of us who have based our solutions on the Microsoft stack.  A great collection of smart and talented web professionals attend MIX and we were thrilled to be part of it.  Many MIX attendees also head home in possession of a shiny new umbraco logo sticker - these were found in a variety of surprising locations throughout the MIX venue.  Look for them to appear on the laptop lids of umbraco users soon, sort of the new hotness for the cool umbraco kids - at least that's what we told folks at MIX!

umbraco-stickers

The Team

I, Paul Sterling, had the pleasure of attending MIX in the company of Per Ploug Hansen from Umbraco, Alex Nordcliffe from Xeed, Peter Miller from Condé Nast Digital, and Benjamin Howarth from Code Gecko.  Our days were packed full of meetings with current and potential partners and very interesting sessions covering a broad range of topics from Silverlight to Windows Phone 7 Series to MVC v2.0 and more.  We had scant time for a break, but we did manage to see the sun once or twice all the same.

4438744536_f37ca7fc22[1]

Day 1

Umbraco's success in the Microsoft Web App Gallery was prominently featured in the Day 1 keynote.  Umbraco has been downloaded more than 100,000 times from the Web App Gallery and the total number of downloads is more than 10 million - all of this in the last 12 months.

75522692[1]

Day 2

The Day 2 Keynote was not without its umbraco tie-in as well.  Microsoft launched its oData protocol and related technologies all presented on the odata.org site - which is powered by umbraco and built by the talented folks at Vizioz.

Its no secret that more than a couple of current and future Microsoft sites are built using umbraco.  To further the great relationship umbraco and Microsoft share we are developing a deeper partnership in 2010.  Much of the results from this partnership will not be seen in the immediate future but rest assured we are working hard together to ensure the growth and stability of the umbraco installed base.  If you've been waiting for the time when Microsoft recognized the unique and valuable combination of umbraco's technology and community - that time is now.

The Dinner

On Tuesday evening umbraco hosted a dinner for 35 MIX attendees.  The response was overwhelming and we were forced to use a highly complex and proprietary algorithm to select the lucky dinner invitees. 

75838835[1]

In addition to a host of interesting and hungry people, a number of virtual celebrities joined us and participated in the lively discussion.  Among the attendees were Scott Hanselman, Sara Chipps, Pete Brown, Chris Woodruff, Jon Galloway, and Jim Minatel

The End

Talking with current umbraco users and partners is a huge rush but meeting people curious about umbraco is even more exciting.  Of all the people we spoke with at MIX we were most impressed with the open-mindedness and willingness to consider an approach like umbraco - one that is open-source, friendly, and maybe a little bit of an underdog.

Get certified in the Benelux

Wednesday, March 17, 2010 by Tim Geyssens

We've just opened registration for the first round of official Umbraco courses (both level 1 and level 2) held in Antwerp, Belgium.

Level 1 is running on 3rd & 4th May 2010
Level 2 is running on 5th & 6th May 2010

Both courses will be be taught by umbraco HQ team member Tim Geyssens who brings more then 3 years Umbraco experience to the dojo.

These are the same courses taught throughout Europe and North America, the training will give you everything you need to know to attain your Umbraco Certification at either level 1 or level 2.

Secure your seat here.

CodeGarden 10 is coming

Wednesday, February 24, 2010 by Niels Hartvig

3650589586_d8bc0718f9_o

Our annual Umbraco Conference - CodeGarden - is here again. On June 24-25th 2010 web developers, designers, editors and other Umbracians from all over the world will gather in Copenhagen for the sixth time. We opened registration last week and we're already past 70 attendees which means it took less than 48 hours to outnumber the number of attendees from 2005-2007!

CodeGarden is a phenomenal conference and THE conference to attend if you work with Umbraco or consider doing it. We've managed to keep the early bird price at EUR300 and that's a *steal* for three full days of talks from all the numero uno Umbraco experts and the fee is even including swag, awesome organic food and loads of surprises along the way.

ASP.NET MVC Pre conference

As we revealed last year, we're transitioning to Microsoft ASP.NET MVC for the next version of Umbraco - Umbraco 5 - which we're aiming to release Q1 2011. At last years CodeGarden, I also promised that we'd help to make this a smooth transition for everyone. And action speaks louder than words, so I'm proud that we're not only thinking about how the software works but also in how to raise the level of competence for people in the Umbraco community by arranging an MVC pre-conference day on the 23rd.

We've somehow managed to convince MVC experts Simone Chiaretta and Jon Galloway to come and do MVC bootcamps on the day before CodeGarden starts (June 23rd). It's free for all attendees and it's an absolutely stunning chance to get up to speed with the next generation of ASP.NET and the foundation of Umbraco 5.

Simone Chiaretta is an ASP.NET MVP and ASPInsider as well as the author of the Beginning ASP.NET MVC from Wrox. Jon Galloway is working at Microsoft and is the author of the coming Professional ASP.NET MVC 2.0.

Ensure your ticket today!

All the previous CodeGardens have sold out and the ticket sale this year has obviously blown us away. Make sure to register today - either before the price goes up or before CodeGarden10 is sold out.

Umbraco 5th Birthday in London - Presentations

Monday, February 22, 2010 by Warren Buckley

Hello all,
It's Warren (The CWS guy) here I haven't blogged for Umbraco Corp for quite a while now, but its good to do a guest post again.

Last week Adam Shallcross from The Cogworks and myself from Xeed hosted the 5th Birthday party on 16th February 2010 in London and I'm glad to say it was a huge success, with around 75-80 people turning up to watch a jam packed day full of talks, birthday cake and mingling.

umbraco-5-london-attendees
Some attendees at the 5th Birthday
Photo: Douglas Robar

Adam and me organised the day to be a fun day as possible, with each attendee getting a birthday goodie bag that included:

  • Umbraco pen
  • Umbraco & Our.Umbraco button badges
  • Umbraco paper pad for all those important notes
  • Drink Voucher
  • Party popper
  • Party hat

umbraco-badges
Umbraco button badges that attendees received
Photo: Warren Buckley

 

The day's schedule was as follows:

  • Per from Umbraco - The history of Umbraco & what is to come in the future
  • William Coleman & Mark Quirk from Microsoft UK - Upcoming tech (.NET4, Azure, Silverlight)
  • Chris Houston from Vizioz.com - CMS Mailer
  • Paul Marden from Orcare.com - Google Checkout
  • Adam Shallcross & Tim Saunders from The CogWorks - Integrating systems not just CMS
  • Benjamin Howarth - Medium Trust
  • Neil Tootell & Julien Decaudin from SAS Design - SAS Design 2009 Projects
  • Alex Norcliffe & Peter Miller from CondeNast - Cloud computing & scalability
  • SWAG Raffle

Presentations

Chris Houston from Vizioz.com - CMS Mailer
http://www.slideshare.net/warrenbuckley/cms-mailer-for-umbraco

Paul Marden from orcare.com - Google Checkout
http://www.slideshare.net/warrenbuckley/google-checkout-for-umbraco

Benjamin Howarth from Code Gecko Developments - Medium Trust for Umbraco
http://www.slideshare.net/warrenbuckley/umbraco-medium-trust

Neil Tootell & Julien Decaudin from sasdesign.co.uk - 2009 Projects
http://www.slideshare.net/warrenbuckley/sas-design

Alex Norcliffe & Peter Miller from CondeNast Digital - Cloud computing & scalability
http://www.slideshare.net/warrenbuckley/pm-an-umbraco5th-presentation-pete

Videos

Paul Marden from Orcare has done a great job of recording these videos and putting them up onto Vimeo.com
http://vimeo.com/channels/88314

Want to see photos of the event?

As always our budding "umbraco" photographer Douglas Robar of Percipient Studios has put his photos online at Flickr - http://www.flickr.com/photos/percipientstudios/sets/72157623392288216/

Want to watch a room full of developers sing Happy Birthday to Umbraco?

 

Would like to say thanks again to The Cogworks and Xeed to help fund the event and also thanks to Microsoft UK for giving us some nice SWAG to give away.

 

Warren :)

We’re opening a North American office

Thursday, February 18, 2010 by Niels Hartvig

We got a lot of users in North America - in fact it's the number one visiting country on this website - but we've never had a good (official) way to support them. So to find a way, we went on a company retreat and had some unexpected help:

More (serious) details coming next week.

Time to vote for the 2010 Umbraco MVPs

Friday, February 05, 2010 by Niels Hartvig

Umbraco got the worlds most friendly community. Period. With more than 5.000 individuals helping each other every month it can be hard to pinpoint who's doing more than others, but there are Umbracians who're putting an almost unbelievable effort in answering questions on the forum, producing killer packages and sharing knowledge in the wiki and blog posts.

To show how much we appreciate their work, we made the Umbraco MVP - Most Valued People (*not* professionals) program in 2007. If you take a look at the ten different people who've previously received the MVP award, I'm sure you'll find out that they helped you when you started with Umbraco and that your Umbraco sites are using their packages.

Previously it was Per and I who decided who got to be MVPs, but last year we decided to change that. Let the people who've received help be the ones who choose the MVPs. So we invented the Karma system on Our and we've used that to make a shortlist of the twenty candidates for the 2010 MVP award:

Cast your vote before March 1st 2010

To narrow this down to five MVPs, please take your time to vote for your favorite candidate. For more details, please check the voting page on Our Umbraco.

Congratulations to all twenty people who made this list and let the best five win!

Bringing the best from our to the package repo

Thursday, January 07, 2010 by Tim Geyssens

Today we've done another update of the umbraco package repo (that's available from the packages tree in the developer section of umbraco). Again we've added some of the best rated/most downloaded projects created by our amazing community.

FamFamFam Icons by Shannon Deminick

Extends the document type icon dropdown with a massive number of icons.

633909961208530000_famfamfamUmbacoicons

More details on this project on our.umbraco.org.

Log Manager by Immo Wache

Adds a new tree to the developer section that can be used to manage the umbraco log.

633960929716338364_view_logs

More details on this project on our.umbraco.org.

Char Limit

A  datatype that allows you to set a limit on the number of characters that can be entered in a textarea.

633881969257021608_charlimit1

More details on this project on our.umbraco.org.

 

Remember to keep voting on your favorite packages and spread some karma on our.umbraco.org!

Blog 4 Umbraco 2.0.24 - Release

Thursday, December 24, 2009 by Per Ploug Hansen

It's only 24 days since we coined the idea of improving the Blog 4 Umbraco package as a christmas calendar. Today we're releasing what we've accomplished so far - and it's quite a lot so in case you've missed anything here's a summary:

In addition to the work done by Per Ploug Hansen, Tim Geyssens and yours truly, several community members have contributed with code, testing and skins. Morten Bock, Warren Buckley and Thomas Höhler have contributed with xslt improvements and Ian Houghton, Warren Buckley, Jason Prothero and Alan Ballard have contributed with skins with many more community members working on more. Awesome.

You can install the final version of Blog 4 Umbraco version 2.0 with just one click from the package repository or download the package from Our Umbraco. You can download the documentation from Our Umbraco and you can download the full source of the project from CodePlex. You can also download the nightly updates from our build server.

Merry Christmas!

Blog 4 Umbraco 2.0.23 – Create new posts from the dashboard

Wednesday, December 23, 2009 by Niels Hartvig

In this second last chapter of this wonderful journey aka the Christmas Calendar 2009 it's the final touch - what it's all about: Create new blog posts. Easier.

While Umbraco's UI makes it a breeze to manage and edit content it's still a multi step process to create a blog post. And while Blog 4 Umbraco automatically generates a content channel so you can edit with Microsoft Word, Live Writer or any other 3rd party that supports MetaBlogAPIs that might not be an option either. All we want is to login to Umbraco, write a post and click Publish. And that while still having full support for any dynamic changes to our document type.

The Dashboard and the DataType APIs to the rescue - and a lot of hacks

Once again the solution is the easy to config and extend dashboard in Umbraco. We'll simply place a "Create Blog post" control on the dashboard and make the control visible when you login. Like this:

Picture 30

Notice how the edit controls looks exactly as when we edit the blog post normally. This is because we're reusing the settings on the document types and uses the DataType APIs to fetch all the metadata on the properties. This means that if you add additional properties to the blog post document type or if you change the existing ones, they'll automatically be updated. It's very simple and the exact same technique used by AutoForm or Doc2Form (and the standard edit content page, btw). And it's really simple - if it weren't because the Rich Text Editor and the Tagging datatypes are the two most advanced and both have horrible design decisions - I couldn't get the toolbar icons from the Rich text editor appearing and I got weird exceptions in the tagging datatype.

Luckily Umbraco is open source are we can actually find the reason why all this is happening. The Rich Text Editor couldn't understand where it was, it was neither on a standard edit page (such as edit content, member or media) and it wasn't in live editing either. So it couldn't find anywhere to place the toolbar icons. Luckily it's fully configurable and we're able to tell it by accessing the Config collection in the tinymce class. Problem solved. Only thing that needs polish is the 140px left padding, but that's a job for a jQuery hack later :-)

It was a bit harder for the tagging datatype. You see, to find out which tags is already selected for the item you're editing it uses a weird technique of either calling the request collection for an id (when editing on a standard edit page) or using the node factory when editing live. This is probably legacy as data types have an easy way of getting the current id of the item edited, but that doesn't help us when it's already done wrong. Luckily we can use reflection to modify the request collection (now that's a hack!) to add the id and voila, the tagging control worked too.

All in all it was a little harder than it ought to and once again this process reveals areas where Umbraco can easily be made better. But at the same time, I was very satisfied with the end result and think it's a very handy technique for improving the editor experience in an Umbraco implementation. This technique could easily be used to news editors or other types of create tasks where users often create the same types of documents. This really speeds up the workflow.

Blog 4 Umbraco 2.0.22 – The Installer

Tuesday, December 22, 2009 by Per Ploug Hansen

We want to give people the best start possible, using the blog package. So after setting up everything in Installer actions for easy install/uninstall, we decided also to add a usercontrol based Installer.

This is purely for giving people the first configuration options - setting the blog's name and description, which is then published so content channels and everything is setup automatly at the same time.

 

So besides the standard install experience, the user also gets the additional setup options.

image

After filling the fields, the blog is setup, the channels are created, and the user is redirected to the blog where a welcome post with documentation and community information awaits:

image

Finally the blog channel is setup automaticly (if the user doesn't have a channe setup already) to make it easy to connect a blogging client to the blog.

Which is ofcourse detailed in the usage guide on how to do.

Blog 4 Umbraco 2.0.21 - Documentation

Monday, December 21, 2009 by Per Ploug Hansen

The goal of the Christmas calendar has since the beginning been a better blog package for umbraco. And so far we've had our eyes on features only. Yes we've done some polishing and finishing here and there, but it has been all about getting the feature-set up to date.

But we would like to take it a bit further and spend the last couple of days before the Christmas holidays to finish the project off in a proper way. We would like the result to be a fully done package. Not just the features, but also with good and clear documentation on how to configure this package, and how developers can skin or extend on it, as well as a good install experience that help the user getting started using the package. image

So today is all about beginning work on the documentation, and adding it to the project.

For skinners and developers

We felt the first documentation should be for skinners and developers. As we've already called out for skins for the blog package. So today we've added a sample skin file to the project, complete with Manifest, Css file, images and thumbnails. Ready to upload to packages.umbraco.org

Also, in the project, static html files have been added for reference, so you don't have to have a website with blog4umbraco on running. Just power up textmate and style away.

Finally the draft of the skinning guide has bee added. Sofar about 10 pages on the template structure, html element placements and contentplaceholders in the masterpages. And more will follow.

For end-users

Also a Usage and Configuration guide is underway. It will cover everything the blog editor need to know to get started with a umbraco powered blog. From installing the package to configuring the features and setting the visual appearance.

So far chapters on configuring pings and Akismet have been added, and more will follow.

Blog 4 umbraco 2.0.18 – A new design in 20 seconds

Friday, December 18, 2009 by Niels Hartvig

The SkinBrowser is finally alive and working. You can try it using the latest build found here. If you rather want to wait for the final version of blog4umbraco that comes in a few days then here's a little movie to show the functionality. As always - remember to crank up the volume:

You need to have Flash and javascript enabled to use this video tutorial

Hopefully we'll see a bunch of new skins (and get rid of some of the ugly ones in there) over the next couple of days now that the markup is in place. Remember to submit your skins!

Blog 4 umbraco 2.0.17 – Picking the right theme for the skinners

Thursday, December 17, 2009 by Per Ploug Hansen

It's never easy to lock down a feature, getting the final touches juuust right and then move on. When working with a feature that will be let loose into a community and get a life of it's own it's even harder. Then it's unchangeable and locked down forever, in the sense that if you change it later on, it will affect alot of people.

That is the situation with the Blog 4 Umbraco Html structure and the skinners that hopefully will use this. We needed to get it right before shipping it, too many people will depend on it. So we tried out some different options to figure out which ones was most flexible, viable and not too heavy to work with.

So we worked through:

  1. The Kubrick theme, easy to work with, included by default on wordpress accounts and known by many. The html is clean but not that flexible incase you wanted something else then a 2 column simple blog.
  2. The K2 theme, tons of features, tons of html, after working with the html, deemed too heavy to set up without cutting off too much of the included functionality
  3. K2 Lite, much better, cleaner html, simple to work with

So we had actually settled on the k2 lite theme to be included on the blog. But then, deep inside the wordpress skinning world, we encountered the Sandbox theme. Now as you can see, sandbox is very very basic, even more basic then Runway - our simple website starterkit, but that is the great thing about it, and also why it seems wordpress is about to include it by default

And there was already ported a css version of k2 for it, perfect! It looks clean, the html is built with css skinning in mind, and everything is pretty clean - wonderfull.

So after the many considerations on how to pick a theme that skinners will be able to use, we ended up using an established standard which already has a community around it. That is indeed truly wonderfull, and really in the spirit of umbraco. Don't try to reinvent the wheel, pick somehting works already if it solves your problem.

So for anyone who wants to build a skin for the blog package, this is a preview of the finished html. It includes a html page with the markup and a sample css file. So to start skinning, simply exchange the css file reference with your own stylesheet.

Download the theme html

We will post the details on how to get the skin into repository, later today.

UPDATE: The blog is now on nightly.umbraco.org as an installable package:

http://nightly.umbraco.org/Blog4Umbraco/2.0.17/Blog4Umbraco_2.0.17_633966499098161229.zip

Blog 4 umbraco 2.0.16 – Ping services

Wednesday, December 16, 2009 by Niels Hartvig

Today is about getting an automated pinger setup on our blog so you can notify indexers like Google Blogsearch about your new posts.

We will set it up with a simple event handler that checks if the blog has any urls to ping. We will add the urls to the blog root itself by using the related links control:

image

This creates a simple xml structure which is saved on our document. So everytime we publish a new blogpost, we will simple look up the serviceUrls property recursively and ping all the urls in there.

First, a little snippet to get the value recursively:

private string GetValueRecursively(string alias, int nodeId)
{
    Document n = new Document(nodeId);
    Property p = n.getProperty(alias);
    if (p != null && !string.IsNullOrEmpty(p.Value.ToString()))
        return p.Value.ToString();
    else if (n.Parent != null)
        return GetValueRecursively(alias, n.Parent.Id);

    return string.Empty;
}

So now we can just pass the alias of the property and the Id of the document where we should start looking. If nothing is found it will continue up the content tree untill it finds anything or runs out of parent documents to look in.

As soon as we've done this, we will query the related links xml. It is structure with a parent <links> element containing child <link> elements with attributes on storing urls, names and other meta data. We will also setup the blog name and url which will be send off to the pinged urls.

string blogName = GetValueRecursively("blogName", sender.Id);
string blogUrl = umbraco.library.NiceUrlFullPath(sender.Id);
string currentDomain = HttpContext.Current.Request.ServerVariables["SERVER_NAME"].ToLower();

if (!UmbracoSettings.UseDomainPrefixes)
    blogUrl = "http://" + currentDomain + blogUrl;

foreach (XmlNode link in xd.SelectNodes("//link [@type = 'external']"))
{
    string ping = link.Attributes["link"].Value;
    //Log.Add(LogTypes.Debug, sender.Id, ping + " n:" + blogName + " u:" + blogUrl);
    PingService(ping, blogName, blogUrl);
}

This is all put together in an event handler that will fire off after any documents with the contenttype alias = "BlogPost" has been published. The actual ping is handled in the method PingService which simply puts together a chunk of xml and sends it off to the url as a normal HttpWebRequest.

 

Done, we can now ping any service that supports the xmlrpc blog pings.

Blog 4 umbraco, 2.0.15 Progress on the SkinBrowser

Tuesday, December 15, 2009 by Niels Hartvig

skinbrowser

I'm getting really close on getting the SkinBrowser fully working now. It's able to load the available skins from the package repository based on the package key (for instance "blog4umbraco") and it's done through AJAX with help from the wonderful jQuery.load method (can you remember how frustrating these things could be prior to that?!?). While the current UI needs a good deal of polish the most important thing is that it works. You can click a skin and it'll save the reference to the skin as the property.

The idea is to then fetch the skin zip-file from the package repository when you save through an event handler. It'll then download and unzip the skin as well as create a new stylesheet in Umbraco and then finally store a reference to the stylesheet path as the value of the SkinBrowser property. This means that it can be fetched in our template using a very simple recursive call such as:
<umbraco:Item runat="server" id="skin" Field="css" recursive="true />

Cool - now we just need real data. We need your help!

So now that the functionality is in place it's time for some data and I've requested some help both on Twitter and Our. Basically all the nice thumbnails above are just bogus in the way that their actual skin zip file is the same - doh. And if you're a html/css ninja with spare time before Christmas it's time to ask yourself "How can I not spend a couple of late night hours converting a Wordpress theme" - and the answer is of course "YES". Go find a sweet a nice WP theme with an open source license or if you have the talent and time create your own design. Make it compatible with the blog4umbraco markup, produce a skin file and upload it to the skin service (details). Remember that an blog4umbraco skin is css and images only.

Before you begin making a skin:

- I've just been told that we're polishing the markup on blog4umbraco to match the K2 theme markup. So wait until later Thursday (the 17th after 12.00 GMT+1) to begin as we'll post the updated markup samples here

- To ensure that people don't work on the same skins, leave a comment with what skin you're creating and when it'll be ready.

As I'm known for being ridiculous optimistic, I'm hoping that Friday the 18th will reveal a blog4umbraco build with a completely done and polished SkinBrowser as well as the first couple of skins available. Let's see if I was too optimistic this time ;-)

Get skin support for your package

If you're producing a public package and like to get skin support then get in touch and we'll be happy to provide the Skinbrowser datatype as well as the skin hosting service for free.

Blog 4 umbraco, 2.0.14 Easy blog creation

Monday, December 14, 2009 by Per Ploug Hansen

Sofar we've only looked into having a single instance of a blog on your site. So the blog was the site in itself. However, there is really no reason why you couldn't run multiple instances of a blog as part of a bigger site so multiple authors could have their own place to write content. Also we havn't looked into who actually is the author. of the blog.

So today we will do 2 things:

  1. Create a simple User Picker for the UI so we can pick a user on the blog item
  2. Create a simple dashboard for creating a blog with

This will involve messing around with the AbstractDataEditor class, the User API and the build Umbraco UIcontrols which are located in the umbraco.uicontrols namespace.

The user picker

For reasons unknown there is actually no UI component in umbraco for picking a specific user and save the users ID on a document. But no worries, this is really really easy to do and faster then you can say "AbstractDataEditor".

We want to create a dropdown control so all we have to do is render a dropdown and save the user selected in the control

Start off by creating a new class, and make it inherite the class: umbraco.cms.businesslogic.datatype.AbstractDataEditor

Override the Id, and DataTypeName Properties and set a unique ID and a proper name.

Then we need the dropdown control and wire up the events we need:

private DropDownList m_control = new DropDownList();
        public UserPicker()
        {
            base.RenderControl = m_control;
            m_control.Init += new EventHandler(m_control_Init);
            base.DataEditorControl.OnSave += new umbraco.cms.businesslogic.datatype.AbstractDataEditorControl.SaveEventHandler(DataEditorControl_OnSave);
        }

When we have the events wired up we can load the users into the control:

void m_control_Init(object sender, EventArgs e)
        {
            m_control.Items.Clear();
            foreach (User u in User.getAll())
            {
                m_control.Items.Add(new ListItem(u.Name, u.Id.ToString()));
            }
            m_control.SelectedValue = base.Data.Value != null ? base.Data.Value.ToString() : "";
        }

And then tell the dataeditor to save the selected value

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

And presto, we can now save a User ID on a document. We will add this as a autho property on the Blog document type. The complete class can be found here

 

The dashboard control

So now that we have a place to store the author ID, we will create a simple control to manage the creation of new blogs and place it on the dashboard. To give it a native feel and follow the umbraco UI guidelines, we use the built-in UI controls to manage the UI. These are in the controls.dll and can be referenced in the .ascx by adding a reference:

<%@ Register Namespace="umbraco.uicontrols" Assembly="controls" TagPrefix="umb" %>

So to build a simple form with internal umbraco UI components you can now use the umb prefix, like so:

<umb:Pane runat="server" Text="Create a blog">
    <umb:PropertyPanel runat="server" Text="Blog name">
        <asp:TextBox ID="tb_name" runat="server" />
    </umb:PropertyPanel>

    <umb:PropertyPanel runat="server" Text=" ">
        <asp:Button runat="server" OnClick="createBlogClick" Text="Create" />
    </umb:PropertyPanel>

</umb:Pane>

Now that we have the form in place, all we need is some simple API calls to create the correct document

DocumentType dt = DocumentType.GetByAlias("Blog");
Document d = Document.MakeNew(tb_name.Text, dt, User.GetCurrent(), int.Parse(cp.Text));

d.getProperty("author").Value = User.GetCurrent().Id;
d.getProperty("blogName").Value = tb_name.Text;
d.getProperty("blogDescription").Value = "The blog of " + User.GetCurrent().Name;

d.Save();

d.Publish(User.GetCurrent());
umbraco.library.UpdateDocumentCache(d.Id);

Later on we will enable the form to also create the author automaticly, but for now the form is just attached to the current user.

Adding it to the installer

The final thing we need to do is to ensure that the installer adds the control to the dashboard on install. The usercontrol is added automaticly, but we need to instruct the installer to add it to the dashboard.config (and remove it on uninstall as well). We do this with a package action:

<Action runat="install" alias="addDashboardSection" dashboardAlias="CreateBlog">
      <section>
        <areas>
          <area>content</area>
        </areas>
        <tab caption="Create Blog">
          <control>/usercontrols/Blog4Umbraco/BlogCreator.ascx</control>
        </tab>
      </section>
    </Action>

 

That is all for today, we did a new ui component for selection users in about 15 lines of code, we used native UI components for building a custom dashboard control and finally wrapped everything up nicely in the installer.

Blog 4 umbraco 2.011 – Html, xslt and the loose ends

Friday, December 11, 2009 by Per Ploug Hansen

So far we've just added new functionality to the blog package, without actually given any thought on how the final package should be presented and how the blog will look and function to the end users.

So today I'll go through these small nitpicking tasks. Add presentation of posts and comments to the package, look into the html and css, and get rid of (most of) the loose ends we currently have. This also means that the html will be final so developers can start modifying the css for the upcoming skinning functionality.

So the hours today have been spend on alot of the details which would normally be focused on when releasing, but as the final release is december 24, and all of us has some sort of family to go home to on that day, we thought it would be better to do today :)

Xslt for posts, comments, tags

First of all, a major thanks to Mister Morten Bock who has donated his xslt snippets for a tag cloud and weighted related posts. These have been added to the package as normal xslt extensions. The related pages xslt contains a single custom method which calculates the weight of the relation between posts by counting the number of categories in common. We are doing this in c# as xslt is not in any way capable of doing this, luckily, extending xslt is so easy to do.

Blog pages

A blog textpage has been added to the package so additional content can be created without it being a blog post.  We will use this to store about pages, search results, tag clouds and everything else that is not a blog post.

Templates refactor

Things have been moved around here and there to take advantage of masterpages multiple placeholders functionality. So each individual part of the master template comes with default html that can be override on any of the child templates. Support for changing background images on each individual blogs have been added

Xslt tweaks

Basic cleaning has been done in a handfull of files.

More polishing to come

This is the first push on the details front, as we get nearer the final release, we will continue to put small details into the package.

And yes I know this is not the most revolutionary of posts ;) So I promise we will do some really great things next week to make up for it.

Blog 4 Umbraco 2.0.10 – Comment moderation

Thursday, December 10, 2009 by Tim Geyssens

Today I continued the work on the comments part of the blog (after storing the comments in a seperate table and tackling comment spam with Akismet). I added a new control to the content dashboard where it will be possible to moderate the comments.

Dashboard ?

The (usually) blank right side of umbraco is called "The Dashboard". This area is configurable by adding references to the file called "/config/dashboard.config".

So I created a new usercontrol wich I added to the content dashboard by added this snippet to the config/dashboard.config

<section>
      <areas>
        <area>content</area>
      </areas>
      <tab caption="Comments">
        <control>/usercontrols/Blog4Umbraco/CommentModeration.ascx</control>
      </tab>
</section>

With this comment moderation usercontrol I simply list all the comments and make it possible to delete and mark as spam/ham , in case Akismet didn't make the right conclusion.

image

The content dasboard now has a comments tab where you can view all/only approved/only spam comments (with gravatar, author name, email, website, comment, timestamp and the page it was posted on). For each comment it is possible to delete. If the comment was seen as spam it has a different background color and it's possible to mark the comment as ham (this will send feedback back to Askimet and approve the comment so it displays on the frontend). If the comment wasn't seen as spam it's also possible to mark it as spam (wich will also send feedback back to Askimet and it will mark to comment as spam and remove it from the frontend).

The code for the usercontrol basicly just uses the datalayer to fetch all comments and then this is binded to a repeater.

private void BindData()
        {
            IRecordsReader rr = SqlHelper.ExecuteReader(
                string.Format(
                "select * from comment {0} order by created desc", Filter));

            rptComments.DataSource = rr;
            rptComments.DataBind();
        }

 

This is the first version of the comment moderation control, so there might be other features added in the next days.

Blog 4 Umbraco 2.0.9 – SkinBrowser datatype take 1

Wednesday, December 09, 2009 by Niels Hartvig

A week ago I blogged about the initial thoughts for a Skin browser in blog4umbraco (and in general) as well as looking at the server part. Today I've started the work in the datatype - ie. the place in blog4umbraco where you'll be able to fetch and change your current skin.

While nowhere near done it was an interesting experience into the very belly of the Umbraco core and an even better inspiration on how we can make this much easier in the future. That was one of my hopes for this calendar - that by eating our own dog food in an über agile (read: completely unplanned) project we'd play with the parts of Umbraco that we don't deal with normally. But let's start from the beginning, shall we!

What is custom datatypes anyway?

Why not start by looking at what a datatype is. It's the different types of edit options on content properties in Umbraco. While that might sound a little complex, you know them already; Upload, Richtext Editor, Ultimate Picker, Textbox multiple (and what's up with that silly name for something that just a textarea, Niels!), etc. In order words, datatypes are the "Type" you choose when adding properties to a Document-, Member- or Media Type.

While Umbraco ships with more than twenty datatypes, you may find that it's not sufficient and this is where the custom datatypes comes in: As with any other areas of Umbraco you can add your own.

The options

Datatypes are the most central part of Umbraco and can be a bit overwhelming as they handle editing, persistence, xml generation and configuration at their most extreme and the price for all this is of course a good bunch of interfaces that you need to implement. At the same time this was one of the very first things designed in Umbraco back in 2004, so - well, let's just skip over that part elegantly and say there's room for improvement - and improvement has been made!

Instead of learning a lot about how all these interfaces work, you can turn any ordinary user control into a custom datatype with implementing just one interface with a single property by using the existing "Usercontrol wrapper" datatype and the IUsercontrolDataEditor interface (found in the umbraco.editorControls.userControlGrapper namespace - notice the nice typo in the namespace. That's called digital patina and gets more and more charming as it age. It's definitely not a bug!). While this technique is really easy and sweet it doesn't fit our needs as we're trying to make a pretty generic datatype that can be used in other places that just the blog4umbraco package, so...

AbstractDataEditor is our choice!

The abstractDataEditor was added in Umbraco 4.0.1 to make it easier to build advanced custom datatypes. It makes it possible to use composite controls together with custom configurators all while not having to know about how everything is wired in Umbraco - just what we need! But the whole configuration part is really something that could need a lot of TLC as all the CRUD operations of config values is a manual process which is really silly and unnecessary complex. But this means that we can improve Umbraco and that's awesome :)

While this (and the above) is great topics for future umbraco.tv videos you can read more about making your own Abstract Data Editors on Tims awesome blog.

With the Abstract DataEditor in place I was able to make a nice (unpolished) way of configuring which package that the SkinBrowser should query on the package repository as well as a placeholder that'll take care of fetching new skins as well as install them:

Picture 21

The SkinBrowser configurator

Picture 22

How it looks right now when placed on a document type (currently a non-functional placeholder)

More on that very soon...

Blog 4 Umbraco 2.0.8 – Tackling comment spam

Tuesday, December 08, 2009 by Tim Geyssens

In todays chapter (notice that it's 2.0.8 , yesterdays should have been 2.0.7, small mistake by santa's magic elf) we'll be improving Blog 4 Umbraco to include some spam protection. We'll be checking the comments against the Akismet spam filtering service. But since Akismet isn't the only spam filtering service we'll be building a simple provider model to make it easy to add support for whatever service you want to use.

Before you can use Akismet you need to have a valid API Key ( You can get a free API key by registering for a user account here). And we'll also need to store this API Key, since Akismet will be set as the default on new Blog 4 Umbraco installations we'll just store this on the blog node. So I'll need to add a new property on the Blog document type.

image

After adding the new property I'll be able to set the API Key on the Blog document.

image 

Now I'm ready to start using Akismet. I'll first start by setting up a simple provider model. The way these spam filtering services work is that you feed them all the comment info and they return whether or not the comment is considered spam.

So I'll define an interface that has a Check method with all the comment info (useragent, ip, author, author email, author url and the actual comment).

public interface ISpamChecker
    {
        String ProviderName { get; set; }

        Boolean Check(int nodeid,
            string UserAgent, string UserIp, string Author,
            string AuthorEmail, string AuthorUrl, string Content);
    }

Next I'll add an abstract class that implements the new interface

public abstract class SpamChecker: ISpamChecker
    {
        #region ISpamChecker Members

        private string m_providername;
        public string ProviderName
        {
            get { return m_providername; }
            set { m_providername = value; }
        }

        public virtual bool Check(
            int nodeid, string UserAgent, string UserIp,
            string Author, string AuthorEmail, string AuthorUrl, string Content)
        {
            return false;
        }

        #endregion
    }

And then I'll add the actual Akismet spam checker class (that inherits from the abstract class and overrides the check method). There's allready an open source .net wrapper for the Akistmet service so I'll make use of that.

 

public class AkismetSpamChecker: SpamChecker   {      

       public AkismetSpamChecker()
       {
           this.ProviderName = "Akismet";
       }

       public override Boolean Check(int nodeid,
           string UserAgent, string UserIp, string Author,
           string AuthorEmail, string AuthorUrl, string Content)
       {

           umbraco.presentation.nodeFactory.Node blog =
               new umbraco.presentation.nodeFactory.Node(nodeid);

           while (blog.NodeTypeAlias != "Blog")
           {
               blog = blog.Parent;
           }

           if (blog.GetProperty("akismetAPIKey").Value != string.Empty)
           {               
               Akismet api = new Joel.Net.Akismet(
                   blog.GetProperty("akismetAPIKey").Value,
                   "http://" + HttpContext.Current.Request.ServerVariables["HTTP_HOST"] + blog.Url,
                   "Blog4Umbraco2");

               if (!api.VerifyKey())
               {
                   umbraco.BusinessLogic.Log.Add(
                       umbraco.BusinessLogic.LogTypes.Error,
                       -1,
                       "Akismet Key could not be verified, please check if you have a valid Akismet API Key");

                   return false;
               };

               AkismetComment comment = new AkismetComment();
               comment.UserAgent = UserAgent;
               comment.UserIp = UserIp;
               comment.CommentType = "comment";
               comment.CommentAuthor = Author;
               comment.CommentAuthorEmail = AuthorEmail;
               comment.CommentAuthorUrl = AuthorUrl;
               comment.CommentContent = Content;

               return api.CommentCheck(comment);
           }
           else
           {
               return false;
           }
       }

   }

 

So in the check method I'll first see if we have a valid API key (using the nodefactory to get it of the blog document), if that's ok I'll return the value of the CommentCheck function.

The final step is to actually call this check method when a new comment is submitted.

Since we want to make it possible to plug in your own spam checker I'll add a little config file.

<?xml version="1.0"?>
<SpamChecker assembly="/bin/Umlaut.Umb.Blog" type="Umlaut.Umb.Blog.Spam.AkismetSpamChecker">
</SpamChecker>

 

That contains the assembly and the type of the spam checker class that will be used (default we'll use the Akismet one).

By using some reflection we'll call the Check method on the correct Type (that's setup in the config file).

bool isspam = false;

           try
           {
               string assemblyFile =
                   HttpContext.Current.Server.MapPath(
                   String.Format("{0}/..{1}.dll",
                   GlobalSettings.Path,
                   Config.GetProviderAssembly()));

               Assembly checkerAssembly = Assembly.LoadFrom(assemblyFile);

               SpamChecker checker =
                   (SpamChecker)Activator.CreateInstance(
                   checkerAssembly.GetType(Config.GetProviderType()));

               isspam = checker.Check(parentId,
                   post.UserAgent, post.UserHostAddress,
                   name, email, website, comment);
           }
           catch (Exception ex) { }

And we'll update the insert statement from yesterdays chapter to store the value of isspam instead of always storing false.

That's it, our comments will now by checked by Akismet and if they are seen as spam they won't appear on the blog (since we only display the comments that aren't flagged as spam).

Blog 4 umbraco 2.0.5 – Comments

Monday, December 07, 2009 by Tim Geyssens

Today we'll make an improvement to blog 4 umbraco that shouldn't have any impact on the frontend of the blog but will make it much easier to handle comment spam and moderate comments. We'll move away from storing the comments as documents and store them in a database table instead. We'll fetch them with some xslt extensions (haven't heard of xslt extensions, be sure to check out the umbraco.tv chapter /documentation/videos/for-developers/xslt-extensions/introduction-to-xslt-extensions)

First

The first step is to create this new table, we'll need to store the post id, the actual comment (name, email, website, comment), the timestamp and we'll also add a spam field.

CREATE TABLE [Comment](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [blogid] [int] NOT NULL,
    [postid] [int] NOT NULL,
    [name] [nvarchar](250) NULL,
    [email] [nvarchar](250) NULL,
    [website] [nvarchar](250) NULL,
    [comment] [text] NULL,
    [spam] [bit] NULL,
    [created] [datetime] NULL,
CONSTRAINT [PK_Comment] PRIMARY KEY CLUSTERED
(
    [id] ASC
)

(this is the sql server create script, we'll also include a vistadb and mysql create script in the installer)

Storing comments

Instead of creating a comment document with the umbraco api we'll update the method to insert a record in the new table using the umbraco datalayer (to make sure this can be executed on sql server, vistadb and mysql)

ISqlHelper SqlHelper = DataLayerHelper.CreateSqlHelper(umbraco.GlobalSettings.DbDSN);
            SqlHelper.ExecuteNonQuery(
                @"insert into Comment(blogid,postid,name,email,website,comment,spam,created)
                    values(@blogid,@postid,@name,@email,@website,@comment,@spam,@created)",
                 SqlHelper.CreateParameter("@blogid", blogid),
                SqlHelper.CreateParameter("@postid", blogpost.Id),
                SqlHelper.CreateParameter("@name", name),
                SqlHelper.CreateParameter("@email", email),
                SqlHelper.CreateParameter("@website", website),
                SqlHelper.CreateParameter("@comment", comment),
                SqlHelper.CreateParameter("@spam", false),
                SqlHelper.CreateParameter("@created", DateTime.Now));

Showing comments

For showing the comments we'll add some new methods to our blog xslt extensions. Basicly I want to select all comments or select the comment for a specific post. So I'll need a GetComments() method and a GetCommentsForBlog(int id) method. Both will return some xml (XPathNodeIterator) that will look like this:

<comments>

<comment id="2" postid="1206" created="7/12/2009 16:22:28">

<name>Tim Geyssens</name>

<email>myemail@domain.com</email>

<website>http://www.umbraco.org</website>

<message>This should be stored in the database</message>

</comment>

</comments>

We'll also use the umbraco datalayer to execute these queries and we'll add a method that creates the comment xml from a RecordsReader.

public static XPathNodeIterator GetCommentsForPost(int id)
      {

          ISqlHelper SqlHelper = DataLayerHelper.CreateSqlHelper(umbraco.GlobalSettings.DbDSN);
          IRecordsReader rr = SqlHelper.ExecuteReader(
              "select * from comment where postid = @postid and spam != 1",
               SqlHelper.CreateParameter("@postid", id));

          return CommentsToXml(rr);
      }

 

private static XPathNodeIterator CommentsToXml(IRecordsReader rr)
        {
            XmlDocument xd = new XmlDocument();

            XmlNode x = umbraco.xmlHelper.addTextNode(xd, "comments", "");

            while (rr.Read())
            {
                XmlNode c = xd.CreateElement("comment");

                c.Attributes.Append(umbraco.xmlHelper.addAttribute(xd, "id", rr.GetInt("id").ToString()));
                c.Attributes.Append(umbraco.xmlHelper.addAttribute(xd, "postid", rr.GetInt("postid").ToString()));
                c.Attributes.Append(umbraco.xmlHelper.addAttribute(xd, "created", rr.GetDateTime("created").ToString()));

                c.AppendChild(umbraco.xmlHelper.addCDataNode(xd, "name", rr.GetString("name")));
                c.AppendChild(umbraco.xmlHelper.addCDataNode(xd, "email", rr.GetString("email")));
                c.AppendChild(umbraco.xmlHelper.addCDataNode(xd, "website", rr.GetString("website")));
                c.AppendChild(umbraco.xmlHelper.addCDataNode(xd, "message", rr.GetString("comment")));

                x.AppendChild(c);
            }

            xd.AppendChild(x);

            return xd.CreateNavigator().Select(".");
        }

 

With the new xslt extensions in place we'll just need to update our xslt to fetch the comments from these.

So this is how the list comments xslt will look after the update:

<h3 id="comments">
<xsl:value-of select="count(BlogLibrary:GetCommentsForPost($currentPage/@id)//comment)"/> comment(s)  for  &#8220;<xsl:value-of select="$currentPage/@nodeName"/>&#8221;</h3>

<ol class="commentlist">
<xsl:for-each select="BlogLibrary:GetCommentsForPost($currentPage/@id)//comment">

<li class="alt" id="comment-{@id}">
<div class="commentcontent">
    <div class="commentgravatar" style="float:right;margin-right: 5px;">
        <img width="40px" height="40px" src="{BlogLibrary:getGravatar(./email, 40, '')}" alt="Gravatar of {./name}"/>
    </div>
    <cite>  <xsl:value-of select="./name"/> </cite> Says: <br />
    <small class="commentmetadata"><xsl:value-of select="umbraco.library:LongDate(@created)"/> </small>
    <xsl:value-of select="umbraco.library:ReplaceLineBreaks(./message)" disable-output-escaping="yes"/>
</div>

</li>
</xsl:for-each>
</ol>

That's it, the blog comments are now stored/fetched from a table instead of using documents.

Blog 4 umbraco 2.0.4 – Rss-feeds

Friday, December 04, 2009 by Tim Geyssens

Today we'll look at improving the blog rss-feed(s), the magic words are xslt, alternative templates and some url rewriting .Currently the blog4umbraco package comes with a single rss-feed that just lists the xth latest blog posts. We'll be improving that so as an end result we'll have:

  • Latest posts rss feed
  • Latest posts rss feed for each tag
  • Comments rss feed
  • Comments rss feed for each post

Basicly the rss feed is an alternative template that's applied to the blog homepage(by adding the template alias 'rss' to the url) . And that template contains a single xslt macro that outputs the rss-feed in the correct format (the rss feed is one of the templates you can start your xslt with).

image

A small update that I'll tackle first it to update the SiteURL variable from a static value to a dynamic one by fetching the current host from the HTTP_HOST server variable.

<xsl:variable name="SiteURL" select="concat(' http://',string(umbraco.library:RequestServerVariables('HTTP_HOST')))"/>

Latest posts rss feed for each tag

In order to have an rss feed for each tag, we'll just have to update the code that selects the blogposts and only show the blogposts that contain the supplied tag. If there isn't a tag supplied (we'll use the request param tag, so /rss.aspx?tag=xmas) we still display all blogposts. So we'll first check if the request param tag is available, if it isn't we select all blogposts (like it should allready do) and if there is a tag supplied we'll filter the blog posts to only select the ones containing that tag.

<xsl:choose>
        <xsl:when test="string-length(umbraco.library:Request('tag')) &gt; 0">
            <xsl:apply-templates select="$currentPage//node [@nodeTypeAlias = 'BlogPost' and contains(Exslt.ExsltStrings:lowercase(./data [@alias='tags']), Exslt.ExsltStrings:lowercase(umbraco.library:Request('tag')))]">
                      <xsl:sort select="@createDate" order="descending" />
                    </xsl:apply-templates>
        </xsl:when>
        <xsl:otherwise>
            <xsl:apply-templates select="$currentPage//node [@nodeTypeAlias = 'BlogPost']">
                      <xsl:sort select="@createDate" order="descending" />
                    </xsl:apply-templates>
        </xsl:otherwise>
    </xsl:choose>

We'll make this have a nicer url by adding a url rewriting rule to the /config/UrlRewriting.config file. So we'll go from /rss?tag=xmas to /rss/tags/xmas.

<add name="rsstagrewrite"
    virtualUrl="^~/blog/rss/tags/(.*).aspx"
    rewriteUrlParameter="ExcludeFromClientQueryString"
    destinationUrl="~/blog/rss.aspx?tag=$1"
    ignoreCase="true" />

Comments rss feed

For the comments rss feed we'll also be able to re-use most of the main xslt we'll just need to know if we need to output a comments feed instead of a blog post feed (since we have to select different documents and these have a different structure). So I'll add a parameter to the blog rss macro called 'iscommentfeed'.

image

And I'll also create a new template called 'CommentRss'. This will be used in the same way as the Rss template (as an alternative template). The only difference between the 2 will be the value of the iscommentfeed parameter.

So I'll first update the blog rss macro to include the iscommentfeed variable

<xsl:variable name="iscommentfeed" select="//macro/iscommentfeed" />

And then prior to selecting the BlogPosts I'll check the value of the iscommentfeed variable. In case the value is 1 we'll need to select the comments instead of the posts.

<xsl:when test="$iscommentfeed = '1'">

            <xsl:apply-templates select="$currentPage//node [@nodeTypeAlias = 'BlogPostComment']">
                      <xsl:sort select="@createDate" order="descending" />
                    </xsl:apply-templates>

        </xsl:when>

I'll also have to update the xslt code that outputs the rss items. Since the post and comments will have a different url and a differen structure (content of a post is stored in the bodyText property, content of a comment in the comment property).

<xsl:variable name="link">
        <xsl:choose>
            <xsl:when test="@nodeTypeAlias = 'BlogPostComment'">
                <xsl:value-of select="concat(umbraco.library:NiceUrl(./../@id),'#comment-',@id)"/>
            </xsl:when>
            <xsl:otherwise>
                 <xsl:value-of select="umbraco.library:NiceUrl(@id)"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:variable name="content">
        <xsl:choose>
            <xsl:when test="@nodeTypeAlias = 'BlogPostComment'">
                 <xsl:value-of select="umbraco.library:ReplaceLineBreaks(data [@alias = 'comment'])"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="./data [@alias='bodyText']"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

Comments rss feed for each post

For making a comments rss feed for each post I won't have to change anything to the xslt. Since I select all the comments found below the currentPage ($currentPage//node [@nodeTypeAlias = 'BlogPostComment']).

So when calling the commentsrss template on the main blog page (blog/commentrss.aspx), we'll list all comments but when calling the template on a specific post ( blog/2009/12/3/xmaspost/commentrss.aspx) we'll only get the comments for that post.

Final touches

The last thing we'll do is update the xslt file that's responsible for outputting the rss feed link.

In case we are viewing the posts of a certain tag we'll need to add a link to the rss feed for that tag (/rss/tags/xmas.aspx).

<xsl:if test="string-length(umbraco.library:Request('filterby')) &gt; 0">
    <link href="{umbraco.library:Replace(umbraco.library:NiceUrl($currentPage/ancestor-or-self::node [@nodeTypeAlias = 'Blog']/@id),'.aspx',concat('/rss/tags/',umbraco.library:Request('filterby'),'.aspx'))}" rel="alternate" type="application/rss+xml" title="RSS Feed for tag {umbraco.library:Request('filterby')}" />
</xsl:if>

And we'll also need to show a link to the comments rss feed (wich is an alternative template of the blog called commentrss)

<link href="{umbraco.library:Replace(umbraco.library:NiceUrl($currentPage/ancestor-or-self::node [@nodeTypeAlias = 'Blog']/@id),'.aspx','/commentrss.aspx')}" rel="alternate" type="application/rss+xml" title="Comments RSS Feed" />

And if we are on a blog post  (we can check that with the nodetypealias) we'll also add a link to the comments feed for that specific blog post.

<xsl:if test="$currentPage/@nodeTypeAlias = 'BlogPost'">
    <link href="{umbraco.library:Replace(umbraco.library:NiceUrl($currentPage/@id),'.aspx','/commentrss.aspx')}" rel="alternate" type="application/rss+xml" title="Comments RSS Feed for {$currentPage/@nodeName}" />
</xsl:if>

The result

When on the main blog page, we'll have the main rss feed and the comments rss feed

image

On a post we'll also have the comments feed for that post

image

And when viewing the posts for a certain tag …

image

Blog 4 umbraco 2.0.3 – Ajax Comment Form

Thursday, December 03, 2009 by Per Ploug Hansen

While Niels is tinkering with the client part of the skinning, I thought I would go back to web developement basics and do some old-fashion Html and javascript.

The current blog comment form is a bit dated, and lacks some polish. I decided to rewrite it, to first of all get some cleaner html, but also to add the following details:

  • Nice clean validation with jquery.validation
  • ajax form posting
  • Gravatar preview "as you type"
  • Compatibility for screen-readers

The plan is to:

  1. Create the server-side logic that creates the comment
  2. Connect that logic to the client, using /base
  3. Do simpel form markup, no runat="server" attributes
  4. Write some simpel jquery to post values to /base
  5. prettify the form
  6. Make it work without javascript

The server-side logic:

For this I created a simple static method with a single parameter, the ID of the blog post. It creates a comment and fills in the different properties: email, name, comment etc.

The way it receives input is through the HttpContext request collection, those who remember Asp 3.0 classic will recognise this approach, so no view-state hell. I've added the entire method below. It contains a couple of comments to guide you. The main points are:

  1. Get values from HttpContext request collection
  2. Check they are valid
  3. Test the blog post exists and it's the right content type
  4. Create the document and fill in the properties
  5. Save and publish
  6. Return the ID of the page created

public static int CreateComment(int parentId)
{

//here we find form values posted to the current page
    HttpRequest post = HttpContext.Current.Request;
    string email = post["email"];
    string comment = post["comment"];
    string name = post["name"];
    string website = post["website"];


    //if all values are there + valid email.. we start to create the comment
    if (!string.IsNullOrEmpty(email) && isValidEmail(email) && !string.IsNullOrEmpty(comment) && !string.IsNullOrEmpty(name))
    {

        Document blogpost = new Document(parentId);

        //if parent is actually a blogpost
        if(blogpost != null && blogpost.ContentType.Alias == "BlogPost"){
            DocumentType dt = DocumentType.GetByAlias("BlogPostComment");
            Document d = Document.MakeNew("RE: " + blogpost.Text + " by: " + name, dt, new umbraco.BusinessLogic.User(0), blogpost.Id);
            d.getProperty("comment").Value = comment;
            d.getProperty("email").Value = email;
            d.getProperty("name").Value = name;
            d.getProperty("website").Value = website;
            d.Save();
            d.Publish(new umbraco.BusinessLogic.User(0));

            umbraco.library.UpdateDocumentCache(d.Id);
            return d.Id;
        }
    }


    //if nothing gets created, we return zero
    return 0;
}

Connecting the serverside logic to the client

Now that we have some code that can create the comment, we want to make it accessible directly from the browser. For that we use the built in /base, which in short works as an automatic proxy between server-side code and the browser by creating urls that can execute this server side code.

The connection happens in the file /config/restExtensions.config

In here we map the dll Umlaut.Umb.Blog.dll in a <ext> element, add a nice alias, and then add the method CreateComment to the manifest as well:

<ext assembly="/bin/Umlaut.Umb.Blog" type="Umlaut.Umb.Blog.Library.Base" alias="Blog4Umbraco">
    <permission method="CreateComment" returnXml="false" allowAll="true" />
</ext>

this means that we can now invoke the method by going to the url /base/Blog4Umbraco/CreateComment/[pageId].aspx we will use this later when jquery will post the form.

Form markup

The great about doing the form without any asp.net controls is that you rediscover how simple and great html actually is. Install the blog package from: http://nightly.umbraco.org/Blog4Umbraco/2.0.3/ and view the /usercontrols/ajaxcommentform.ascx to see the full markup.

The below sample is the markup for a single field:

<p class="commentField emailField">
    <label for="tb_email" class="fieldLabel">
        <%= Umlaut.Umb.Blog.BlogLibrary.Dictionary("#Email","Email address") %>:
    </label>
    <input type="text" id="tb_email" name="email" class="input-text required email" />
</p>

Things to notice: We have dictionary support for labels (first parameter is the key, and the second is the value to return if the key doesn't exist), and we use jquery.validation for validating the form on the client. We do this by adding the classes "required" and "email" to this field. Which ensures that the field is filled out and is a correct email.

Post values to /base url with jQuery

Finally, the core functionality! When the form has been filled out we want to post it with ajax to the /base url, which will handle the comment creation. We do this with jQuery.Post

var url = "/base/Blog4Umbraco/CreateComment/<umbraco:Item field="pageID" runat="server"/>.aspx";

jQuery.post(url, { name: jQuery("#tb_name").val(), email: jQuery("#tb_email").val(), website: jQuery("#tb_website").val(), comment: jQuery("#ta_comment").val() },
                   function(data){
                     jQuery("#commentPosted").show();
                   }
                   });

First we build a url variable. As you ca see it points to /base/Blog4Umbraco/CreateComment/ and we then insert the current page Id on the server side. jQuery then posts a collection of values (email,name,etc) to the /base url. and displays some feedback.

Presto, we have an ajax form.

Prettify

While we are at it, we'll also add a gravatar preview, so when you enter your email, you will see your gravatar image to the right:

image

This is also done with jquery and /base:

jQuery("#tb_email").blur(function(){
                var email = jQuery("#tb_email").val();
                if(email != ""){
                    var url = "/base/Blog4Umbraco/GetGravatarImage/" + email + "/80.aspx";
                    jQuery.get(url, function(data){
                        if(data != ""){
                             jQuery("#gravatar").css( "background-image","url(" + data + ")" ).show();
                        }else{
                            jQuery("#gravatar").hide();
                        }
                    });
                }
          });

Again, we send simple request to a /base method, this time with 2 parameters, email and image size. The call returns a url to the gravatar image associated with the email.

Make it work without javascript

The great thing about having the form as an ajax form is that automated comment spam doesn't get through. However, neither does people using screenreaders. To ensure that screenreaders can use the form, we need to ensure that it works with javascript turned off. Luckily, we already have the serverside code that expects a collection of values in the Request collection. And when javascript is turned off, the form will post back to it's own url, due to the standard asp.net form. This means that we can execute the /base serverside logic on the page load event in the AjaxCommentForm.ascx like this:

protected void Page_Load(object sender, EventArgs e)
        {
            if (Page.IsPostBack)
            {
                Library.Base.CreateComment(umbraco.presentation.nodeFactory.Node.GetCurrent().Id);
            }
        }

Notice it is the exact same method, it uses the request collection so it works no matter if its executed when a form is post to a /base url, or if the form is post to the page with the macro on.

More

There has just been posted 2 videos to umbraco.tv about umbraco /base and a video walkthrough of the code explained above. So to get even more info on how to do ajax and umbraco, go to:

http://umbraco.tv/documentation/videos/for-developers/base-and-ajax-development

Also, the code is on codeplex: http://blog4umbraco.codeplex.com/ and as a nightly build: http://nightly.umbraco.org/Blog4Umbraco/2.0.3/

Blog 4 Umbraco 2.0.2 – skinning

Wednesday, December 02, 2009 by Niels Hartvig

My challenge today was to come up with a way to provide easier skinning for the blog4umbraco package. Today there's several challenges if you want to get up to speed fast with the current blog4umbraco package:

  • The default skin is old
  • There are layout quirks (such as the comment form doesn't align - yikes!)
  • Alternative skins for blog4umbraco are scattered and there's no conventions
  • Changing a skin requires good knowledge of Umbraco terms such as doctypes, templates and macros. Not easy to get started

The problems above is not unique to blog4umbraco, but a general thing with Umbraco as we like to see ourselves as a framework. This - however - shouldn't prevent us from making it easier to get quickly up to speed for newcomers. And as most people know, once you got something that you can relate to, it's more motivating to dive in.

Bring in the skin

The solution is to create a convention for skins that in the current project benefits blog4umbraco, but over time could benefit other projects such as Warren Buckleys Creative Website Wizard, Runway and the hot new Business Website Starter Pack.

As I'm a fan of keeping things simple and to the point and as we're talking simple skinning (not fancy theming) I decided to keep skins CSS+images only. If the markup is cool, the possibilities with CSS alone is incredible and for more fancy stuff we have the package format to take care of that. So without further ado, let me introduce the new Skin format for Umbraco packages:

What is a skin?

Skins for Umbraco is a zip file containing CSS + images as well as a manifest, a thumbnail and a preview image.

The structure of the zip must be:

  • /thumbnail.png (a 100x100 pixel thumbnail in png format)
  • /preview.png (a 500xYYY pixel preview in png format)
  • /skin.xml (a manifest file containing meta data about you and your skin. See example skin.xml and grab the XSD for Visual Studio intellisense)
  • /css/style.css (your css file. Must be named 'style.css')
  • /css/images/* (images for your css)

User experience

The idea is to host skins in the package repository and make them relate to a specific project. That project can include a new datatype (Skin Browser) which gets configured with some help text as well as a URI that acts as the identifier to fetch skins from the repository. To use skinning in a package all you need to do (once you've got your project approved in the package repo by the evil Umbraco HQ) is to place the Skin Browser data type on the root page of your package content:

umbraco

The skin browser will show you the current skin used and will store the reference to the css file (ie. /css/pixel/style.css). This can easily be used in templates by using the recursive option when inserting an Umbraco field: <umbraco:Item runat="server" id="skin" Field="css" recursive="true" />

When clicking the "Browse skins from Umbraco Package Server" it'll query the repository for a list of skins that matches the project:

chooseSkin

When clicking on the "Use this skin" link, it'll download the skin, extract it and update the css reference (the value of the "Skin Browser" property). When you publish the page you'll then use the new skin.

Nice Balsamiq Mockups - is this vapor?

Well, ehm. The Christmas Calendar manifest say that we can't use more than an hour a day. I've spend three in total (which will make it up for the coming Saturday and Sunday) and managed to make the concept, mockups and formats. But not the datatype - that'll have to wait for one of the coming days. But I did manage to build the server part as well as the submit skin functionality which made me positively surprised of the development speed I gain from Umbraco (nice plug, aye ;-) - but bear with me, I almost don't do implementations anymore).

On our package repository - which runs Umbraco of course - I created a "skins" document type which will be the placeholder for a project (such as "blog4umbraco") as well as a "skin" document type that holds all the metadata:

Picture 15

Using XSLT it was really easy to make a feed that the coming data type can use to fetch the different skins (see the XSLT here) and using alternative templates I can now fetch the list of skins by calling the URL of the project in the repository combined with the alias of my listing template "getskinsasxml":

http://packages.umbraco.org/skins/blog4umbraco/getskinsasxml

Uploading a new skin

I also managed to make a nice little usercontrol that lets you upload your skin (the zip file) and then extract all the meta data and create a new skin as a content object. Using notifications in Umbraco it'll automatically notify moderators to review the submitted skin before publishing it (and thus, making it publicly available in the feed). Again I used alternative templates to make it easy to know which project to associate the uploaded item for. I simply append "uploadskin" to the url and then I know that the current page is the correct skin:

http://packages.umbraco.org/skins/blog4umbraco/uploadskin

One important thing when using alternative templates for something like this that you're responsible for verifying that the alternative template is used on the appropriate type (as alternative templates bypasses the template rules on a doctype). To do this I added a simple check in the Page Load event where I use the nodefactory to verify that the current page indeed has a document type of "skins" (ie. our project placeholder type):

if (Node.GetCurrent().NodeTypeAlias.ToLower() != "skins")
{
    throw new Exception("Can only upload skins to skin repositories");
}

So now we got the skinning infrastructure in place. All we need to do next is building the custom data type using the AbstractDataEditor which makes it easy to build a configurable custom data type as opposed to just using the User Control Wrapper data type which makes it super easy to build a custom data type, but doesn't support configuration.

We also need to look at the markup for the blog4umbraco templates to see if it's as good as it should be. If anyone wants to help with that or help making skins - let us know!

Merry Christmas :)

Blog 4 Umbraco 2.0.1 – Setting up the project

Tuesday, December 01, 2009 by Per Ploug Hansen

Our first day of developement is all about getting project ready for the agile developement process. We don't want to worry about packing, file manifests or doing daily builds the next 24 days, so the first thing to do on this project is getting the infrastructure setup.

This will require:

  1. Source Code repository
  2. A build server
  3. A clean project structure containing all files
  4. A package manifest for installing the package on umbraco
  5. A nant script for putting the package together and automating manifests, zipping etc
  6. Som misc utillities for handling files in the package

Source code

Blog 4 umbraco is already on codeplex, so we will keep it there and modify the current project to fit our needs, source and issue tracker can be found on:
http://www.codeplex.com/blog4umbraco

Build server

We already use TeamCity for our Contour, Courier and Concierge build processes, it's easy to setup, has a fantastic UI and works fantasticly with nant and subversion, cannot recommend this enough. As there is alreay enough documentation out there on how to setup Team City, I won't spend more time on this, but it's awesome, your build process just works and you don't have to worry about anything. As we use Nant for building the code we can also test the entire build process locally, by running the nant scripts on the local developement machine.

Get TeamCity here: http://www.jetbrains.com/teamcity/

Project Structure

We put everything in our visual studio project to ensure it can build anywhere, so it will contain our nant script and package manifest files for easy editing. For the project files themselves we've setup this simple structure:

  • Solution items
    contains nant script, package manifes and utillities
  • Css
    All css files for the presentation
  • EventHandlers
    Classes that hook into the eventmodel
  • Images
    images for the presentation
  • Library
    The Blog xslt extension
  • Scripts
    javascript files
  • Templates
    Master template files
  • UserControls
    usercontrols for macros
  • Xslt
    xslt files for macros

Everything is now in source control so our build server can fetch it every night and put together a nice package and hotfix

Package Manifest

The package manifest is the part of the project that tells umbraco how the different items should be installed it contains refences to all files, templates, macros, css etc. Normally package files are created in the umbraco backend by using the package located in the developer section. However, we need to have the package file updated every night, and don't want to spend time on this. So instead we will generate a very basic package manifest, using the umbraco packager, which includes all document types, template references and other items that are unlikely to change. This basic package manifest will then be updated on every build to keep it uptodate.

For this project we installed the current blog package and then generated a new package containing all templates, document types, stylessheets, macros etc. and added its manifest to the visual studio solution.

Nant scripting

Nant is a automated build tool, which performs tasks in a build script (wikipedia). But it does so much more then building source code. In this project I've setup nant to perform the following tasks (so I don't have to)

  1. Build the source code
  2. Move files from the project into a package folder
  3. Modify the package.xml manifest with the list of current files
  4. Add template markup to the package manifest from the template files in the project
  5. Add stylesheets to the package manifest
  6. update the version number
  7. Zip the files as a package with a manifest
  8. Zip files as a hotfix to make it easy to update current installations
  9. publish the files on nightly.umbraco.org
  10. Clean up

I've setup a nant project a couple of times now, and making nant perform the above tasks took about 40 minuts to do. So how do you setup Nant to do these things, download the source from codeplex and view the nant.build file and go through the below chapters:

You need to have nant installed on your developement machine to be able to use nant. It can be downloaded and installed from here: http://nant.sourceforge.net/release/0.85/help/introduction/installation.html

To run the nant script, open cmd.exe, browse to the blog4umbraco directory and write the command "nant" hit enter and it will execute the .build file.

Nant script structure

The script is divided into different targets (<target> elements)

  • Compile
  • Movefiles
  • Manifest
  • Zip
  • Publish

These targets handle a different part of the process. You can execute all targets by call the command "nant" or just some of them by calling the comman "nant <name of target>" (ex: "nant manifest"). Each target depends on another target which ensures that everything is done in the right order.

 

Using nant to build your project

The first thing we need to do is compiling the source code. We use the Msbuild.exe which is included in the .net framework. msbuild is alot more picky about building visual solutions and forces you to clean up missing files, wrong page declarations etc. To make nant perform the build we call the msbuild.exe file directly and tell it to build out solution:

<exec program="${msbuild.app}" basedir="${root.dir}">
      <arg value="UmLaut.Umb.Blog.sln" />
      <arg value="/p:Configuration=Debug"/>
      <arg value="/p:Platform=&quot;Any CPU&quot;"/>
    </exec>

Adding template markup to the package manifest

We keep our templates as files in the project, but to install them, we need to move the markup to the package manifest, this is done by executing a nant task called loadfile and then xmlpoke:

<loadfile file="${core.dir}\templates\Blog.master" property="blog.master" />
<xmlpoke file="${zip.dir}\package.xml" xpath="/umbPackage/Templates/Template [Alias = 'Blog']/Design" value="&lt;![CDATA[${blog.master}]]&gt;" />

We load the template file into a property, and then inject the contents of that file into the package manifest. The xpath tells xmlpoke where to place the value ${blog.master} which is the contents of the file. We use the same technique for all the templates and for the stylesheets as well.

Gathering files for the package and zipping them

For our package we need to gather all the files umbraco needs for the installation and tell umbraco what path to place them on. For this we create a temporary folder and copy the needed files. We place them in the right structure as well. We use simple nant tasks to copy these files and make new directories

    <!-- Images -->
    <mkdir dir="${package.dir}\images" />
    <copy todir="${package.dir}\images" includeemptydirs="true" flatten="false" failonerror="false" overwrite="true">
      <fileset basedir="${core.dir}\images">
        <include name="*.*" />
      </fileset>
    </copy>

    <!-- Usercontrols -->
    <mkdir dir="${package.dir}\usercontrols\${dist.name}" />
    <copy todir="${package.dir}\usercontrols\${dist.name}" includeemptydirs="true" flatten="false" failonerror="false" overwrite="true">
      <fileset basedir="${core.dir}\usercontrols">
        <include name="*.ascx" />
      </fileset>
    </copy>

When we have the files collected in the folder, we execute a small utillity which registers all files in the package.xml manifest and moves them to the folder they will be zipped in. The current package format requires that all files are located in the root of the zipped folder so we also rename all files to a guid to ensure that nothing is overwritten. The utillity "AddFilesTopackages.exe" takes care of this as well (included in the blog 4 umbraco project)

    <!-- here we will append files in the package directory to the package file-->
    <!-- arguments: package.xml manifest, folder with files in correct structure, folder to send to for zipping-->
    <exec program="${root.dir}\AddFilesToPackage.exe">
      <arg value="${package.dir}\package.xml" />
      <arg value="${package.dir}" />
      <arg value="${zip.dir}" />
    </exec>

Finally we will zip everything into 2 packages, one is the installable umbraco package with all files located in the root of the folder, the other a hotfix release with all files named and located correctly so it's easy to xcopy to an existing installation.

     <!-- Zip everything -->
    <zip zipfile="${root.dir}\package.zip" includeemptydirs="true" >
      <fileset basedir="${zip.dir}">
        <include name="*" />
        <include name="**/*" />
      </fileset>
    </zip>

    <!-- Zip hotfix -->
    <zip zipfile="${root.dir}\hotfix.zip" includeemptydirs="true" >
      <fileset basedir="${package.dir}">
        <include name="*" />
        <include name="**/*" />
        <exclude name="package.xml" />
      </fileset>
    </zip>

These are all small snippets of the build script. I recommend you open up the nant.build file and investegate it further, it is a fantastic tool for automating anything and for handling the tedious task of maintaining a package manifest it is a real time-saver.

Moving forward

With nant, codeplex and teamcity in place, we are now ready to start adding features, we don't have to worry about spending time on releasing packages and can move forward much faster.

Nightly builds will be available on http://nightly.umbraco.org/Blog4Umbraco/ both as installable package and a hotfix.

The source code is on codeplex: http://blog4umbraco.codeplex.com/ where you can also add suggestions, snippets and post bugs

Tutorials on nant can be found here http://nant.sourceforge.net/release/latest/help/introduction/ and here http://blog.jpboodhoo.com/NAntStarterSeries.aspx for those who want to learn more.

 

End of the first chapter of the umbraco christmas calendar! I promise the next chapters will not be this long or filled with nant tasks xml.

Christmas Calendar 2009 – a better blog package

Tuesday, December 01, 2009 by Niels Hartvig

At the little Umbraco HQ we've been discussing how we could make a Christmas Calendar that would work throughout December. As we're busy working on v4.1 it couldn't be too ambitious and the idea was to offer Contour at a random discount between 1-24EUR that changed daily. That was until Pete Brown Twittered this:

Picture 13

If there's one thing my parents always have told me, it's to respect anyone who has a Commodore 128 as their Twitter background, so that's what we're going to do and that's what the Christmas Calendar 2009 is all about:

Making an awesome blog4umbraco version 2 with daily progress

The dogme manifest for this calendar is very simple: One guy in the HQ have to spend an hour every day working on the package with 45 minutes devoted to dev/design and 15 minutes on blogging about the progress. When we reach December 24th this means that not only will we have a stunning free blog package for Umbraco, but we have also shown how fast it is to build and improve things in Umbraco and how suitable Umbraco is for agile team development.

Stay tuned as Per will blog about setting up our build and package environment for this project.

Merry Christmas!

Umbraco Contour is out

Monday, November 16, 2009 by Niels Hartvig

contour

Contour - our brand new form designer that makes creating contact forms, entry forms and questionnaires just as easy as editing content - is finally released. It's the best thing we've ever made and it's also the most relevant product we've shipped.

Until this date making online forms with Umbraco have been either developer work, hacks using AutoForm/Doc2Form or other creative but odd solutions. Odd because the techniques used were never meant to deal with gathering form data.

Contour is designed for that purpose only. It has taken nearly three years to come up with the perfect balance where simplicity and functional depth goes hand-in-hand - just like Umbraco. But over the summer the pieces came together and I'm really sure you'll love it. Whether it's simple contact forms, huge questionnaires or making "web2.0'ish" functionality like user-generated content it got you covered.

Contour is also the first product that follows our new pricing strategy where you don't need to purchase Umbraco PRO. Contour is priced at just EUR199, but the rest of the year we're giving it away for a mere of 99EUR.

That was a lot of words. Tim Geyssens have done a great job of showing it instead - enjoy:

You need to have Flash and javascript enabled to use this video tutorial

* and yes, Contour is the artist formerly known as UmbracoForms!

Umbraco Contour RC1 is out

Friday, November 06, 2009 by Per Ploug Hansen

Thanks to our fantastic team of beta testers, we have crossed off a huge amounts of bug-fixes and enhancements on the Umbraco Contour todo list. 

So today we're releasing the first RC of Umbraco Contour (the software formerly known as Umbraco Forms) 

The RC will have same availability as the betas: only people in the Contour Beta Program and Pro Subscribers can get a valid beta license.

The list of changes can be found here as well as a list of nightly builds

To update you current Contour installation, you can use this zip file which should just be unzipped to the root of your website (it is not a package) 

And to start from scratch download the Umbraco Contour RC1 package here

You still need a license key to try this out, all Pro subscribers can get a key instantly by contacting us.

Again, thank you all for the bug-reports and feature suggestions

Tim, Niels and Per

edit: typos and clearifying availability

Umbraco 4.1 Beta 1

Monday, October 19, 2009 by Aaron Powell

Well a few months ago the core team had a discussion, and we decided to set ourselves a deadline for the Umbraco 4.1 Beta 1 release.
There was a lot riding on this release, Niels was going to have to listen to Ole Erling if the commitments weren't made.

But more importantly it would have been another delayed release, something which we didn't want.

So with some hard last minute work I'm proud to announce that Umbraco 4.1 Beta 1 is available for download and testing.
*pauses for dramatic effect*

Grab a copy and get your testing on! (Usual disclaimer about don't use on a production site applies)

If you haven't been following our twitter feeds and are unsure what to expect from this release I've compiled a list of new features/ imporved features which are available in this release:

  • .NET 3.5 SP1 Framework required
  • Umbraco tree replaced with jsTree 0.99a
  • Umbraco tree state remembered across applications
  • New client & server API for interaction with Umbraco and the tree
  • Client Dependency for JS and CSS
  • Umbraco Examine as the default back of office search provider, using Lucene as the indexer
  • Syntax highlighting editor for CSS, JS, Templates, Python and XSLT
  • Improved data layer with child node interaction
  • Removal of a lot of legacy items (classes, old data types, unused pages)
  • LINQ to Umbraco with NodeDataProvider
  • Improved Media Picker data type
  • Image Cropper data type
  • Media recycling bin
  • New event fired before a document is created (Newing event)
  • Improved Document API with an OptimisedMode constrictor (new Document(bool optimisedMode, int id);) which allows for the Save method to cancel a save before database writing occurs (not implemented on the editContent.aspx page though)
  • Documents can now be interacted with via named arguments (eg: myDoc["property_alias"])
  • Dynamic Tree proxy for dynamically creating Umbraco Applications
  • Macro Container Data Type
  • Umbraco now launches from /umbraco/ 

We are all very excited about this release, there's some awesome new features in it and some existing features have been drastically improved.

When you're testing if you find any questions ask them on the Umbraco Forum in the 4.1 section and if you find anything that is an out-right bug feel free to post it straight to the Umbraco codeplex site.

Happy testing :)

Update - Forgot one feature, TinyMCE now has a spellchecker. This is now part of the core not a package like it use to be.

Another day at the office

Sunday, October 11, 2009 by Chris Houston

I love getting feedback, but why bother spending time getting in touch when being anonymous. It's like the person sending this almost knew that (s)he was asking a little too much ;-)

Picture 49

The irony however was that the person missed the opportunity of getting free umbraco.tv forever with just twenty minutes.

If you'd like to get some free umbraco.tv content, there's always the videos on Document Type basics or User Control basics.

Awesome guide for Umbraco newbies

Monday, October 05, 2009 by Chris Houston

I love when people act. It's not the easiest thing in the world. In fact it seems like the current trend these days is not even bother to tell someone that you're unsatisfied but rather just tweet "xxxxx sucks bigtime". Which is kind of odd as - I like to think that - most people don't do things to annoy you. So when something isn't right, there's a big chance that being constructive and friendly will get you much further than an angry tweet.

So when I opened up my laptop this evening and saw a ton of retweets of Lee Messenger's announcement about of a newbie guide to Umbraco I got really excited. When I followed the link and read his work it made me really happy. What a great resource and what a wonderful, constructive way of helping others. I'm sure that already by the time you read this, the effort made by Lee has helped people save more hours than it took collecting and sharing the information. Even though it's a lot.

Imagine what could happen if we all took the time to follow Lees example. If we wrote the tutorial we missed a couple of months back, if we submitted a great bug report, shared a cool project or took the time to help others in the forums the way we got help last year. Of course we'd disappoint the number of people who still like to say that Umbraco has a steep learning curve and that there's no documentation - even more than the disappointment they'd feel if they read Lees post.

But that's a tradeoff I can live with. Let's get to work - there's karma waiting!

Umbraco Concierge 2.0 Released

Thursday, September 10, 2009 by Chris Houston

Today we're releasing the new version of one of the tools in the Umbraco Pro bundle: Concierge. This is a major upgrade to the tool helping you keep track of your website.

Get an overview of what it does on umbraco.tv

Tracking changes and dependencies

Concierge is a tool for keeping track of the different components in your website. It helps you keep track of which components are currently not in use and can be safely deleted. It spots the connections between components and helps you determine if a change might break an existing page and see what areas needs testing after a change is made.

Reporting and logging

Concierge helps you digest the statistics and data surrounding your website. Search the application log for details on the health of the website. Or use the reporting capabilities to build a view of specific data about your website.

Check-in and Check-out

Concierge can help your editors workflow, by enabling locking of content and media items. Any editor can lock a document for exclusive editing and ensure that ongoing work isn't edited or deleted. Concierge also provides a central overview of all components currently locked for easy administration

Make it your own

Both the documentation section and the reports can be extended to include your own data. Concierge 2.0 comes with an API for adding any source of data to your documentation or as a report.

Available today

Our pro customers can download Concierge 2.0 on their profile today along with API documentation. It is a free upgrade to all existing Pro subscribers.

Package repo updated with the best from our.umbraco.org

Monday, August 17, 2009 by Chris Houston

The project page at our.umbraco.org is rapidly being filled with some excellent packages (even looks like we'll need to split them in categories, since the projects list is getting crowded).

Since we now have a clear overview of the projects and their value for the community (don't forget to hit the 'thumbs up' if you like a project) we'll be updating the package repository more often.

For our first update we've added 5 of the best rated (and stable) projects.

You can now download and install these directly from the integrated package repository.

our.umbraco.org maintenance

Wednesday, August 05, 2009 by Chris Houston

At around noon today, we will take our.umbraco.org offline for a couple of hours to perform some maintenance upgrades and bug fixes, do not panic, we will be right back.

We know this is hard on some of our community members, so here is a list of suggested things to do instead of refreshing our.umbraco.org every 10 seconds:

I’m coming for the UK Meetup next week

Wednesday, July 29, 2009 by Niels Hartvig

I'm jumping a plane on Wednesday for London to join the exciting Umbraco UK Meet up arranged by Darren Ferguson and kindly hosted by LBi.

I'll do a recap of the most important things announced at the CodeGarden 09 conference as well as co-host a session with Darren where we're going to build a little crazy app live in 30 minutes.

The meet up is next Thursday (the 6th) and is a great chance to learn about Umbraco as well as experience the worlds friendliest community crowd. Don't miss this and as LBi just made it possible for us to be 55 instead of 35 people, there's room available again!

So what are you waiting for - sign up (it's free!) and let's talk next week! There'll be beer and prizes too!

London Meetup, Thursday 6th August

Monday, July 20, 2009 by Per Ploug Hansen

Since Codegarden09 in Copenhagen Darren Ferguson and the UK umbraco community have been busy arranging an Umbraco UK meetup.

The event will take place on August 6th in London and will be kindly hosted by LBi - one of the largest full service digital agencies. LBi are kindly donating the venue free of charge!

There is an event wiki page with all of the details here. You can sign up to attend by leaving your details on this wiki page or by filling out this contact form.

Spaces are limited so please don't leave it until the last minute.

Help required!

Although most of the practical details are in place there is plenty the Umbraco community can do to support this event.

Give a presentation

If you think that you have a compelling talk/presentation to give at the event, please leave some details on this wiki page or fill out this form.

Tweet/Blog/Email your friends

Be sure to let any UK Umbraco users know about the event by sending links to the wiki pages above. Use the hashtag #umbracouk.

Non Umbracians are welcome, there will be plenty of beginner focused material. If you know any CMS professionals who may be interested in Umbraco then get them to come along.

Come along prepared to participate

We don't want the meetup to be a bunch of guys standing up and talking we want to have group sessions and may be some open space. Come along prepared to speak up, with questions and topics around Umbraco in mind.

Finally

Without community partcipation this event will just be some tech guys in a room.

By contributing to the wiki pages above and throwing your suggestions into the ring we can make it something much more than that.

Win tickets for CodeGarden 09 :)

Wednesday, June 10, 2009 by Niels Hartvig

Do you want to get to CodeGarden for free and do you have a cool site or package that you want to show during the open space, then you're in luck.

Microsoft have sponsored 2*2 tickets and all you need to do is to submit a three paragraph description (inclusion of screenshots is a bonus here) of what you'd like to show and mail it to me.

The deadline is the 15th of June 12.00 GMT+1 and the winners will be selected by the hard but righteous jury which is me and Daniel Frost from Microsoft.

Impress us, come to CG for free and get famous :-)))

Umbraco 4.0.2.1 is released

Wednesday, June 03, 2009 by Niels Hartvig

Unfortunately there was an issue with linking in the WYSIWYG editor in yesterdays release which we completely missed, so we've fixed that this morning and updated the release so we now have an Umbraco 4.0.2.1 aka the "digit edition".

The update service have been updated to automatically notify existing Umbraco 4 installations about this update.

Thank you to our wonderful community who found this error and reported it quickly and sorry for any inconvenience.

Umbraco 4.0.2 is out and so is an upgrade guide

Tuesday, June 02, 2009 by Niels Hartvig

Thanks to great response from the community I was able to make the release of 4.0.2 come today. I fixed three bugs in the beta and I've updated the change log.

Introducing the Upgrade Guide

I was finally able to make the first version of an Upgrade Guide that shows you how to do both a patch upgrade as well a major upgrade of Umbraco. I've tried to gather all the details that have caused headaches, but as this is a v1.0 of the guide, I'd love feedback and ideas for changes.

You can download the upgrade guide on Codeplex.

Umbraco v4.0.2 beta released

Sunday, May 31, 2009 by Niels Hartvig

Finally - Umbraco version 4.0.2 is ready for testing (this is not marked as a stable release yet, but it's likely to be within a couple of days). Please report any bugs you find in the Issue tracker. Only bugs related to this release will be fixed, so no need to report any issues already added in the tracker, please vote them instead.

This is a stability release fixing 43 bugs. Most importantly the horrible encoding bug has been fixed, but also a lot of minor quirks reported by our fabulous community via http://codeplex.com/umbraco has been fixed.

Most work has gone into the way Macros are inserted and edited in TinyMCE, so hopefully this should feel much more stable, especially if your macros are rendered in the editor. The Membership Provider has also been fully implemented, so it now supports the full featureset of the MemberShipProvider APIs.

We've also ensured that all events in Umbraco are now correctly wired up - there have been quirks with the BeforeUpdateDocumentCache as well as the Macro save events.

Full change log on the download tab.

We expect v4.0.2 to be released during the first week of June.

UmbracoCast no 9 - the family grows...

Monday, May 25, 2009 by Niels Hartvig

Watch this new UmbracoCast to see that our little family will finally get a new member on August 1st 2009. But you'll need to watch three minutes of Per Ploug Hansen and yours truly mumble about CodeGarden 09, Umbraco 4.0.2 and Paul Sterlings US events first.

Missed any previous UmbracoCasts? Now we finally have an archive of all old videos.

Umbraco Events in the US

Monday, May 18, 2009 by Niels Hartvig

While the US and Canada have the largest number of Umbraco users the number of Umbraco related events here is quite low relative to our European counterparts.  Recently there was the Tulsa Umbraco Users Group meeting, and last year Codegarden US 08, but that's about it.  Starting what we hope will be a much more frequent schedule of Umbraco sessions, events, training, and meetups here is where you can find Umbraco in the next few weeks:

We are very excited to tell more .Net and web developers about Umbraco.  Like many of us who use Umbraco daily already know, once you realize the limitless flexibility and ease of use it's a rare-day you return to another framework.

In each of the appearances above, look for North America's very own Nabaztag Umbraco Rabbit.

Hope to see you at one of these events and, if you know of other events that will benefit from learning more about Umbraco, let us know.  If I don't see you at one of these, I hope to see you at CodeGarden 09.

-Paul

Umbraco Courses in June - new dates

Monday, May 11, 2009 by Niels Hartvig

UPDATE: I was a little too fast on the trigger yesterday - June 1st is a bank holiday in Denmark, so the Level 1 course will start on the 2nd and not the 1st!

By request we'll run the highly praised Umbraco courses again on June 2-3rd and 4-5th.

The courses will follow the very same model that have made the last ten rounds of courses a massive success, and just like last it'll focus entirely about Umbraco 4!

So we'll look at Masterpages, XSLT Debugging with Visual Studio, the new Event model, Canvas Editing, Membership Providers, Package creation and many of the other improvements that have made Umbraco 4 a milestone in Web CMS. By attending the course you'll be among the first to become experts and certified on the new platform.

The agendas for the courses are as follows:

June 2-3rd: Level 1 - implementing websites using umbraco:

  • Understanding the umbraco basics - Boost/Nitro, Document Types, Templates and Macros (including usage of the new Masterpages functionality)
  • Creating a simple website from scratch
  • Understanding XSLT - creating a news "module"
  • Creating multi-language websites including coverage of Dictionary Items and Languages
  • Advanced properties: Re-use of properties and recursive usage of properties
  • Two-way feedback using AutoForms and Notifications
  • Optimizing markup for Canvas Editing
  • Great Packages: Implementing full-text searching and mail forms

June 4-5h: Level 2 - umbraco for .NET Developers, extending and integrating solutions:

  • Usage of .NET User Controls with umbraco
  • Debugging XSLT and .NET Controls with umbraco and Visual Studio
  • In-depth explanation of the umbraco object model and usage of the umbraco presentation APIs
  • Creating, importing and modifying content from .NET using the API
  • Usage of AJAX and umbraco
  • Extending XSLT with custom .NET classes
  • Custom event handling in umbraco using the brand new event handlers in Umbraco 4
  • How to integrate legacy authentication systems using Membership and Role Provider

The registration is open and the first seats are already booked - as always we encourage you to register fast as the past courses have all sold out (and as mentioned the last one in 24 hours!).

I'll be speaking in Århus on the 29th

Friday, April 24, 2009 by Niels Hartvig

I'm very excited that I've been invited by the best .NET User Group in Denmark - ANUG - to speak about Umbraco.

It's this Wednesday (April 29th) and as the fine folks have given me a whole evening I'll bring plenty of demos (one of them will feature a lottery where you can win an Umbraco CodeGarden 09 ticket or one of the famous limited edition Umbraco T-shirts).

You'll need to sign up using Facebook (WTF? ;-)) on ANUGs website.

And oh, one last thing... I'll be speaking Danish...

New videos and pricing on umbraco.tv

Thursday, April 23, 2009 by Niels Hartvig

We're really happy here at the Umbraco HQ as we *finally* managed to activate subscriptions on the umbraco.tv. This means new low prices to get started and at the same time we're back at adding a lot of exciting new content. But let me start with the best news:

New low price: 19EUR / month, opt-out and in whenever you want!

That's right, getting started with umbraco.tv and more than five ours of videos by me and Per Ploug Hansen will only set you back 19 EUR (~25USD) and you can stop your subscription at any time.

New videos on XSLT Extensions - more videos coming

To celebrate the re-launch we've added two new videos on XSLT Extensions that'll teach you the basics of XSLT Extensions, how to create them as well as more advanced topics such as accessing SQL data from XSLT including sorting and paging data in your presentation layer.

More trial videos and previews

Starting with the two new XSLT videos we'll be adding free three minute previews of the videos as a supplement to the two free full videos on User Controls and Document Types. This gives you a safe way to see if you find it worth the cash.

Existing subscribers will get their periods doubled

For all our existing subscribers - no matter when you purchased the subscription - we'll start their subscriptions on May 1st and we'll double the period. So if you've purchased three months you'll get six months, etc. We really appreciate your early support on this product.

So what are you waiting for - start your subscription today and experience that the lack of documentation is a myth ;-)

Calling SEO experts - 301 or 302 for RSS package

Tuesday, April 21, 2009 by Niels Hartvig

Thanks to Søren Sprogø from Afdeling18 we've been aware that there might be a problem for correct Google indexing of certain pages if you use the RSS Community Package.

According to Søren this is due to Google using the guid attribute (ie. /26156) from the RSS to index the Umbraco pages but it detects it as duplicate content if already have indexed the content using the niceurl (ie. /blog/2009/4/7/how-to-migrate-umbraco-40-to-iis-7-and-aspnet-35).

What's the best solution - 301 or 302 redirects?

The solution to this is to make Umbraco detect if there's an incoming guid link (ie. yoursite.com/pageid) and then do a redirect and I'll look at implementing this for 4.0.2 (with the option of disabling it).

The big question is then - should it be a 301 redirect (permanent) or a 302 redirect (temporary). In my logic it should be a 302 as the whole point of a guid link is to ensure it won't change (and the id won't change, but the nice url might if a page title is changed). Søren argues that to fix the Google problem it needs to be a 301, which would be very sad as the whole point of ensuring links over time is then lost.

I've looked at how Wordpress handles this and it seems that hosted blogs (on wordpress.com) uses 302 redirects, while many Wordpress installs uses 301.

So calling all SEO/Google/RSS experts - what should we do?

Our contact form has been broken

Saturday, April 11, 2009 by Niels Hartvig

If you've tried to send us an e-mail since Tuesday, it has unfortunately ended up in the dark nothing. When we moved servers this week our mail server has been configured wrong and as a result our contact form have been failing silently.

This means that we've never gotten your contact enquiry if you've sent it through our contact form on this website!

We sincerely apologize if you've tried to get in touch with us and when we haven't gotten back to you it's not a result of arrogance, but lack of server skills.

We really appreciate if you would contact us again.

How-to migrate Umbraco 4.0 to IIS 7 and asp.net 3.5

Tuesday, April 07, 2009 by Per Ploug Hansen

Last night umbraco.org was migrated from our tired old windows 2003 server to a new windows 2008 monster server. This meant we had the opportunity to migrate to a asp.net 3.5 setup with integrated pipe-lines using IIS 7. It can seem like a daunting task, but in reality it is a simple operation. This is the walkthrough of how we moved umbraco.org.

Files and database

To make the transfer as fluent as possible we setup a new site next to the old one, and copied over all the files. We backed-up the database, but otherwise kept it where it was, as it was already upgraded to 4.0 and no changes are needed for the database. So we now had two identical sites: www.umbraco.org running asp.net 2.0 which point at the umbraco4Db database, and new.umbraco.org pointing at that same database. The files on both sites are identical at this point.

Websites and application pools

For the new site, we setup a new website in IIS7, and a separate Application Pool, setting it to framework asp.net 2.0 and using integrated pipeline.
(note: asp.net 3.5 is an extension of 2.0 so it has no separate framework settings)

Configuration files

Despite its complexity, umbraco.org is still an unmodified umbraco installation. So the only configuration file we needed to change was the web.config, if you have a more custom setup, your results might vary.

To upgrade the web.config to an asp.net 3.5 compatible version, go to the umbraco source repository and open aspnet35.config, which is located here:

http://umbraco.codeplex.com/SourceControl/changeset/view/48966#742920

Use this file as a base for your new web.config, copy over custom configuration from the old web.config, such as custom sections, umbracoDbDNS and other custom appsettings, the MemberShipProvider sections, RoleProvider settings etc.

Especially notice if umbracoMembershipProvider (under membership) has a passwordformat ="hashed", this differs between version 4.0 and 4.0.1.

When you've synced the changes between your old web.config and the file from the codeplex repository, you have an asp.net 3.5 compatible configuration file which can run on integrated pipeline. This new web.config file is placed in the root of the new website and testing can begin.

Directory urls and authentication

if you use extensionless urls / directory urls with umbraco as well as authenticating users on your website, you need to add one additional setting to the web.config.

under <system.webserver> all umbaco's httpmodules are listed. Due to the way IIS process extensionless urls, you need to add: runAllManagedModulesForAllRequests="True" to the modules element, så it looks like this: <modules runAllManagedModulesForAllRequests="True">

That is all there is to it, copy over files, keep database connection, upgrade web.config file to a asp.net 3.5 compatible version, and you're done.

Things to keep in mind

Make sure that your folder permissions on the new site are setup to work with IIS 7 and your application pool.

Don't do this upgrade on a live site, backup your files and migrate it to a new website, when the migration is done, it is very easy to simple turn off the old site and change the hostnames on IIS7.

You don't need a new database, as no database changes are needed to switch to IIS7 and asp.net 3.5

We'll be moving umbraco.org tonight

Monday, April 06, 2009 by Niels Hartvig

We'll be moving the umbraco.org website to new ultra fast servers tonight (22.00 - 24.00 GMT+1) so expect a little downtime as DNS will update.

This will only affect umbraco.org and umbraco.tv. The forum will continue to be online.

Exciting Umbraco jobs

Wednesday, April 01, 2009 by Niels Hartvig

A sure sign that Umbraco finally is going mainstream is the growing number of jobs available for talented Umbracians. This week I've spotted two interesting job posts that I'd like to share:

  • CondeNast (Wired, Vogue, CG) is seeking .NET/Umbraco dev . If you're living near London and wants to work on some of the largest scale Umbraco sites, you should definitely check this one. The team is cool (they got people in the Umbraco core team too) and the challenges are massive. 
  • Twins seeking Umbraco specialist. If you're living in Denmark, one of the most prominent Umbraco Certified Solution Providers are expanding their Umbraco team (Danish) .

Brilliant umbraco hosting provided by FAB-IT