Archives for the month of: July, 2010

After a month in the making, I’m happy to announce the first release of the Desktop Media Uploader package for Umbraco.

Having released a number of sites in Umbraco, I always love the feedback I get from clients on how simple it is to use. But the one area I do get some negative comments on, is the amount of steps it takes to upload files to the media section. I have had some success with existing packages such as Tim Geyssen’s Zip Upload and Keller’s Multi File Upload, but I was sure there could be an even easier way.

Being a big fan of Dropbox, I started to think, how could I make uploading files to an Umbraco site as simple as dragging and dropping? And with that, Desktop Media Uploader was born.

Once you install the Desktop Media Uploader package, you’ll find a new dashboard added to the Media section of your site, with a link to install the Desktop Media Uploader app. Simply click the link, and the install process will start automatically.

Once the app is installed, launching the app is as simple as double clicking the icon installed on your desktop.

When you first launch the app, you will be presented with the sign in screen. Simply enter the URL of your website, and your username and password and click Sign in (optionally, you can set whether the app should remember your details, and whether it should sign in automatically).

Once you are signed in, you will now see the main screen for the Desktop Media Uploader. From here you can launch the folder picker to select a media folder to upload files to (by double clicking on a folder), and then simply drag and drop files in to the upload area.

Once you have everything queued up, just click the Upload button to upload everything to your website.

It’s as simple as that.

For a complete run through, checkout the video below.

(You can view a higher res version on screenr.com)

So what’s next?

There are still loads of features that I will be implementing in Desktop Media Uploader in the future, including:

  • Multiple Accounts
  • Folder support
  • Chunked uploads
  • And many more

The ultimate aim is to make Desktop Media Uploader the simplest, and best way to upload media to Umbraco.

If you like what you’ve seen, then please do download Desktop Media Uploader and try it out for yourself, and if you find it useful, then please do vote it up. If you find any issues, or there is something you’d like to see in the next version, then why not drop a thread in the support forums.

Happy uploading.

SEOThere has been a fair bit of conversation lately around Umbraco packages not always getting the recognition that they deserve. Whether this is due to new developers not knowing what existing packages there are, or the flurry of new packages making them easy to miss, it’s often difficult to know what is actually out there. Warren Buckley is currently lobbying for a few changes in the projects section of our.umbraco.org to help make packages more visible, but I thought I’d try to help out by starting a series of posts to highlight some useful packages around specific subjects.

With that in mind, I thought I’d kick the series off with 10 essential Umbraco packages to help with SEO (in no particular order).

1. Google Analtics for Umbraco

This package adds a new section to the Umbraco backend, which gives you access to your google analytics statistics in form of some standard reports (out of the box). You also have the ability to create your own reports from the metrics and dimensions, which are available through the Google Analytics API.

2. 301 URL Tracker

The 301 URL Tracker keeps track of changes to the name or location of a page, and automatically stores the old URLs and when someone requests one of these old URLs, they are automatically transferred to the correct new URL, with a 301 HTTP response. Search engines recognize this HTTP response and replace the old location with the new location.

3. WWW Forcer

The WWW Forcer, will force the user to browse the site with the www. subdomain. This is especially useful for preventing duplicate page serving, an SEO technique.

4. Cogworks CogPageReview

The CogPageReview package gives content editors the ability to setup review dates on content then be notified either by a dashboard control or via regular emails a list of content due for review. Part of the rational behind this project is that regular updates to site content can help improve SEO site rankings.

5. Broken Link Checker

Broken link checker for Umbraco finds links in your pages as you publish them and checks that they are valid. If any broken links are found then this is reported via the Umbraco dashboard.

Links are queued for checking and a background scheduled tasks perform the actual verification. Once a user has fixed a broken link, they remove it from their dashboard.

6. Robots.txt Editor

The Robots.txt editor adds a tree node to the developer section, which allows access to your Robots.txt file from the root of your website. If you do not have an existing Robots.txt, then one will be created for you.

7. AutoTag

The AutoTag package is a custom datatype control that generates a list of keywords/tags from a text area. Thus making the task of categorising your new articles, blog posts or pages much quicker.

8. Canonical Meta Link Package

The Canonical Meta Link package automatically creates canonical meta tags, if the URL used is not the one found by Umbracos NiceUrl. Especially useful if you use umbracoUrlAlias or umbracoUseDirectoryUrls.

9. Google Sitemap for Umbraco

The Google Sitemap for Umbraco package automatically generate an XML Google sitemap to help Google index your site’s content.

10. Auto Link

The Auto Link package automatically injects links into content based on a configuration. This allows you to automatically link keywords and phrases in your posts and comments with corresponding posts, pages, categories and tags on your site.

Hopefully this post will give you a bit of an idea of what Umbraco packages are out there around SEO, and maybe even lists a few packages you didn’t know about. I definitely recommend for you to spend a little time going through the our.umbraco.org projects section, but if you can’t be bothered, be sure to keep an eye out for the next post in the series =).

UPDATE – July 20, 2010 19:27

Ok, I know the title of the post says 10 Essential Umbraco Packages for SEO, but when this one came up, I just had to add it.

11. DynamicRobots

DynamicRobots is a httpHandler which will look for the string {HTTP_HOST} in your robots.txt file and replaces it with the current sites hostname for you. This is especially handy if you are running multilingual, or multiinstall sites, as it allows you to define one robots.txt file that works for all sub-sites.

An interesting conversation occurred this morning on Twitter between Aaron Powel, Sebastiaan Janssen, Peter Gregory and myself about how we structure our Visual Studio projects when working with Umbraco, so I thought I’d share how I currently set mine up. I’m not saying this is the right solution, as I feel there are a number of flaws in it, but so far it has served me well.

Folder Structure

Folder structure

Above is an example of the folder structure I will usually follow, which is broken down as follows:

  • Assets - All creative files, and copy docs
  • Db - Database backups and SQL scripts
  • Lib - Library assembleys. I will usually copy the Umbraco dlls into a sub folder in Lib.
  • Src – Contains all my source code and web folder.
    • ProjectName.Web – My Visual Studio web project folder.
    • Web – My actual web folder containing the Umbraco web files, merged with my web projects output.
  • Tools - Contains useful build tools which I will get on to shortly.

I will usually host my .sln file within the root of the folder structure for easy access.

Project Structure

Within Visual Studio, I will create folders for all the core Umbraco folders, plus one for Config, which is not exactly what you think it is, but I’ll get on to that shortly.

The next step is to set up the projects post build event which does 2 things. Firstly, copies over all the relevant projet files to the Web folder, and secondly, merges my config files, but I’ll get on to that shortly, I promise =).


REM #################################################
REM # Copy files
REM #################################################

xcopy /s /y "$(ProjectDir)Css\*.css" "$(WebProjectOutputDir)\..\Web\css\"
xcopy /s /y "$(ProjectDir)Images\*.jpg" "$(WebProjectOutputDir)\..\Web\images\"
xcopy /s /y "$(ProjectDir)Images\*.gif" "$(WebProjectOutputDir)\..\Web\images\"
xcopy /s /y "$(ProjectDir)Images\*.png" "$(WebProjectOutputDir)\..\Web\images\"
xcopy /s /y "$(ProjectDir)MasterPages\*.master" "$(WebProjectOutputDir)\..\Web\masterpages\"
xcopy /s /y "$(ProjectDir)Scripts\*.js" "$(WebProjectOutputDir)\..\Web\scripts\"
xcopy /s /y "$(ProjectDir)UserControls\*.ascx" "$(WebProjectOutputDir)\..\Web\usercontrols\"
xcopy /s /y "$(ProjectDir)Xslt\*.xslt" "$(WebProjectOutputDir)\..\Web\xslt\"
xcopy /s /y "$(ProjectDir)favicon.ico" "$(WebProjectOutputDir)\..\Web\"
xcopy /s /y "$(TargetDir)*.dll" "$(WebProjectOutputDir)\..\Web\bin\"

REM #################################################
REM # Merge config files
REM #################################################

REM FOR /F %%a IN ('DIR /B $(WebProjectOutputDir)\..\Web\Config\*.config') DO (
REM     CALL "$(SolutionDir)Tools\Scripts\XmlConfigMerge.bat" $(SolutionDir) $(WebProjectOutputDir)\..\Web\Config\ $(ProjectDir)Config\ %%~na %%~xa $(ConfigurationName)
REM )

REM CALL "$(SolutionDir)Tools\Scripts\XmlConfigMerge.bat" $(SolutionDir) $(WebProjectOutputDir)\..\Web\  $(ProjectDir)Config\ Web .config $(ConfigurationName)

IIS

Personally, I prefer to set up my websites in IIS, rather than using Casini. I won’t go through this step, as it’s not really doing anything special, but one thing I do tend to do, is set up a host header in my hosts file, again nothing special, but I will share a .bat script I have pinned to my quick launch for easy editing.

start /d C:\Windows\System32\ notepad.exe C:\Windows\System32\drivers\etc\hosts

Debugging

During development, I will generally have a browser window open at all times with the site running, so to debug, I will usually use “Attach to Process” in Visual Studio (Ctrl + Alt + P) to attach to the w3wp.exe process. From there you can run through breakpoints as per usual.

Config Merging

Ok, so now to the semi-interesting bit I promised =), Config merging.

One of the main reasons I chose the project structure I use is to allow total separation of my project specific files, from the Umbraco web files. By separating it in this way, I should, in theory, be able to take a fresh Umbraco install, run the post build events, and have a fully setup client website (In theory). This should also help with upgrades, where I can grab a new version, copy everything over, and trial the website out. The difficulty for me came with config files.

What I didn’t want to do was to copy the whole config file over, as I couldn’t be sure the configs would always stay the same, plus it’s just a waste (a small waste granted, but a waste none the less), plus I wanted to have different configs for different machines and different build configurations.

To solve this problem, I use a tool called XmlConfigMerge which allows you to merge XML config files together. This way I only have to store in my solution the differences in the config files, and not the whole config file itself. To allow for different configs per machine and build process, I simply use the built-in Visual Studio $(ConfigurationName) macro, along with the DOS %computername% global variables to automatically select which config files to merge. It does this based on the name of the config file, which would be one of the following.

  • ConfigName.config
  • ConfigName.BuildConfiguration.config
  • ConfigName.BuildConfguration.ComputerName.config

Looking back at my post build command, you’ll now see the 2 statements at the bottom, the first of which loops through all files in the config folder, and the second specifically merges the web.config. These commands get passed to the following .bat script.

@echo off

SET SLN_DIR=%1
SET DST_FILE=%2%4%5
SET TMP_FILE=%2%4_tmp%5
SET SRC_FILE1=%3%4%5
SET SRC_FILE2=%3%4.%6%5
SET SRC_FILE3=%3%4.%6.%COMPUTERNAME%%5

COPY "%DST_FILE%" "%TMP_FILE%" /y

IF EXIST "%SRC_FILE1%" (
 "%SLN_DIR%Tools\XmlConfigMerge\XmlConfigMergeConsole.exe" "%TMP_FILE%" -m "%SRC_FILE1%"
)
IF EXIST "%SRC_FILE2%" (
 "%SLN_DIR%Tools\XmlConfigMerge\XmlConfigMergeConsole.exe" "%TMP_FILE%" -m "%SRC_FILE2%"
)
IF EXIST "%SRC_FILE3%" (
 "%SLN_DIR%Tools\XmlConfigMerge\XmlConfigMergeConsole.exe" "%TMP_FILE%" -m "%SRC_FILE3%"
)

CALL "%SLN_DIR%Tools\Scripts\CopyIfNewer.bat" "%TMP_FILE%" "%DST_FILE%"

DEL "%TMP_FILE%" /f /q

What this script does, is copy the source config to a temp file, then checks for existence of global, build specific and user specific configs in the config folder and merges them with the temp config file. Finaly, a check is made to see if the temp file was changed, and if so, overwrites the existing config file. The script for checking whether the file has changed is as follows:

@echo off
echo Comparing two files: %1 with %2

if not exist %1 goto File1NotFound
if not exist %2 goto File2NotFound

fc %1 %2 /w
if %ERRORLEVEL%==0 GOTO NoCopy

echo Files are not the same.  Copying %1 over %2
copy %1 %2 /y
goto END

:NoCopy
echo Files are the same.  Did nothing
goto END

:File1NotFound
echo %1 not found.
goto END

:File2NotFound
copy %1 %2 /y
goto END

:END
echo Done.

Conclusion

As I said at the beginning, this is far from the perfect solution. It is one that I have adapted over time, having worked in multi-developer environments. Some of the flaws right now are that the build process can take a while with all the config merging, and because all of your source files are separate, you are currently forced to do a build to copy over any files to the Web folder. I’m sure I will continue to change this as I go along, but hopefully this may be handy for people starting out.

If you have any comments on my setup, or would like to share your own, please drop me a comment below.

Follow

Get every new post delivered to your Inbox.