Why Snapshot?

by Aaron Powell 18. May 2010 02:53

In my previous post I introduced a new tool we’re working on here at TheFARM called Snapshot which is a content export engine for Umbraco.

When doing that post I knew that I was going to have to write this one anyway, people were inevitably going to ask “But why?”

I was hoping to have time to do it before anyone did, but alas I was wrong :P.

Here’s a few scenarios which Snapshot aims to be useful in.

The “We Don’t Need a CMS” client

We’ve all had these, it’s “just a small site”, “we don’t change content”, etc. But in the back of your mind you know they will change content and if it’s a static site you’ll have to get the devs to do it. Well with Snapshot you can create a CMS but the client doesn’t have to know.

Shared hosting, virtual folders and medium trust

Yes Umbraco can run in Shared Hosting, yes with 4.1 it can run in a virtual folder and medium trust. But 4.1 isn’t out yet. So you could look at the medium trust patch for 4.0.3, but you may not be comfortable with running a custom version of Umbraco, it does mean that upgrades are off the table.

Since Snapshot generates an ASP.NET site from within itself there’s no need to worry about Umbraco restrictions like that, it comes down to how you’ve coded your site.

Database-less websites

Not every website needs a database, but unfortunately Umbraco requires one even when you’re not editing content. You may not be aware but when you work with the Media API (either via the umbraco.library methods, or though the Media classes) you are going into the database. Yes there are projects which simulate a media cache you can even do this with Examine.
But you’ll still have to have your web server talking to a database.

Snapshot doesn’t require a database form the web server. We’ve got built-in Media caching, a Media API and even replace the umbraco.library XSLT methods so that the Media interaction in an XSLT doesn’t require a database!

Security

Umbraco is reasonably secure, but wherever you have a login you have a vulnerability, it’s just the way of the web. A Snapshot site has no login, has no database, thus it is more secure (yes yes, famous last words :P). With Snapshot you can put your CMS inside your DMZ and never have it expose itself to the outside world. You can then get Snapshot to generate a site from the CMS and you just deployed the generated files.

Speed

As fast as Umbraco is (and the backed just got faster) there’s always room for improvement. When writing Snapshot we came across several places which were not as good as they could have been within the Umbraco API. Take umbraco.library for example. You interact with static methods on the type in XSLT, but for every XSLT macro an instance of the class is created. This means that it can’t really have request-level caching of what you’re interacting with.
Or take NodeFactory, it doesn’t have caching of the node(s) you’ve tried to access; you get a new instance each time.

Now I’m not having a go at Umbraco’s API on this, just pointing out some facts.

In Snapshot we have much improved caching. Since we’re using Dependency Injection (via Autofac) we only create a single instance of our umbraco.library implementation, we also do the same for our ContentService (the NodeFactory replacement) and MediaService (media API replacement).
These have caching built into them as well, so you hardly ever create objects, you get back previously created ones.

In future posts we’ll look more into the new API’s and just how sexy they can be ;).

Because we can

Really, does there need to be any reason other than this! :P

 

 

Hopefully this gives some insight into what we’re trying to achieve and shows you how it could be viable in your scenarios. Keep in mind this isn’t all you can do with Snapshot, it’s just some of the most common reasons why.

Categories: .Net | Snapshot | Umbraco

Introducing Snapshot

by Aaron Powell 18. May 2010 01:31

Over the past few weeks Shannon and I have been dropping hints on Twitter about an exciting new project we’ve been working on. We’ve now started dropping hints including the name Snapshot.
Well we thought it was about time that we stopped playing the tease and brought more to the table.

What is Snapshot?

In short Snapshot is a tool for Umbraco, giving you the ability to export a full ASP.NET site from the CMS.

Darren Ferguson tweeted about a similar product he’s working on, generating HTML files from Umbraco.

But we’re going up a notch, we’re exporting a fully working ASP.NET website from Umbraco.
This means that macros will work, .NET User Controls will work, everything you’d expect from an Umbraco site.

Just there’s no CMS at all. In fact, you shouldn’t require any of the Umbraco assemblies to run it!

 

Enough talk, here’s a video!

Snapshot introduction from The Farm on Vimeo.

Categories: .Net | Snapshot | Umbraco

Unit Testing meets Umbraco 4.1

by Shannon Deminick 17. May 2010 14:42

Yup, it's true, unit tests are now part of Umbraco 4.1!

I was starting to fix a few bugs listed on CodePlex for Umbraco and a lot were related to adding foreign keys, primary keys, indexes, etc… in the database. I was quite happy to take up the much needed task of putting some real structure into the underlying table structure but once I started adding the constraints, SQL server started telling me there was problems. Turns out that adding the correct foreign keys and indexes started to expose quite a few bugs in the data layer. These bugs are mostly related to data integrity such as deleting rows from the umbracoNode table but not from the related cmsDataType table when removing an Umbraco Data Type. In light of knowing that there was a lot of testing ahead of me I decided to figure out how to get unit tests working with Umbraco (otherwise testing all of these data constraints was going to be painfully slow and tedious).

So what’s the big deal? Everyone writes unit tests for code! Well, if you’ve used the Umbraco API for anything, you’ll quickly realise that you can’t use any of the Umbraco APIs unless you’re using them in an ASP.Net web context and having a web context in a unit test framework is generally hard to come by without some tricky type mocking. Here’s where Microsoft’s Visual Studio unit testing framework comes in very handy! It’s actually very easy to make a Visual Studio unit test run in the same web context as your website and here’s how:

  • Create a new Unit Test project in Visual Studio
  • You’ll notice that it creates a .testrunconfig file in your Solution Items folder in your solution
  • If you double click this file, it will present you with some options, click on the "Hosts" option:

image

  • As seen above…
    • Select ‘Run in default host’ (I’m actually not sure if this is required :)
    • Choose ASP.NET in the Host Type drop down list
    • Change the URL to test to be the URL that your web application is running under (or if you’re running in IIS, select Run tests in IIS)
    • Choose the path to your web application files in the "Path to Web site" field
    • Enter a "/" in the Web application root (assuming you’re not running in a virtual directory)
    • Close and save the .testrunconfig file
  • Now, in your unit test class, you just need to ensure that your tests are run with this config:

image

Now when you run your unit test, it will run in the context of your web application!

Caution!

A couple of things to consider with this configuration:

  • If you’re automating unit tests using a build server, or similar, this isn’t going to work. This will work on your machine because it’s running under the Cassini context built in to Visual Studio. Build servers aren’t going to automagically be able to start up a Cassini server to run your tests under (well, i’m sure anything is possible, but i don’t think this is going to work out of the box). Running it under IIS could be an option however.
  • Debugging doesn’t work quite the same as normal unit test. You can’t actually just set a break point and hope that it will stop code execution and allow you to debug but fortunately there’s a work around for this. You’ll have to add a user defined break statement in your code if you want to step through it:
System.Diagnostics.Debugger.Break();
  • When you add this, an alert will pop up asking you if you want to debug so all you have to do is click yes and start debugging with another instance of Visual Studio. You can just keep this instance attached to the process and add breakpoints to this instance as much as you like.

Working in teams

As you can tell from the above configuration file, that this setup is specific to my computer which is why I’ve named the .testrunconfig file using my machine name: Shandemvaio. This is useful when working in teams (such as the Umbraco core team). Each member of the team can create their own .testrunconfig file and before running the tests just set the Active Test Run Configuration file to be their own… nice.

The Tests

So far I’ve written some tests for the Document object. I’ve started with this object since it’s probably the most important and is also the highest in the object hierarchy which means that the test written here will also be testing a lot of the base class functionality. We could write unit tests for months and still not have written tests for every circumstance so I’m merely focusing on unit tests that relate to data integrity. And here’s the ones written so far:

image

… and there’s lots more to come!

Categories: .Net | Umbraco

FADS – A development process overview

by Aaron Powell 13. May 2010 09:54

A few months ago we were sitting around as a .NET team discussing how we need to structure our development process. One of the main topics was how the .NET project structure should be done. At TheFARM we’ve had a fairly good project structure for a while, but we needed to better quantify it.

We structured all projects with a similar .NET internal set in the format of:

  • Abstractions of our models and data services
  • Concrete implementations of each
  • Web usage of each

The problem was explaining it to a new developer, how do you say “Our structure is around …”?

So while sitting around discussing this we decided that we should give it a name. We like names here at TheFARM, especially fun names. This site is FarmCode, Suite101 is our business blog, and we have fun names for many of our internal systems.
It was only fitting that we think up a name for our .NET project structure.

Now I must clarify, we hadn’t been drinking (or at least not as far as I can remember) when we were having this discussion, we were just throwing around ideas for anagrams which we could use. I don’t rightly remember what else we had, but eventually we settled on FADS, or theFARM’s Abstracted Data Services.

Tacky, maybe, but now it’s named, so it’s easier to say “With FADS, where should X be?”, or as we’re currently discussing “How should we DI FADS?” (yeah that’s right, let's get as many anagrams into a sentence as we can :P).

What’s the goal of FADS?

The primary goal of FADS is to separate the data layer away from anything else, making unit testable development a lot easier. Your web layer doesn’t have any access to the underlying data layer(s), not does it have access to the actual .NET classes which represent the data layer.

Everything you do with FADS is done via interfaces. The data layer exposes interface so you can only access the data via them. The beauty of this is that you can refactor your data layer as much as you like, but not have the web layer any the wiser.
In fact, this happened recently with a project where we decided to swap out a data layer which was using the Umbraco XML as the data store for Examine. The web layer was unaware of any changes, except for the fact that everything started working a crap load faster!

Since FADS is just a design pattern it is quite acceptable with any .NET project, be it a standard ASP.NET WebForms application, an Umbraco-based application or even a non-web application.

Tags: , ,
Categories: .Net | Umbraco

Tutorial 2: Managing XML/SWF payloads easily

by Tom Byrne 13. May 2010 08:48

This is part two of a three part tutorial.

  1. Using Multiple XML sources
  2. Loading classes from other SWFs
  3. Download Source

1. Using Multiple XML sources

If your app is big enough, you won’t want your users to download all XML content when it starts, you’ll want to break down content into chucks which are loaded only when the app needs them. This is easy in SiteStream by linking your XML sources together.

This example expands on the example in Part 1 by including a second XML file (myXML2.xml), this is done by adding a ‘url’ attribute to the requested item (root/item2 in myXML.xml), which is recognised by SiteStream as a special attribute. This second XML file contains the fully populated version of the object (as opposed to the empty ‘stub’ version in the myXML.xml file). Notice that the code hasn’t changed at all, SiteStream will realise that the requested item references another XML source and will automatically load in the additional content. This would also be the case if the code requested any object deeper within the myXML2.xml file (i.e. “root/item2/childObject”).

 

myXML.xml:

<Array id="root"
myPackage="myPackage.*">
<myPackage:MyClass id="item1"/>
<myPackage:MyClass id="item2" url="myXML2.xml"/>
<myPackage:MyClass id="item3"/>
<myPackage:MyClass id="item4"/>
<myPackage:MyClass id="item5"/>
</Array>


myXML2.xml:

<myPackage:MyClass id="item2" colour="0xff0000"
myPackage="myPackage.*">
<myPackage:MyClass id="childObject"/>
</myPackage:MyClass>

 

SiteStreamTest.as:

package
{
import org.farmcode.siteStream.SiteStream;
import flash.display.Sprite;
import myPackage.MyClass;
public class SiteStreamTest extends Sprite
{
public function SiteStreamTest(){
var includeClass:Class = MyClass;
var siteStream:SiteStream = new SiteStream();
siteStream.rootURL = "myXML.xml";
siteStream.getObject("root/item2",onSuccess);
}
private function onSuccess(e:MyClass):void{
trace("Item 2 retrieved");
}
}
}

 

The SiteStream object has a property 'baseDataURL', which allows the setting of base URL which will be prepended to the beginning of the XML URLs included in your data. This property helps with multiple environments where the relative path to XML files might change. This value is not used for the root XML load.

2. Loading classes from other SWFs

When you’re app becomes large, you may wish to break down the SWF into several parts (‘Modules’ in Flash Builder), generally the issue with this is loading these SWFs in at the right time. SiteStream makes this very easy by allowing SWFs to be referenced in the package/namespace declarations of the root node.

Note, the only change I have made to SiteStreamTest.as is removing the reference to MyClass (to avoid MyClass being included in the main SWF).

The following example builds on example in Part 1, notice the MyClass Class has been moved from the SiteStreamTest SWF into the CodeLibrary SWF, which is then referenced in the XML package declaration.

myXML.xml:

<Array id="root"
myPackage="CodeLibrary.swf::myPackage.*">
<myPackage:MyClass id="item1"/>
<myPackage:MyClass id="item2"/>
<myPackage:MyClass id="item3"/>
<myPackage:MyClass id="item4"/>
<myPackage:MyClass id="item5"/>
</Array>

SiteStreamTest.as:

package
{
import org.farmcode.siteStream.SiteStream;
import flash.display.Sprite;
public class SiteStreamTest extends Sprite
{
public function SiteStreamTest(){
var siteStream:SiteStream = new SiteStream();
siteStream.rootURL = "myXML.xml";
siteStream.getObject("root/item2",onSuccess);
}
// Removed reference to MyClass to avoid inclusion
private function onSuccess(e:*):void{
trace("Item 2 retrieved");
}
}
}

 

CodeLibrary.as:

package
{
import myPackage.MyClass;
public class CodeLibrary extends Sprite
{
public function CodeLibrary(){
var includeClass:Class = MyClass;
}
}
}

The SiteStream object has a property 'baseClassURL', which allows the setting of base URL which will be prepended to the beginning of the SWF URLs included in your data. This property helps with multiple environments where the relative path to SWF files might change.

 

3. Download Source

 

< Goto Tutorial 1 | Goto Tutorial 3 >

Tags:
Categories:

Tutorial 3: Node Referencing & Alternative Parsers

by Tom Byrne 13. May 2010 08:47

This is part three of a three part tutorial.

  1. Node References
  2. Configuring SiteStream URLs
  3. Download Source

1. Node References

SiteStream XML allows you to have references between objects that will be resolved when parent item is resolved.

This can help in:

  • Reducing the amount of XML and processing by listing common objects once and referencing them multiple times.
  • Help create complex relationships between objects that would otherwise require lengthy coding.

The syntax used to reference other nodes is:

childObject="{root/item2}"

Where 'childObject' is the name of the property this reference will fill.

Or, if it is preferrable to use a node to reference:

<String id="childObject">{root/item2}</String>

References do not need to remain within their own XML file/source and can reference items anywhere in all of your linked XML sources.

To expand on the example in part 1, I will add a reference to item2 which will result in item2's 'childObject' object being pointed to item3.

myXML.xml:

<Array id="root"
myPackage="myPackage.*">
<myPackage:MyClass id="item1"/>
<myPackage:MyClass id="item2" childObject="{root/item3}"/>
<myPackage:MyClass id="item3"/>
<myPackage:MyClass id="item4"/>
<myPackage:MyClass id="item5"/>
</Array>

Currently SiteStream only allows for absolute paths in Node References, meaning that if an XML file's position relative to the root changes, so to must any references pointing into it (including those within the file itself).

 

2. Alternative Parsers

The rules and methods SiteStream uses to parse XML can be modified on a per item basis. This is done by having an item (created in your XML) implement the ISiteStreamItem interface, this will then allow full control over how this item (and it's descendants) are parsed.

Note that the item itself will be created with it's parents settings (or the default settings if no ancestor was an ISiteStreamItem), as SiteStream doesn't know if it is an ISiteStreamItem until after it is created. All subsequent properties and children will then be parsed with the newly created object.

This feature has most commonly been used to create collections of items which only get resolved when they are specifically requested (as opposed to their parent object), which can be very useful for creating libraries of objects.

 

3. Download Source

 

< Goto Tutorial 2

Tags:
Categories:

Why SiteStream?

by Tom Byrne 13. May 2010 07:14

SiteStream is an AS3 library for parsing XML into first-class objects, read a basic tutorial here.

SiteStream aims to solve certain inflexibilities of AS3. It is not a replacement for flashvars or Remoting/AJAX. It is better to consider it a non-compiled part of your application.

Consider these traits of AS3/Flash Player:

  • AS3 is strongly typed and pre-compiled, meaning that code dependancies will automatically get bundled together without special provisions to split them into seperate SWFs (like Flash Builder's 'Module's).
  • The Flash Player offers no control over the order in which parts of a SWF are loaded (I have a feeling they do this for server compatibility reasons).
  • Which of these SWFs to load, and in what order, enerally depends on which parts of your app the user visits.

These SWFs quickly become unmanagable, SiteStream provides a simple way of loading the appropriate SWF at the appropriate time.

The XML files themselves are also only loaded when needed by the app.

Whilst AS3 (and other C-based languages) are great for fine functional programming, XML based languages have long been recognised as stronger in broader architectural programming situations (e.g. MXML, XAML, etc). SiteStream allows the core displays, data-sources and visual assets of your app to be configured and assembled in XML.

The benefits of doing this in a non-compiled format (as opposed to MXML):

  • Implicit management of SWF loading.
  • Easily switch from XML files to dynamically generated XML output (from any number of existing CMSs).

After saying all of this, SiteStream doesn't impose any rules upon it's use in your applications, and if you want to use it purely for the loading of data structures you're perfectly free to do so.

Tags:
Categories: Flash | SiteStream