Log in

First Umbraco experience

15 August 2010 18:40

Today I played a bit with Umbraco for the first time. I mostly focused on its multilingual support, which is a feature I usually expect from a CMS.

Friendly URLs

These days it seems that if your URL has a file extension, such as .html or .aspx, it's a sin. I don't get why an extension matters so much for SEO but I'll play along. Umbraco supports this out of the box, by modifying the web.config file. In appSettings, find the property umbracoUseDirectoryUrls and set it to true. That will give you the popular extensionless URLs.

Multilingual Support

Being a noob in Umbraco, I googled around a lot to find information about its multilingual support. Most of what I did is based on this article. The basic approach is to indicate the language in the query string. I'm going to do the same thing, but I'll use friendly URLs by modifying the configuration file UrlRewriting.config, which is in the conifg folder. I added the following rewrite rule:

<add name="languageRewrite" 
    virtualUrl="^~/(en|el|nl)/([0-9a-z\/]+)"
    rewriteUrlParameter="ExcludeFromClientQueryString"
    destinationUrl="~/$2?lang=$1"
    ignoreCase="true" />

with this rewrite rule, I get virtual URLs in the form: http://mysite/language/originalurl that will be translated to http://mysite/originalurl?lang=language without the user seeing this translation. This is the way I have organized the URLs in my own website and I like it, but in my case they're not virtual; I have to create them individually. One good enough reason for my to migrate my site to Umbraco :-)

Using the querystring parameter

Now all I need is my templates to be aware of this new query string parameter. In the tutorial I consulted I got lost in the XSLT magic, so for the time being I'm using the very simple approach of ASP.NET. Inside my page template:

<% if (Request.QueryString["lang"] == "el") { %>
    <umbraco:Item field="message_el" runat="server"></umbraco:Item>
<% } else { %>
    <umbraco:Item field="message" runat="server"></umbraco:Item>
<% } %>

It's ugly, but it works and it looks familiar to the ASP.NET developer. If the language on the query string is Greek (the code is el), use the message_el field. Otherwise, fallback to the default (English) message field.

Overall experience

I also played with Media and I managed to display my images (it wasn't as straight forward as I would expect). I had a first taste of XSLTs, Macros and the usual CMS stuff, Document Types, Contents and Templates. XSLT in particular seems to be the way you can do powerful stuff with Umbraco, but I haven't gone there yet. For the next time, I'll try to use the Dictionaries for localized text, in combination with what I have already and try to make the ASP.NET template more reusable.

Tags: ,

Categories: Coding


How to fail your project

10 August 2010 19:33

The following list presents a few ways to screw up a project. Please use it only to save your project and not otherwise. Using this list for intentionally screwing up a project is forbidden.

Don't write documentation. Why spend time writing down stuff that nobody reads anyway? Instead use face to face conversations where everyone leaves happy with their own conclusions. Make sure that you don't include in these conversations other people that might benefit from them. The best thing to do is keep them out of the loop and let them continue with their work. Don't communicate the results of these conversations with e-mail or any other tangible means; this can lead to proof and proof can lead to documentation. If you do send an e-mail, follow the same rule and don't send it to anyone who might actually gain knowledge from it or provide additional or different information. Every bit of knowledge must be kept in a "he said she said" level, so that nobody can be held responsible about anything.

Don't respect the coding guidelines. Code is poetry, poetry is art and art should be free. Don't listen to the lead developer who insists on maintaining a coding style. Live for today and forget about tomorrow. All these warnings that ReSharper (or anyother tool) display are for informational purposes only. If the compiler can read it, then the other developers can read it too. Extra bonus if you type in documentation in broken English that only you can understand.

Don't write unit tests. You know that it works. You tested it from the GUI. Once. Well, sort of. Anyway, it doesn't matter. If the other developers find out that it doesn't work, they probably are the ones who broke it. Claim that "it worked on my machine" and "I don't know what happened". It's a slim chance that they will be able to present evidence that they didn't break. If the others feel unit tests are important, they can write them themselves. You've got better things to do, like, write the actual code. You're saving the project while the others are slacking off writing unit tests. They should give you a medal!

Don't communicate with the others. If you do something that will affect others, don't tell them. If they are smart they will figure it out themselves. Why distract them anyway? They're busy. And it's a minor change anyway, right?

Don't ask for help. This is a special case of the previous one. If you are not sure about something, don't ask for help. Instead, assume how it should work and just write some code. Ideally, sneak-in the code and don't have it reviewed by another team member. This ensures that other people will consider it a fact. Think of all the endless meetings you just saved your team.

Bonus for international teams: Don't speak English (or whatever language that the entire team happens to speak). Effective communication is only done by speaking in your native language. If you are the most knowledgeable person in the team, this ensures that your job safety is guaranteed, at least until your company goes bankrupt, for some other unrelated reason of course. If on the other hand you're the person who knows the least, you can continue to work happily while the others discuss in their own language about how the feature you've been working on for the past week should be dropped altogether.

If the developers in your team are doing one or more of the above, your project will probably fail in some way. If the developers in your team are doing all of the above, you can rest asured that your project will fail so bad that people will actually discuss about it in the years to come and even refer to it as "that failed project".

Final tip for managers: If you are a manager in such a project, don't make the mistake of firing the person or persons who have repeatedly practiced the above examples, especially if you're the one who hired him. That will make you look bad for hiring an incompetent developer in the first place. Instead, let the mess continue, with the sane developers sinking further more in despair. This way, all the developers will look bad, but you won't, ensuring that your bonus is not harmed in any way.

Tags: , ,

Categories: Work


Combine subversion post-commit hooks with NAnt

25 July 2010 11:08

Subversion offers a mechanism called post-commit hook that allows an executable file to be run on the subversion server after a successful commit has been made. Since I host my own home server, containing both this website and my own subersion server, I thought I could use this mechanism to automatically update some files on the website when a commit has been made. For example, if I commit some changes on a web page template, it would be nice if it would automatically be updated on the website and also be packaged as a zip file for visitors of the site to download.

To make it a bit simpler at first, I want a post-commit hook on a repository that will get the latest version after the commit and copy certain files to a certain folder. From time to time, I would like to modify that list of files. Now, the executable that can be run in the post-commit hook can be an .exe or a .bat file. An .exe file doesn't seem right, because it's tedious to update an .exe file everytime I want to modify the list of files I want to copy. The batch file is a better alternative but, and this applies also to the .exe solution, being a hook it means that it will not live inside the repository. Therefore, I would have to modify the batch file separately before every commit that changes the list of files to be copied. And I will have to open up remote access of some sort to the hooks folder of the subversion server in order to do so. That doesn't seem right either. Wouldn't it be nice if my source code also describes the post-commit actions? So I need to find a way to bring the control of the post-commit actions inside my source tree. That's where I though I can use NAnt.

The idea is that the post-commit hook will be really minimal and do only the following actions:

  1. Create a temporary folder
  2. Export the latest source code into the folder
  3. Run NAnt specifying a special target name, e.g. postcommit
  4. Delete the temporary folder

And the real set of actions to be performed will be defined as a NAnt build script in the root of my source tree, using a predefined target name (e.g. postcommit). I find this approach more generic and powerful. In effect, we are converting our subversion server into a powerful tool that can do whatever NAnt allows: automatic build, automatic unit-testing and continuous integration, e-mail reports, backup, whatever. As long as you can specify it in a NAnt build file, the subversion server will run it.

This is how my post-commit hook looks like:

REM Create Temp folder
mkdir c:\Temp
cd C:\Temp

REM Export source code into trunk folder
"C:\Program Files\Subversion\bin\svn" export \
  --username myusername \
  --password mypassword \
  svn://svnhost/repository/trunk \
  trunk

REM Go into trunk folder
cd C:\Temp\trunk

REM Run NAnt
"C:\Program Files\nant-0.90\bin\nant" postcommit

REM Cleanup
cd C:\Temp
del /f /q/ s trunk
rmdir /q /s trunk

and this is a sample of a NAnt file:

<?xml version="1.0"?>
<project name="demo" default="postcommit" basedir=".">
	<description>demo autodeploy script</description>
	<property name="dest.dir" value="C:/Web" overwrite="false" />
	<target name="postcommit" description="">
		<touch file="${dest.dir}/it_worked.txt" />
	</target>
</project>

If you noticed the full paths in the post-commit batch file, that's because post-commit hooks run in an empty environment, which also means empty PATH variable. Also, it assumes that there's a trunk folder in your source tree and that folder contains a NAnt build file which has a target called postcommit. The trunk folder should exist, if you use the recommended root folder structure for the subversion repositories (trunk, branches, tags). So, if you copy the post-commit hook into the hooks folder of your repository on every commit NAnt will kick in and execute your custom actions. The sky is the limit! Hope this helps.

Tags: , , ,

Categories: SysAdmin


Playing with Castle DynamicProxy

24 July 2010 22:09

If you've ever used an ORM tool, such as NHibernate or the Entity Framework, you'll probably have noticed that their goal is to be as unobtrusive as possible. They say, and I agree, that you shouldn't be forced to have your business objects inherit from strange classes like MarshalByRefObject, or to annotate your properties with all sorts of ORM specific attributes. In that aspect, I find NHibernate to be rather clean.

But in the end, every ORM tool expects you to call some Save method in order to indicate that at this point you would like the ORM to kick in and do its magic. I was wondering, is it possible to have a piece of code like this:

Person person = new Person();
person.Lastname = "Smith";
person.Firstname = "John";

and just by using that code to end up with a new record in my database?

Well, technically, it's possible. I played a bit with DynamicProxy to make it work and I enjoyed it. What does DynamicProxy do? It creates dynamic subclasses of your classes at runtime, overriding all virtual members (properties and methods). All calls to those members are intercepted and your interceptors can do additional pre and post processing with those calls. If this reminds you of Aspect Oriented Programming, it's no coincidence. In fact, let's see an example of DynamicProxy in action, using the classic AOP example: Logging all method calls of a class.

So our class Person should look something like:

public class Person {
	public virtual string Lastname { get; set; }
	public virtual string Firstname { get; set; }
	public virtual void Print()
	{
		Console.WriteLine(
			"My name is {0} {1}",
			Firstname,
			Lastname);
	}
}

Note that all members are virtual so that DynamicProxy will be able to override them and intercept them. We want to print a message to the console everytime a property is being read or written. We'll implement the IInterceptor interface:

public class LogInterceptor : IInterceptor
{
	#region IInterceptor Members

	public void Intercept(IInvocation invocation)
	{
		if (invocation.Method.Name.StartsWith("get_"))
		{
			Console.WriteLine("Getting property");
		}
		invocation.Proceed();
		if (invocation.Method.Name.StartsWith("set_"))
		{
			Console.WriteLine("Property set");
		}
	}

	#endregion
}

What is happening here? If we access a member of the class that this interceptor is, well, intercepting, the Intercept method is call instead. The invocation argument can provide information about the original call but the most important method is the Proceed, which proceeds with the execution of the original non-intercepted code. The name of the method being called can be found by invocation.Method.Name. Note that properties are actually treated as method calls. The name of the method is the name of the property prefixed with get_ if it's a getter or set_ if it's a setter. In this code, all members are allowed to execute, since the invocation.Proceed() is always called. But if we're getting a property, a message will appear immediately before getting it and if we're setting a property the message will appear immediately after setting it. This doesn't have much value other than demonstrating pre and post processing in an interceptor.

In order to take advantage of the interceptor, we can no longer create our Person objects directly but we have to use DynamicProxy's Proxy Generator. The code for that looks something like this:

ProxyGenerator generator = new ProxyGenerator();
IInterceptor logInterceptor = new LogInterceptor();
Person person = generator.CreateClassProxy<Person>(logInterceptor);

And that's it! If we now call person.Firstname, instead of our code (which is not much since we're using an automatic property, but ok) what gets executed is the LogInterceptor. In there, a message will be printed notifying us that a property has being accessed and the invocation.Proceed() call allows the execution to proceed normally, returning the property value to the caller as expected.

I had a lot of fun playing with this tool and creating objects that are instantly persisted to the database without requiring an explicit call to a Save method. Of course, this "instant persistancy" technique is a disaster for the database, since every property modification results to a trip to the database. But it was very interesting nonetheless and I hope I'll have a chance to use more of DynamicProxy in the future.

Tags: , ,

Categories: Coding


Daleri Structure: the BlogEngine.NET version

18 July 2010 17:41

For this blog, and for the rest of this site, I'm using the Daleri Structure template by Andreas Viklund. Since I've ported it to BlogEngine.NET, I think it's a good idea to publish it so that other BlogEngine.NET users can use it.

I've submitted it to BlogEngine Theme and until they've reviewed and - hopefully - approved it, it's also available for download here. I hope this helps.

Tags: ,

Categories: Coding


Too fast for my computer

13 July 2010 19:29

I've been working on the same project since January and up to recently we had been using Visual Studio 2008 with ReSharper 4.5. A few weeks ago, we upgraded to Visual Studio 2010 and ReSharper 5. I don't know which one is to blame, but the IDE has become a bit slower. Two features in particular are really annoying:

  1. Ctrl+Click to navigate to the declaration of an identifier. This functionality was instantaneous in the previous version. Ctrl, Click, done. In the new version, in the beginning I had thought that it's not supported anymore. But I figured out that there's a small delay. I have to press the Control key, keep it down for almost a second, then the mouse cursor changes into a hand and then I can click. That's really disappointing.
  2. Auto-complete, intellisense, or whatever it's called these days. In the previous version it appeared immediately as I started typing. Now, if I type too fast, it doesn't have enough time to appear so by the time I hit Enter to apply the auto-complete that I know will be applied, I just get only the partially entered input. And then I have to go back, type it again, wait for it, wait for it, ok it appears now I can hit Enter.

As a colleague said when I complained about it: "maybe you're too fast for your computer then".

Tags: , ,

Categories: Software


070-536 Again

12 July 2010 18:42

Today I took again the 070-536 exam and I passed it once more, this time with an even higher score (861, while the previous time I had scored 838 points). I'm crossing my fingers that this time the testing center will not go bankrupt... hopefully within a few days I will get a notification from Microsoft verifying that I passed the exam. In combination with the 070-528 that I had passed on March, I should now have the MCTS .NET 2.0 Web Applications certification, which is my first certification!

Tags: , ,

Categories: Certifications


Certification Nightmare

25 June 2010 15:58

Last Monday, after spending about a month studying daily in the train to work, I went and took the 070-536 exam at New Horizons testing center, in Rotterdam Alexander. I was nervous because there are a lot of topics covered in this test that I've never ever used, since I'm focused more on web applications. After 45' minutes and 40 questions, I had succeeded! The popup window congratulated me and notified me that I had a scored 838 points, while the base is 700. Then I clicked next and that's when it all started.

I got an error popup window saying something like "Please contact Global Help Desk". I clicked the only available button in the window, "OK", and then the screen went blank showing only the mouse pointer which had turned into the hourglass. Convincing myself that this has to be normal, after all I studied so hard and why should this happen to me in the first place, I went to the reception to get my test results. Which of course, weren't there. The receptionist asked me if I had hit "Print" and I explained the situation. We went together back at the testing room where she tried a few tricks to send the results to the printer but she couldn't. She told me to call Prometric and verify that the test results got sent to their servers.

I went home and called Prometric around 12 o clock. They told me that the results are sent with a 24 hour delay so I should call back tomorrow.

On Tuesday morning, I called again and they were surprised that they hadn't received anything. They told me that they would call the testing center (New Horizons) to investigate.

On Wednesday morning, I called once more and I spoke with a different person who said that test results are actually updated every 48 hours. He also noticed that on Tuesday the incident was noted with the central offices of Prometric at the USA, so they will investigate. He told me that this takes about 3 business days, so if I haven't heard from them by Friday, I should give them a call.

This is Friday afternoon and I just got off the phone with Prometric. I spoke with the same person I spoke on Wednesday, but his response was quite interesting this time. The testing center New Horizons at Rotterdam Alexander had gone bankrupt ( ! ) on the same day I took the exam. So, the person who normally sends in the results, wasn't there to do it. They're trying to figure out a way of getting those results from the bankrupt test center... assuming that they got stored localy in the first place.

I visited the Prometric web site again and I don't see New Horizons in Rotterdam Alexander listed anymore in the test centers so I guess this guy was telling the truth and I've hit the one in a million situation.

Now I have to call them back again on Monday to see if they have any news. He told me that there are 35 more candidates that day that have the same problem. He was also kind enough to inform me that if I will have to take the test again, Prometric will pay the costs.

 

Tags: , ,

Categories: Certifications


Dynamic PNG Image Generation with ASP.NET

25 June 2010 15:16

I had created a small web app in MonoDevelop that created a png image on the fly. Porting the app to Windows .NET 3.5 with Visual Studio 2008 was almost painless, but it did include two unexpected incident. The first one was... well the app didn't run anymore, showing the dreadful "A generic error occured in GDI+". A bit of a research lead to this article here. Apparently the problem occurs only with PNG images. The stream that you write the generated image to needs to be seekable and I guess in Mono the Response.OutputStream is seekable but in .NET it's not. The solution is to use an intermediate MemoryStream to write the image to and then dump that stream on Response.OutputStream.

After that was fixed, I noticed that the fonts were appearing ugly, as shown in the following graphic:

The solution to that was to fill the background of the entire image with a colour (white in my case). I think it must be related with PNG transparency. If you observe the above screenshot, the text appears ugly only in the area that is not filled with colour.

Tags: , , ,

Categories: Coding


ScrumCard

5 June 2010 21:49

I made my first "hello world" Windows Mobile Phone application today. It's called ScrumCard and you can download it from here. ScrumCard is a simple mobile phone application that simulates poker planning for Scrum. So if you forgot your poker planning cards, you can use this app to show your team your estimate of the story points.

Using the horizontal scrollbar, you can choose a value between 1 and 89. Values belong to the Fibonacci sequence. If you want to enter a different value, you can use the text box labeled Custom Value.

If you want a more sophisticated and also free alternative for your Windows Mobile Phone, you can try AgileHand from ScrumDesk.


Tags: , , , ,

Categories: Coding



Return to top