How to Import RSS (and other) data

Written by Mark Burnham

Importing data into Umbraco

It's really easy to import data of all sorts into Umbraco. First of all, to import RSS feeds, you should read Kaspar's article on importing Flickr images:

http://kasperb.dk/2006/6/26/display-your-flickr-images-on-your-umbraco-driven-website.aspx

When I first read this, a number of lights went on, and I realized it was going to be easy to import any other kind of data into Umbraco. Basically, you import whatever data you want as XML,

and transform it exactly like Kasper does, with XSLT.

There are other methods. You can write a library as is described here:

http://blockquote.be/2006/08/09/extending-umbraco-with-a-library/

For me, it's easier and more flexible to output the data with a .NET Web Form and use umbraco.library:GetXmlDocumentByUrl to import it into your XSLT.

If your data source is SQL Server, you can use the "FOR XML" clause in your queries. You should definitely read up on this, because it will save you a bunch of time. Get the basics here:

http://www.sqljunkies.ddj.com/Article/296D1B56-8BDD-4236-808F-E62CC1908C4E.scuk

I'll give you a quick example of importing data from an AdventureWorks database (download the source from here) :

1) create a new Web Form in Visual Studio. Call it ourData.aspx. To make things simple, we'll do all the work in the Page_Load function:


Hide Code [-]

protected void Page_Load(object sender, EventArgs e)
{

string sqlStr = "select top 30 Title, FirstName,LastName,EmailAddress FROM Person.Contact For XML RAW('Person.Contact'),ROOT,ELEMENTS";

string connStr = "Server=(local);Database=AdventureWorks; User ID=umbracoUser;Password=pass;";


using (SqlConnection cn = new SqlConnection(connStr))

using (SqlCommand cmd = new SqlCommand(sqlStr, cn))
{
cmd.Connection.Open();
using (XmlReader xr = cmd.ExecuteXmlReader())
{
xr.Read();

while (xr.ReadState != System.Xml.ReadState.EndOfFile)
Response.Write(xr.ReadOuterXml());
}
}
}


{..} Click Show Code

Make sure to change the database connection string to whatever you need for you installation. You should be able to load this page in a browser and see a nice dose of XML. If you can't see XML, there's something wrong. NOTE: When you get more complicated data imports, you can always see the XML by loading your "data import page".

2) Copy this Web Form to the /umbraco directory of your installation.

3) Now, in Umbraco, create a new XSLT file and macro that contains the following code:


Hide Code [-]

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:Stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library"
exclude-result-prefixes="msxml umbraco.library">


<xsl:output method="xml" omit-xml-declaration="yes"/>

<xsl:variable name="url" select="'http://localhost/umbraco/ourData.aspx'"/>

<xsl:template match="/">

<xsl:variable name="pagexml" select="umbraco.library:GetXmlDocumentByUrl($url)" />

<!--<xsl:copy-of select="$pagexml"/>-->
<ul>
<xsl:for-each select="$pagexml/root/Person.Contact">
<li><xsl:value-of select="Title"/>&nbsp;<xsl:value-of select="FirstName"/>&nbsp;<xsl:value-of select="LastName"/></li>
</xsl:for-each>
</ul>
</xsl:template>

</xsl:stylesheet>



{..} Click Show Code


2 items of note here:

a) the URL path has to be complete (use "http://")

b) You can always see what is being imported by using the xsl:copy-of function.

4) Place the macro you created in step 3 anywhere you like and the data will appear. That's it!

Hopefully you can now see how easy it is to import data into Umbraco. Have fun!!

Get Over 1000 Templates In Umbraco

Written by Richard Weeks

Get Over 1000 Templates In Umbraco

In this article, I am going to show you how to get access to a huge range of cross-browser CSS-template layouts in Umbraco using one CSS file and two Umbraco templates. No, that's not a typo!

In the interest of keeping things brief, this article assumes you have a fresh working installation of Umbraco. I also assume you have at least a working knowledge of how templates work in Umbraco.

First of all, download the latest
Yahoo User Interface (YUI) from Yahoo!.

Extract the archive and copy "reset-fonts-grids" from the Build directory. That's the only file you will need for the purposes of this article but I strongly recommend you delve into the documentation regarding the rest of the library.

Again, to keep things simple, we won't bother copying this file to Umbraco. I like to put things like this in their own directory, say, /Assets/Styles/YUI/.

Specifying Document Widths

Next, we need to start creating our templates. First, we create our page templates. These basically set how wide the content is on a web page and how it reacts to browser resizing. These are set by applying a specific ID and are as follows:

#doc - 750px centred (good for 800x600)
#doc2 - 950px centred (good for 1024x768)
#doc3 - 100% fluid (good for everybody)
#doc4 - 974px fluid (good for 1024x768)

There is also another custom width:

#doc-custom - an example of a custom page width

I'll just be using the first 4. These provide for the vast majority of use cases.

I created a base template, which looks like this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html>
<head>
<title></title>
<link rel="stylesheet" href="/Styles/YUI/reset-fonts-grids/reset-fonts-grids.css" type="text/css">
</head>
<body>
<div id="" class="">
<div id="hd">Header</div>
<div id="bd">Body</div>
<div id="ft">Footer</div>
</div>
</body>
</html>

Specifying Document Templates

Now, this is where it gets interesting. Look at this part of the code:

<div id="" class="">

This is our placeholder for one the IDs as specified above. Putting one of those IDs into this template will make it conform to that page width. That's not the whole story though. Note also the class attribute. The class allows us to further specify the layout of our page. We can add a range of class names that further divide the page within the body region. These are as follows:

.yui-t1 - Two columns, narrow on left, 160px
.yui-t2 - Two columns, narrow on left, 180px
.yui-t3 - Two columns, narrow on left, 300px
.yui-t4 - Two columns, narrow on right, 180px
.yui-t5 - Two columns, narrow on right, 240px
.yui-t6 - Two columns, narrow on right, 300px

What about if we just want one column? Well, this has a class attribute of .yui-t7.

To accompany each of these templates, we have some code to add between our body. In terms of Umbraco, the page width document serves as our master template and the template that provides page columns are sub templates. Here are the templates for t1 to t6 (remember these go between #bd):

<div id="yui-main">
<div class="yui-b">
<div class="yui-g">
<!-- YOUR DATA GOES HERE -->
</div>
</div>
</div>
<div class="yui-b">
<!-- YOUR NAVIGATION GOES HERE -->
</div>

No, actually, that's it! Yes, you get 6 templates for the price of 1!

The one-column template is very simple:

<div class="yui-g">
<!-- YOUR DATA GOES HERE -->
</div>

Making YUI Grids Work With Umbraco

Let's make our templates more Umbraco friendly.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd%22<div id="hd"></div>
<div id="bd">

<?UMBRACO_TEMPLATE_LOAD_CHILD/>

</div>
<div id="ft"></div>
</div>
</?ASPNET_FORM>
</body>
</html>

This is perhaps the quickest implementation. What we are saying here is there will always be two properties given to any page created. These will supply the document ID and Class. You would create these document properties when you create the accompanying Document Type entry in Umbraco.

Advanced Template Selection

If you don't want to have to supply these details every time a page is created, you could bind their values to a Macro and use some XSLT to automatically choose the appropriate attribute values, e.g.:

<div id="<?UMBRACO_GETITEM field="templateId"/>" class="<?UMBRACO_GETITEM field="templateClass"/>">

Becomes...

<?UMBRACO_MACRO macroAlias="GenerateDocType"></?UMBRACO_MACRO>

The Macro has no parameters and simply gets the results of a XSL transformation:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:Stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="
http://www.w3.org/1999/XSL/Transform%22
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library"
exclude-result-prefixes="msxml umbraco.library">

<xsl:output method="xml" omit-xml-declaration="yes"/>

<xsl:param name="currentPage"/>

<xsl:template match="/">
<xsl:choose>
<xsl:when test="$currentPage/@nodeTypeAlias = 'YOUR_NODE_TYPE_ALIAS'">
<xsl:call-template name="doctype">
<xsl:with-param name="document">YOUR_SPECIFIC_ID_VALUE</xsl:with-param>
<xsl:with-param name="template">YOUR_SPECIFIC_CLASS_VALUE</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="doctype">
<xsl:with-param name="document">YOUR_SPECIFIC_ID_VALUE</xsl:with-param>
<xsl:with-param name="template">YOUR_SPECIFIC_CLASS_VALUE</xsl:with-param>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template name="doctype">
<xsl:param name="document" />
<xsl:param name="template" />
<xsl:text disable-output-escaping="yes"><![CDATA[<div id="]]></xsl:text>
<xsl:value-of select="$document"/>
<xsl:text disable-output-escaping="yes"><![CDATA[" class="]]></xsl:text>
<xsl:value-of select="$template"/>
<xsl:text disable-output-escaping="yes"><![CDATA[">]]></xsl:text>
</xsl:template>

</xsl:stylesheet>

The caveat of the first method is that you must supply the id and class attribute values with every page, for the second you must remember to create an entry in the XSLT to supply the appropriate values.

To form your pages, create a template with the template code:

<div id="yui-main">
<div class="yui-b">
<div class="yui-g">
<!-- YOUR DATA GOES HERE -->
</div>
</div>
</div>
<div class="yui-b">
<!-- YOUR NAVIGATION GOES HERE -->
</div>

Make the document width template the master and you're good to go - lots of possible combinations from just two templates and one CSS file!

Wrapping Up

This article really only touches on the power and flexibility of YUI Grids. If you are interested, visit the YUI developer site and particularly look at nested grids. Adding these will give you the ability to create thousands of templates using very little code. YUI Grids can be very confusing at first but perseverance wins. Naturally, the examples above keeps everything basic but I hope you can see with the addition of nested grids, your templates within Umbraco could get very creative indeed.

Note that of course, nothing is perfect. YUI Grids are an amazing achievement but like all frameworks, subject to bugs and bug fixes! YUI has an established developer community and you can find details of this for help, when needed, on the YUI site.


Debugging

Debugging your Umbraco usercontrols

If your newly built usercontrol fails to work, you have several options to debug your control:

If you add ?umbDebugShowTrace=true to the URL, you'll be able to see a complete stack trace, showing all parts of the communication between Umbraco and your usercontrol. The actual error(s) is marked with red.

You can also see the elements being passed to a macro by appending
?umbDebug=true to the URL in your browser

Creating and Using an Action Handler

What is an action handler?

An action handler is a piece of code (a proper class) that gives you the possibility to react on the actions performed by any user in the content tree. For example, you can perform some actions in each node in the tree content is published. An example will explain in detail:

For a concrete example, I took the position that umbraco has the build in mechanism to define the values of properties Devault new content. The new action will Handler Devault write values to properties of a document type defined.

How to implement an action handler

You can implement your own action in any Handler. NET as a class. In this example, I'll do a class project own library to show how the complete cycle.

1. So in VS.NET create a class library project. Give it a name of your choice. In this example, the name of the project is TH.Umb.Sandbox.Library.

2. Add a new class and give it a name of your choice. In this example, the name of the class is DefaultValueHandler

3. Add references businesslogic.dll, and cms.dll interfaces.dll from the bin folder umbraco.

4. Let class implements the interface umbraco.BusinessLogic.Actions.IActionHandler.

5. Implement HandlerName the function that returns the name of this action handler.

6. Implement returnAction the function that defines the actions to which the action handler will react.

7. Last but not least the implementation of the Run function that does the job. Here you can set this code should be executed on this measure.
Thus, at least, you should have a code like this:




using System;

namespace TH.Umb.Sandbox.Library
{
public class DefaultValueHandler : umbraco.BusinessLogic.Actions.
IActionHandler
{
string umbraco.BusinessLogic.Actions.IActionHandler.HandlerName()
{
return "TH.Umb.Sandbox.Library.DefaultValueHandler";
}

umbraco.interfaces.IAction[] umbraco.BusinessLogic.Actions.IActionHandler.ReturnActions()
{
return new umbraco.interfaces.IAction[] { new umbraco.BusinessLogic.Actions.ActionNew() };
}

Boolean umbraco.BusinessLogic.Actions.IActionHandler.Execute(
umbraco.cms.businesslogic.web.Document documentObject,umbraco.interfaces.IAction action)
{
if (documentObject.ContentType.Alias == "th_sandbox_defaultvaluetest")
{
try
{
umbraco.cms.businesslogic.property.Property p =
documentObject.getProperty("DefaultValueProperty");
if (p == null) { return false; }
p.Value = "This is the default value set by an action handler";
documentObject.Save();
}
catch (Exception)
{
return false;
}
return true;
}
else
{
return false;
}
}
}
}





A word from the function of returnAction: The return variable is an array of actions. Thus, you can come back to action. Therefore, you can manage more than one type of action with an action Handler.

A word to the execution of the function: The first item you get from this function is called documentObject and it is the document upon which this action is the stage. The second parameter is the action that is the stage. So if you defined an action returnAction you can delay the action you handle at this time.

How to install the action handler

The installation is done by copying the dll in the bin folder umbraco:

1. First build the project release (right click on the project, select new build).

2. Then go to the project file to select the DLL from the bin / output folder (in this case, select the TH.Umb.Sandbox.Library.dll) and copy it into the bin folder umbraco.

That's it. Now the manager is installed and will perform all the actions you have selected.

Supported Actions

•Assign Domain
•Audit
•Copy
•Delete
•Disable
•Empty Transcan (new in v3)
•Export
•Import
•Move
•New
•Notify
•Package
•PackageCreate
•Protect
•Publish
•Quit
•Refresh
•RePublish
•Rights
•Rollback
•Save
•SendToTranslate (new in v3)
•Sort
•ToPublish
•Translate (new in v3)
•UnPublish
•Update