First time here? You are looking at the most recent posts. You may also want to check out older archives or the tag cloud. Please leave a comment, ask a question and consider subscribing to the latest posts via RSS. Thank you for visiting! (hide this)

July 2007 Blog Posts

Hacking Google Analytics

Last week the old version of Google Analytics was dismissed and the only available UI is the new version, which is great, much more user friendly, but misses 2 features I used a lot:

  • Today users by hour
  • Users by month

I didn't find the user grouped by month report yet, but after a bit of URL hacking I found how to get the hourly report for the current day.

The biggest problem is that the date validator in the analytics UI validates the user input based on Google server date, which happens to start 19 hours later then in New Zealand.

Today is 31st July but the date selector allow me to select only till 30th of July (current date in Google time zone). And if I manually enter 31/07/2007 I get a JS message box with the validation error.

date_selector

You can select a report also specifying the period in the URL, and this period is not validated:

.../dashboard?id=xxxxx&pdr=20070629-20070730&cmp=average

So the easy way to get the current day to show up in the chart is it to change the URL to include the current day:

.../dashboard?id=304878&pdr=20070731-20070731&cmp=average

today_users

Now you have the stats for the current day, and since all the links in the dashboard are created based on the prd parameter also all the other reports will be for the same period, so they will include the current day, too.

If you click on "Visits" (.../visits?id=xxxx&pdr=20070731-20070731&cmp=average) and then "Hours" you will finally get the hourly report for the current day in your own time zone. 

Just remember that since the UI doesn't allow a period ending in a future date, the date selector is not going to work anymore.

not_working_selector

I send an email to Google so that they can fix the UI validation logic based on the browser time zone and not on their own time zone, but got no answer back.

Technorati tags: ,

Simone vNext

Since more than a few readers and community fellows (both Italian and Kiwi) send me emails and IMs asking what I am going to do next I think it's better to answer them all with a blog post. So here is the roadmap:

  • Next Monday (6th August) I'm flying back to Italy to enjoy a bit of summer weather
  • I'll be in Italy working from home on the project I just started here at Calcium (and since Daniela is working on a wonderful lake far from Milano, I'll stay in the house on the lake with her)
  • Together with Daniela we will decided whether to stay in Italy or come back to New Zealand:
    • If we decide to come back we will do it at the end of October/beginning of November and I might come back in Calcium or go working in another company in Wellington or in the South Island
    • If we decide not to come back I might go back working for Esperia Connexia, or look for some other job in Italy (or Europe)

As I said in a post a few weeks ago, if it was only for the work conditions I'd come back to NZ as soon as my wife finishes her contract with the European Commission research center, but life is not only work, so... only time will tell...

One thing that is sure, is that this blog will go on even if I'll stay in Italy.

Technorati tags: , ,

Hairdressers Expedition on Everest

Back in the '72, the Monty Python's Flying Circus had this sketch about a fictitious climbing expedition by International Hairdressers.

This was a comedy show, but how long before the holy Sagarmatha becomes a "hiking peak" that everyone with US$ 30K can climb?

[via peakr]

Technorati tags: , , ,

Want to save NZ native bush?

Why don't you just send an email or mail newsletter instead of sending paper magazines or "snail mails"?

"Save the cheerleader, save the world" "Send an email, save a tree !" is the name of the campaign that Calcium started in order to try and preserve the native New Zealand trees.

If you go to saveatree.co.nz and refer a friend

"...Calcium Communication and its participating partners will make a donation towards the purchase and planting of a native tree in New Zealand."

So, please, check out the website, and refer some friends: you will do a good action to preserve NZ great native tree.

180x150-banner pohutukawa

If you want to spread the word, you can also download a badge and put it on your blog's sidebar.

Technorati tags: , , ,

Ladies and Gentlemen, please start your ... downloads

vs2008

As announced, VS Orcas 2008 Beta 2 has been released:

Release Notes on ScottGu blog

Direct download page on MSDN

Technorati tags: ,

Google in Maori

[July 25rd, 2008] UPDATE: Google Māori gone live: www.google.com/intl/mi

[July 23rd, 2008] UPDATE: Google Māori to go live on July 24th.

Seems like Google is working to create a Maori version of their search engine:

Google Looks At Maori Language

They already have Klingon, Hacker and Elmer Fudd, why not Maori which is a real language?

Technorati tags: ,

Orcas Beta 2 due this week?

>>>>>>> Oh, and I'm desperately waiting for the VS2K8 Beta 2 - will it be dropped soon?

You'll see Beta2 ship later this week - so only a few more days now.
Thanks,
Scott

ScottGu wrote that Beta2 will ship later this week in a comment on his post announcing IronRuby.

And it's said to be 99% feature complete. I think I can exceed my traffic cap next week.

Technorati tags: ,

Vista Gadget to monitor Orcas TFS Team Build

team_buildOne of the new cool features of the new Orcas TFS is the Team Build Job, which adds a kind of Continuous Integration to Team Foundation Server.

Jim Lamb, PM of this new feature, just released a Vista Sidebar Gadget that lets you monitor the builds happening on one server.

The screenshot at the right looks pretty familiar to me.smile_regular

This gadget doesn't have an undocked view with more details about all the projects, but uses the flyout to show more details of a specific project then you click on the project name.

You can look at a preview of the TFS Team Build Monitor Vista Sidebar Gadget on Jim's post.

And if you missed it, you can look at a preview of my CruiseControl.NET Monitor Vista Sidebar Gadget, too.

Thanks to Thomas F. for pointing it out.

Yoga the Swiss way

I just found (via swissmiss) one of the best advertisement I've seen in my life:

a Swiss cow, doing Yoga in the campaign of the SwissMilk Consortium.

wallpapers_yoga3_800

And there are also other nice Yoga positions as desktops on the Swissmilk website.

Thumb up for the marketing guys behind this campaign.

Technorati tags: , ,

Learn Spanish with a podcast

I decided to learn Spanish Castellano, and looking for free resources on the Internet I found a very nice way to learn a new language: a podcast.

CoffeeBreakSpanish I already listen to podcasts related to technology and .NET development, but I never thought to a podcast as a way to learn a language.

So I subscribed to CoffeeBreakSpanish, hosted by a Scottish Spanish teacher.

I only listened to the first 3 lessons, but seems to be well paced and also teaching things in a friendly and practical way.

The lessons are only 15 minutes long, so I can listen to two of them when going to and coming back from lunch (Yes, I know, half an hour of walk just to go to lunch is a long time).

For those who are not interested in Spanish, the same site also produces an Italian and a German podcast.

I'd also be interested in learning Catalan, the language spoken in Catalunya, the region of Barcelona, but didn't find any online resource for it. But for now, Adios!

How to add a required validator to a CheckBoxList

If you add a normal RequiredFieldValidator and you want to validate a CheckBoxList, you will get a runtime exception informing you that the CheckBoxList cannot be validated.

Sometimes you want to make sure the that user has selected at least one of the checkbox in the checkbox list, but as aforementioned, if you user a normal RequiredFieldValidator you will get an exception.

You could use a CustomValidator control, but a nicer and more reusable approach is to build a custom web control that extends the BaseValidator.

I found a 2001 article on how to do that (Building a CheckBoxList Validator Control) but it doesn't work properly on ASP.NET 2.0 and also it doesn't work on Firefox.

So I have to make some small changes to make it work on ASP.NET 2.0 and on Firefox.

First thing you have create a class that inherits from BaseValidator

public class RequiredFieldValidatorForCheckBoxLists : BaseValidator

Then you have to override a few methods:

ControlPropertiesValid

This method must check whether the ControlToValidate property of the validator refers to an existing control and if the control is of the correct type

protected override bool ControlPropertiesValid()
{
   Control ctrl = FindControl(ControlToValidate);
   if (ctrl != null)
   {
      CheckBoxList _listctrl = ctrl as CheckBoxList;
      return (_listctrl != null);
   }
   else
      return false;  
}

In this we check if the control is null and if the control can be cast to a CheckBoxList.

EvaluateIsValid

This is the methods that performs the server side validation in case JavaScript is not enabled on the client, or not supported.

protected override bool EvaluateIsValid()
{
   return EvaluateIsChecked();
}

// Private method to perform the real check
private bool EvaluateIsChecked()
{
   CheckBoxList _cbl = ((CheckBoxList)FindControl(ControlToValidate));
   foreach (ListItem li in _cbl.Items)
   {
      if (li.Selected)
      {
         return true;
      }
   }
   return false;
}

In this method I just loop through all the items of the CheckBoxList and if I find one that is selected then I return true.

Now we have the validation working on the server after a postback, but it would be nice if we could perform the validation directly on the client when the user toggles the state of the checkboxes. To accomplish this there is another step to take: inject some client side JavaScript in the OnPreRender method.

OnPreRender

The PreRender event is raised just before the control is rendered on the page, so it the best moment to inject some client side functionality into the page.

protected override void OnPreRender(EventArgs e)
{
   base.OnPreRender(e);
   if (EnableClientScript) { ClientScript(); }
}

private void ClientScript()
{
   StringBuilder sb_Script = new StringBuilder();
   sb_Script.Append("<script language=\"javascript\">");
   sb_Script.Append("\r");
   sb_Script.Append("\r");
   sb_Script.Append("function cb_verify(sender) {");
   sb_Script.Append("\r");
   sb_Script.Append("var val = document.getElementById(document.getElementById"
			+"(sender.id).controltovalidate);");
   sb_Script.Append("\r");
   sb_Script.Append("var col = val.getElementsByTagName(\"*\");");
   sb_Script.Append("\r");
   sb_Script.Append("if ( col != null ) {");
   sb_Script.Append("\r");
   sb_Script.Append("for ( i = 0; i < col.length; i++ ) {");
   sb_Script.Append("\r");
   sb_Script.Append("if (col.item(i).tagName == \"INPUT\") {");
   sb_Script.Append("\r");
   sb_Script.Append("if ( col.item(i).checked ) {");
   sb_Script.Append("\r");
   sb_Script.Append("\r");
   sb_Script.Append("return true;");
   sb_Script.Append("\r");
   sb_Script.Append("}");
   sb_Script.Append("\r");
   sb_Script.Append("}");
   sb_Script.Append("\r");
   sb_Script.Append("}");
   sb_Script.Append("\r");
   sb_Script.Append("\r");
   sb_Script.Append("\r");
   sb_Script.Append("return false;");
   sb_Script.Append("\r");
   sb_Script.Append("}");
   sb_Script.Append("\r");
   sb_Script.Append("}");
   sb_Script.Append("\r");
   sb_Script.Append("</script>");

   //Inject the script into the page
   Page.ClientScript.RegisterClientScriptBlock(GetType(), SCRIPTBLOCK,
					sb_Script.ToString());
   //Registering validator clientside javascript function
   Page.ClientScript.RegisterExpandoAttribute(ClientID, "evaluationfunction",
					"cb_verify");
}

First I check if the client validation is enabled, and, if it is, I write on the page the javascript method, and more important, the code to tell the common validation script to call my "cb_verify" function to validate the value of the control.

If you do a "View Source" on an ASP.NET page you will see something like this:

var validator = document.all ? document.all["validator"] :
		document.getElementById("validator");
validator.controltovalidate = "answer";
validator.isvalid = "False";
validator.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid";

These lines add custom properties to the validators registered on the page, so we have to do the same also to specify the function name used to validate the CheckBoxList, using the RegisterExpandoAttribute method:

Page.ClientScript.RegisterExpandoAttribute(ClientID, "evaluationfunction",
					"cb_verify");

which will add the following code to the page:

checkboxListValidator.evaluationfunction = "cb_verify";

Add the RequiredFieldValidatorForCheckBoxLists to the page

Register the control and then add it to the page

<%@ Register TagPrefix="CC1" Namespace="Custom.Validators"
    Assembly="Custom.Validators" %>

<CC1:RequiredFieldValidatorForCheckBoxLists
    ControlToValidate="answers"
    runat="server"
    ID="checkboxListvalidator">*
</CC1:RequiredFieldValidatorForCheckBoxLists>

Download the complete file

Here is the complete RequiredFieldValidatorForCheckBoxLists.cs file, also without all the extra new lines I added above to make long lines fit into the width of the main column.

Technorati tags: , ,

ORM vs HandCoded DAL: Adding a new field to a table

In a World of constantly changing requirements adding a new field to a table is pretty common task: a new user profile field, a new flag to control the display of something, some other customization parameter.

Let's see the steps involved in this easy task, both using an ORM (I'm using NHibernate) and using an hand made DAL.

Task NH HandCoded
Add field to the table 1 min 1 min
Update DB script file with the new field 1 min 1 min
Add property to Object (DTO) 1 min 1 min
Add rule to NH mapping file 1 min -
Find and change Insert and Update SPs - 2 min
Find and change all select SPs that return that table - 2 to 10 min
Update the SPs script - 2 to 5 min
Change the CRUD methods of the DAL - 15 min
Fix the misspellings of the SPs parameters or table fields - 5 min
Time spent complaining about having to add a new field and how boring and repetitive the task is - 15 min

Total:

4 min 45 min to 1h

Total time with NHibernate4 minutes (3 if you use the attributes for the mapping).

Total time with an hand coded DAL: 45 minutes to 1 hour (using a well designed DAL, and only 1 database, using for example MS SQL and MySQL will lead to almost twice the time)

I used NHibernate as example, but the same applies to all other ORM and Entity Frameworks, and, at some degrees, also to code generation.

Technorati tags: , , ,

How NOT to prevent SQL Injection

This is the best anti-pattern about security and SQL Injection on the web. Today I found, via <edit>, html.it blog, a CMS that use a "creative" approach to get data from the DB: passing the SQL string directly as querystring to the page. Here is an example:

newssearch.asp?strSQL=SELECT+*+FROM+news+WHERE+(+lingua+%3D+'ENG')

And if you search on Google for "allinurl:sql select from where", you will find heaps of pages that use this approach (tonight the results were 111.000). I found sites built in ASP Classic, PHP, cgi, Perl, seems quite a widespread technique.

What if someone writes DROP TABLE NEWS instead of SELECT ...?

Technorati tags: ,

kick it on DotNetKicks.com

Microsoft Presenter Mouse 8000

I just bought a new mouse: the Microsoft Wireless Notebook Presenter Mouse 8000.

And I'm really impressed by its precision, and the smoothness of the movements. Maybe a bit too small for everyday use, but is a good solution as portable mouse, since it comes also with a carrying case.

But it is not only a Bluetooth optical mouse, is also a laser pointer, and a remote control that works both in "media mode" and in "presenter mode".

In media mode you can play, pause, skip, control the volume of movies and songs, and in the presenter mode you can navigate through the slides.

And with 10 meters of Bluetooth range, it can really be a basic media center remote or a good companion for presentations.

bag mouse

If you want to see my new mouse in action, come to my presentation about Vista Sidebar Gadget development in September.

Technorati tags:

LinkLift Control: here is the code

Last weekend I released a small ASP.NET User Control to display the Text Links provided by LinkLift. I also promised that I would have released the code for it. This weekend, among other things, I cleaned it up a bit, I fixed a small bug and here it is:

Download the source of the  LinkLift ASP.NET control.

I also set up a project on Google Code to store all my opensource projects that are too small to have their own repository, and I called it, ala Ayende, CodeClimber.Commons. And will move all my personal code on it soon.

Technorati tags: , ,

CruiseControl.NET Monitor Vista Gadget, version 0.9.5

Another weekend, another release: today is the turn of my CC.NET Monitor for Vista Sidebar, which hits version number 0.9.5.

This new version is very close to what I've planned for the final 1.0: a lightweight replacement of CCTray that runs on the Vista Sidebar.

The main feature introduced with this version is the autoscrolling of the projects when in docked mode: if you enable this new feature, the list of all the projects you are monitoring will automatically scroll and loop through all the projects.

I also added some improvements in the usability and error reporting:

I also changed the icon that is displayed in the list of all installed gadgets, which is also more appealing than the previous one:

drag

You can download the new version both on Google Code and on Windows Live Gallery.

The only feature that is missing for version 1.0 is the possibility to play an audio notification when the state of a project changes (Play audio notifications #3)

Anything else you would like to see in the CC.NET Monitor Gadget?

Technorati tags: , , ,

Peakr: social bookmarking for Climbing

logoDigg, del.icio.usDotNetKicks, StumbleUpon, Reddit and many other are all social bookmarking sites where users "save online" their bookmarks. So other users can see the bookmarks, and see which are the "hot" pages about a certain topic. Some of these sites also allow users to "vote" for the bookmarks, creating a sort of "popularity contest" where the most voted pages, posts or news should be the most interesting to read.

But all these sites are technology focused (dotnetkicks, digg) or very generic (del.icio.us, StumbleUpon)  so it's difficult to find articles about niche topics like climbing.

So, a French climber/developer, Francis Dierick, decided to built a social bookmarking site specific for climbing: Peakr

If you are into Climbing, and find some interesting news, video or post, please register and submit it to Peakr.

Or if you are looking for what's happening in the world of climbing and alpinism, but don't want to read 20 different blog or sites, this is a good site to read since it contains almost everything that is happening.

The site started only one month ago, so for the moment not many active users, but hopefully it will grow. They also give 1$ to a "well-known environmental group" per each user that register to the site, so registering will also do good for the planet and for the "outdoor climbing playgrounds".

Technorati tags: , ,

7 months of CodeClimber and 6 months in NZ

Almost seven months ago I started this blog in English, a bit more than 6 months ago I landed in Wellington and a few days later I started working for Calcium.

And furthermore, in a month (actually a little bit less) I'm going back to Milano to enjoy the end of northern hemisphere's summer and hopefully to do some good climbing.

So it's time to draw a line and make some considerations about the past.

First let's speak about the Wellington .NET user group

My fellows in Italy knew that even before coming to NZ I was more for a decentralized user groups and not for a big national user group, and now, after attending to 6 events in 7 months, and going to a few geek-lunches I'm even more convinced of that: I prefer short meetings with less people, the possibility to drink a beer and eat a slice of pizza while talking to the developer evangelist from Microsoft (Darryl) or discuss with everybody about one particular topic. I really like this type of meetings. Maybe the top-down meetings are good for someone new to the technology, but I prefer discussing and exchanging opinions with like-minded developers.

And another nice meeting is the weekly lunch with geeks organized by Ivan: I think these discussions are more valuable than sitting all day long listening to big names presenting or "teaching" how to write ASP.NET applications or how to migrate from VB6 to .NET. We speak about architecture, we speak about agile methodology, about RoR approach, about human side of development, about Apple.

And what about New Zealand?

Just 2 words: relaxed and easygoing. Sometimes too much relaxed for what I was used in Italy. But in Wellington there is such a great nature and landscapes at no more than 15 min of drive from the CBD. You are living in such a great environment, why should you get angry for some job related problems?

The only real problem is that the houses are built as if they were in a tropical island, with thin plywood walls, not double glazing, not central heating: but they are not a tropical island, and here in Wellington in winter you get a damn cold wind straight from the South Pole, and the temperature can be as low as 2°or 3°C with 20-30 knots of wind (which makes a perceived temperature of -6°C). Last weekend, if I were in Milano, I'd have said: "Questa è aria da neve" which sounds like "This is wind of snow", but the wind chill doesn't bring snow, only cold, a lot of cold.

Now my blog

I'm pretty happy with it: only 7 months of life and already more than 300 RSS feed subscribers, an average of more than 200 unique visits and a bit less then 300 pages per day in the last month. Ok, nothing compared to the 62000 subscribers to codinghorror, or even to the 4000 of Phil Haack blog, but still a good result for a 7 months old blog.

Following Ayende formula (views*15 + agg views*10 + comments*35) here is the list of my top 15 posts:

 

Title
V
A
C
Popularity

How to make a Gmail-like loading indicator with ASP.NET Ajax

5859
414
32
93145

Codename your releases

2962
298
7
47655

How to enable an ASP.NET WebService to listen to HTTP POST calls

2182
339
3
36225

Vista Gadget for CruiseControl.NET - CC.NET Monitor for Vista Sidebar 0.5

1914
368
11
32775

Here I am... writing in English

1718
294
3
28815

VS2005 SP1 installation: first try

1354
274
3
23155

How to refresh an UpdatePanel from javascript

1078 326 4 19570

Synchronize assembly version with CC.NET build number with NAnt

1074
237
5
18655

Easier editing of CruiseControl.NET config file with CCNetConfig

887
324
2
16615

8 things the Linux community doesn't get about the average computer user

742
368
1
14845

How-to add Lightbox v2 to a Subtext skin

746
320
2
14460

Ajax TreeView

745
292
3
14200

Breaking change in Subtext 1.9.5: update your custom skins

637
339
5
13120

iTunes causing VS to throw LoaderLock exception

659
314
2
13095

CC.NET Monitor for Vista Sidebar 0.7

560
392
5
12495

 

The most popular, with almost twice the popularity rating of the second, is the post about the Ajax UpdatePanel that has been linked by ScottGu in his first "useful links" post.

The experience of these 7 months, even if I was far away from my wife, the Alps, my friends, my parents and Milano, is positive, and so I'm happy that last year I decided to quit my job to move to Wellington.

Now I've another month of cold winds, lunch with geeks, and then I'll enjoy the end of the summer in Italy.

Convert a Unix timestamp to a .NET DateTime

The POSIX time, or Unix time, is the number of seconds elapsed from the midnight of January 1st 1970 in UTC coordinates.

This timestamp is used in all *nix languages; probably you will never need to use a Unix timestamp in .NET, but if you have to interact with other application or sites, maybe built in PHP or Java, you will probably have to deal with it.

But .NET doesn't have a method to convert a Unix timestamp to a DateTime and viceversa (or I didn't find it), so I had to implement it.

static DateTime ConvertFromUnixTimestamp(double timestamp)
{
    DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
    return origin.AddSeconds(timestamp);
}


static double ConvertToUnixTimestamp(DateTime date)
{
    DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
    TimeSpan diff = date - origin;
    return Math.Floor(diff.TotalSeconds);
}

The first method converts a Unix timestamp to its DateTime equivalent, and the second takes a DateTime and convert it to the Unix time.

And in order to get the current timestamp

ConvertToUnixTimestamp(DateTime.UtcNow)

Just a little note on the Unix time: this timestamp is implemented in most systems as a signed 32-bit integer, so can represent only dates in a the range −2,147,483,648 to +2,147,483,647, which means that on January 19th, 2038 the timestamp will overflow, bringing the date back to December 13th, 1901. This is known as Year 2038 problem. Hopefully most of the application we are building now will not last that long.

Technorati tags: , , ,

One of the smartest .NET guy in Wellington moves to Subtext

Ivan, the Belgian .NET developer and member of the Wellington.NET user group just moved his blog from DasBlog to Subtext.

He is a very smart guy, with lot of interesting opinions about development, not only .NET but also Ruby and other "cool" languages, so if are not already subscribed to his blog I encourage you to do so.

He also decided to stop developing nBlogr, his own blogging engine: it's always sad when someone decides to stop developing his own project for lack of time.

Hopefully Ivan will contribute to Subtext, and with the plugin framework we are adding to Poseidon, he will be able to do it without mastering the core of the engine, but only implementing an interface and subscribing to some events.

LinkLift control for ASP.NET

A few weeks ago I received a message from Valentina Baraldi, the Italian Country Manager of LinkLift, asking me if I wanted to take part in the beta testing of their Text Links.

At the moment they are hitting the Italian, German and Spanish markets, but they are delivering Text Links also in other languages (English, French, Polish and Portuguese)

Text links are a new way to monetize your blog, that should be more targeted then Google AdSense: the most famous company that delivers these kinds of links is text-link-ads. So I decided to give it a try since at the moment my blog doesn't have AdSense, yet.

But they are providing plugins only for a few PHP based CMS (Wordpress, Serendipity, Joomla, Drupal and "plain" PHP) but not for .NET or other platform, so, in order to implement it inside my blog, I had to build a control for ASP.NET.

And this the project I worked on yesterday at the SuperHappyDevHouse at Wellington.

Register for a LinkLift account

If you want to receive LinkLift text ads, first thing you have to do is register for an account, and then "Sell links" .

Once you added your blog you have to get your unique id. Since they rely on sending you a personal plugin with all the parameters already configured there is now way to find your "userId", so, to get your adspace id you have to go the list of all your pages, click on the "Download XML file" link and copy the url for it. The url of the xml file is in the following format:

http://www.linklift.it/external/textlink_data.php5?adspace=<adspaceId>&dl=1&

The <adspaceId> is what you need to configure the user control and get your links.

Install LinkLift.NET

Download LinkLift.NET, and copy the files into your web application. The zip file contains 3 files:

  • LinkLift.dll, this must be copied to the bin folder of your web application
  • LinkLiftTextAds.ascx, this is the web user control, and must copied inside your website
  • LinkLiftTextAds.css, the stylesheet with the CSS styles for the ads.

Add LinkLift.NET to your skin

Let's see how to add the LinkLift.NET control in a Subtext skin:

1 - Copy files on the server

  • Copy the LinkLift.dll file inside the <subtextroot>\bin folder of your Subtext site
  • Copy the LinkLiftTextAds.ascx file inside the <subtextroot>\Skins\<skinname>\Controls folder
  • Copy the LinkLiftTextAds.css file the root of your skin <subtextroot>\Skins\<skinname>

2 - Configure your skin definition

Open your skin definition (might be the skins.config or, if you have a custom skin, the skins.user.config), and the line marked in bold:

<SkinTemplate ....>
  <Scripts>
    ...
  </Scripts>
  <Styles>
    ...
    <Style href="linklift.css" media="screen" />
    ...
  </Styles>
</SkinTemplate>

3 - Add the control to the skin

Next (and last) step, edit the PageTemplate.ascx file, adding the reference to the LinkLift.NET control so that the Text Ads are displayed in all the pages of your blog.

Import the control at the top of the file:

<%@ Register TagPrefix="uc1" TagName="LinkText"
        Src="Controls/LinkLiftTextAds.ascx" %>

And then add the control where you want the links to appear in all your pages. I added it just before the main content region so it is displayed just under the header, but you might want to add it in the sidebar:

<uc1:LinkText id="ll" runat="server"
  Domain="www.linklift.de"
  FileName="~/Images/<blog_yourdomain_ext>/LL_<temporaryfilename>.xml"
  Adspace="<yourAdspaceId>"
  CheckAfter="1440" />

There a few properties you can set:

  • Domain: is the host name of the server you want to get the text links from
  • Filename: is the name of the file that will be created on your server to locally cache the link definition
  • Adspace: your unique identifier, the one retrieved during the registration
  • CheckAfter: duration of the local cache specified in minutes. After this time has passed the control will update the text link definition retrieving a new file from the server
  • WebRequestTimeout: timeout in milliseconds for the request to the server (not in the snippet above, and defaults to 7sec)

4 - Customize the style of the ads

Optionally you may want to change the style of the ads, for example changing the color of the text, or displaying 4 links per row instead of two as I'm doing now.

This is the default style:

   1:  ul.linklift 
   2:  {
   3:      margin:2px 2px 2px 0;
   4:      padding:2px;
   5:      width:100%;
   6:      overflow:hidden;
   7:      list-style:none;
   8:      border:1px solid #00704A;
   9:      border-spacing:0px;
  10:  }
  11:   
  12:  ul.linklift li
  13:  {
  14:      width: 48%;
  15:      display:inline;
  16:      float:left;
  17:      clear:none;
  18:      padding:1px;
  19:  }
  20:   
  21:  ul.linklift a
  22:  {
  23:      line-height:140%;
  24:      font-size:12px;
  25:  }

For example, if you want to change the number of links per row change the width value at line 14: 50% shows 2 per row, 100% one per row, 33% 3 per row, 25% 4 per row (mine is 48% because I've to take into account also a few pixels of padding and margin around)

Or to change the color of the border of the box change the value at line 8, or the set the color of the text add a color attribute in the style for the external <ul> element.

LinkLift.NET as Subtext plugin

I'm also working at a plugin version of this control, that will be shipped as part of the Subtext 2.0 download later this year. It will store the links inside the database (not as file) and will allow an easier customization of the appearance.

Where is the source?

Let me clean it up a bit, and I'll post it. Hopefully before the end of the week.

Technorati tags: , , ,

Back home from SuperHappyDevHouse Aotearoa

I just got back home from the SuperHappyDevHouse Aotearoa, which turned out to be quite a nice event: lots of coders, lots of Mac and Linux, a few .NET developers, free food, free drinks, free Internet wireless connectivity.

Nice chats with the other .NET developers, mainly about the "usual" topics: ORM, dynamic languages, Reflector (which I finally decided to install).

I also helped Ivan migrate his blog to Subtext, importing all his old posts from DasBlog using Ayende procedure, only to discover at the end that his hosting control panel cannot change the .NET runtime, so we rolled back to migration, and wait till some support guy manually change the .NET runtime to 2.0. And I finally added a few Wellington .NET blogs to my blogroll... about time smile_regular

During the day I also worked on a small project for Subtext: I implemented a control to display advertisements by LinkLift, a German Text Link Ads company that asked me to be a beta tester.

If you want to have a look at the party-like atmosphere of the SHDH you can have a look at the pics on Flickr: shdhnz (here, here, here and here pictures depicting me)

Technorati tags: ,

SuperHappyDevHouse Aotearoa

Tomorrow I'll be at SuperHappyDevHouse Aotearoa, the NZ version of the US SuperHappyDevHouse held monthly in the SF bay area.

I still haven't grasped what it is about, so I just report the "official" description:

SuperHappyDevHouse Aotearoa is inspired by SuperHappyDevHouse, a monthly hackathon event in the US, combining serious and not-so-serious productivity with a fun and exciting party atmosphere.

The whole thing is about rapid development, ad-hoc collaboration and cross pollination. Hardcore coders, l33t hax0r, passionate designers, and other types that enjoy software and technology development will be at home in the SuperHappyDevHouse.

This is not a marketing event. It's intended for passionate and creative technical people that want to have some fun, learn new things, and meet new people.

There will be 45 attendants (including Ivan Porto Carrero, the 3 guys from Mindscape, Darryl Burling and other 39 LAMP/Linux developers), a lot of lightning talks, from complex linux programming stuff to lighter "social" talks, and free food and drinks from 10am to 5pm.

From what I understood it should be a place where "creative technical people" meet, work on their projects, show them to the other guys, collaborate and maybe come out with some new ideas.

Probably I'll work more on Subtext Plugin Framework (unfortunately I don't have Vista on my laptop, so cannot work on the CC.NET Monitor Gadget).

Will tell you my impressions on the shdh in the next few days.

Technorati tags: , ,

How to install Subtext

Sometimes I receive mail from people asking how to install Subtext and how to move their old contents from their old blog.

Probably the "official" docs are a bit hidden, so here is quick list of all the resources available:

And now the migrations docs:

Hope this short list helps everybody that wants to move to Subtext. And hopefully will also help Ivan and Nic in their migration from dasBlog to Subtext smile_wink

Extending the UI of Subtext with Plugins

Today I published the 3rd article for Subtext plugin SDK quickstart documentation: Create a custom settings page.

This article explains how to write a web user control to collect data for the configuration of the plugin.

Here is the toc:

  • Create a Settings page
  • Load and store settings
  • Installing the plugin
  • What’s next

Now that the plugin framework API are pretty stable you can start write plugins for Subtext and help us with your feedback about the API.

So, go and grab the latest code from SVN, read the Quick Start guide, write your plugin, if you have problem have a look at the FAQs, post a question in the developer’s forum, and if nobody answers you contact me.

Will keep you post of new developments on the Plugin SDK.

Technorati tags: , ,

We have a winner!!!

The best regatta of the last 15 years of America's Cup... Alinghi won, but New Zealand was very close, and probably lost only because of bad luck with the spinnaker ripped in race 3, and just one second of difference in race 7. See you again in 2 years in the Mediterranean Sea.

Subtext nominated for the SF Community Choice Award

Thanks to everyone that nominated Subtext for the SourceForge Community Choice Award.

Nominations

Subtext has been nominated for 2 Awards:

  • Best Project for Communications: The best project for talking to your friends or sharing information (together with Miranda, Pidgin (ex gaim), FileZilla and others)
  • Most Collaborative Project: The project most likely to accept your patches and value your input (with Azureus, XOOPS, Zimbra, ADempiere)

This is already a big achievement for Subtext, but maybe we can do even better then just being nominated. A it is the only .NET project nominated for the final award.

How can you vote?

This is easy: just go to the vote page, look for the 2 categories above, select Subtext from the dropdown menus and click on the "Submit all votes" button, or click on the button below:

vote

How to clean your ASP.NET HTML markup with the CSS Adapter Toolkit

The HTML rendered by some built-in ASP.NET controls is ... ugly: lots of tables, nested tables, useless divs and spans, and sometimes even not compliant with accessibility guidelines for public sites.

What is the CSS Adapter

ASP.NET 2.0 has the Adaptive Control Adapter Architecture that allows developers to override the default rendering of the built-in controls for some specific browser (for example mobile devices or set-top box).

Leveraging this feature, the ASP.NET team released the CSS Adapter Toolkit, which was initially intended as example to show how to develop a control adapter, but then became the de-facto implementation to render some built-in ASP.NET control with a pure CSS approach.

With this adapter the asp.net menu will not be rendered as an HTML table any more, but as nice menu built using nested <ul> tags.

And the same CSS-only approach is used also for (if you click on the links provided you will see the before and after the CSS adapter treatment):

How to install the CSS Adapter

There are 2 different procedure to install it. One is easy, quick, error-proof, but not customizable, the other is longer and more complex, but gives you the possibility to change the rendering.

Let's start with the complex one: it involves a lot of steps, actually 22 steps. Since Fritz Onion explained the procedure very well, I link to his post for the complete step by step tutorial: Steps for adding a CSS Control Adapter. This is complex, but you will use the source code of the adapters, so you can change the way the controls are rendered.

Now the easy one, which is the procedure I followed to install the adapter for the web application I working on.

  • Download the CSS Friendly Adapter from CodePlex: http://www.codeplex.com/cssfriendly.
  • Reference the CSSFriendly.dll inside your web project.
  • Create the ASP.NET App_Browser folder under your website root, and copy the CSSFriendlyAdapters.browser file in this folder.

If you don't want to change the way the controls are rendered, or are not interested in understand how a control adapter is developed, I suggest that you adopt the easy procedure: in less then a minute the HTML markup of your ASP.NET application will be much more polished, more compliant to the latest Web 2.0 trends and public accessibility guidelines.

Technorati tags: , ,