drunktender lives!

Much like everyone else, I get distracted and need to clean off my desk from time to time.  In doing so, I discovered my nice little relay circuit board that needed some rewiring after it was tweaked for a small issue that made me pull it.  The old wiring that was used previously was thicker and hard to manipulate.  This made working on the boards hard and more difficult than needed.  On top of that, the wiring was slightly too large for the connections on the boards.  I grabbed some wiring I had from the skateboard instead of strapping 100% of the wiring so now everything should work a lot nicer.  The new wiring is a smaller gauge and is far more flexible.

IMG_2105

This project would be far higher of a priority if I lived in Seattle or Chicago, no doubt.

Creating a SubText Skin

Since 10 Volt Media created the HTML and CSS for my new skin per my request and nothing else, I’m having to create a new SubText Skin from scratch.  Fear not, this won’t be too hard of a process.  Well, it turns out, it slightly is.

Step 0.)  Have a local copy

I do not suggest doing this on a live copy of your server.  Too much goes wrong too quickly.  Do not do this on a live server.

Step 1.) XML

Head into your Subtext.Web project then to the Admin folder to find Skins.Config.  This is the file that tells the system what skins are what along with how items should be loaded.  I’ll constantly be going back to this file adding files in.

So I’ll add in a new SkinTemplate.

<SkinTemplate Name="Better Than Everyone v2" 
  TemplateFolder="BetterThanEveryone_v2">
</SkinTemplate>

Looking at other skins, you can see items can be loaded based on browser and version along with if it is being printed or is a screen.

Now I have a reference so lets create the folder.  In the SubText.Web project, we’ll go to Skins folder and for me, I’ll add the folder “BetterThanEveryone_v2”.

Step 2.) Base Files

We told the application we have the skin, now we need to get it up and working to a bare minimum.  The files will be within the “BetterThanEveryone_v2” folder.  I suggest cheating and copying from the Naked Skin (day.ascx has postcategorylist.ascx also if you do this)

These are the bare minimum files needed:

  • controls/homepage.ascx
  • controls/daycollection.ascx
  • controls/day.ascx

These are just the bare bones.  We’ll want to create a master page template to get a unified theme across all our pages.  This file will be called the PageTemplate.ascx and lives in the root level of your custom skin folder, not in controls.

Since to make my life easier and I’m borrowing base files from another skin, you’ll see a bunch of the controls that are referenced aren’t referenced yet but that isn’t that big of a deal.  We’ll add them later.  What I am going to do is comment out everything except

<dt:contentregion id="MPMain" runat="server" />

Why?  This will have the page still load.

Now not all functionality will still work.  Things won’t work still like

Step 3.)  Remembering how to code

I’m not being sarcastic here since not everything is very clear.  You’ll need to look in some CS files to know how certain things will act.  I also suggest checking out how the other skins work and look.

This is important as certain base controls work different than one another.  An instance of this is for the PreviousNext control again.  It has an attribute you can use for max text size called TextSizeLimit.  Had I not checked the base control, I would not have realized this handy addition.

Step 4.) Things to watch for

I ran into the following error when I was working with PostComment.ascx.  I used <%= instead of <%# and was given this error:

The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).

Also verify your search skin has the proper appearance.

Step 5.) For my skin, all needed files … I think.

controls\ArchiveDay.ascx
controls\ArchiveMonth.ascx
controls\CategoryEntryList.ascx
controls\CategoryList.ascx
controls\Day.ascx
controls\DayCollection.ascx
controls\EntryList.ascx
controls\Footer.ascx
controls\Header.ascx
controls\HomePage.ascx
controls\MyLinks.ascx
controls\PostCategoryList.ascx
controls\PostComment.ascx
controls\PreviousNext.ascx
controls\ShareThisPost.ascx
controls\SingleColumn.ascx
controls\SubtextSearch.ascx
controls\ViewPost.ascx
PageTemplate.ascx

This should be everything, some are extra but like the header and footer.  Certain items are there for base functionality, others are there to make the site usable.

Step N.) Learning SubText to make it easier

It can semi act like WordPress by using the DataBinder expression.  This means you need to know what data is coming back.

In my CategoryList.ascx, I used just this to allow me to dynamically pop in CSS classes.  This bit of code uses regular expressions to strip out non-alphanumeric characters.

<%# Regex.Replace( DataBinder.Eval(Container.DataItem, "Title").ToString().ToLower(), "[\\W]", "") %>

Step N + 1.) The next step?

The one thing I’d like to see is having SubText post back without ASP.NET controls.  This allows me not to know or care about which controls must be on the page for it to work, all I need to know is what my input control needs to be named and what fields are in the data returning.  On a “base skin”, list the data getting returned so one can do the binding rather than all the literals and labels.  Not sure how Phil Haack and company will like what I want to do but I’ll pass by the idea.

Reskinning progress

Progress after a day is pretty good.  I had to actually dive into the code a few times with SubText to fully understand how to do the skin properly as it wasn’t straight forward.  I’ll do a post but I think if you really want to do a skin, you’ll have to be able to understand ASP.Net at some level.

Here is a localhost version of the skin after a few hours of hacking.  I still need to do the comment section and properly do the right navbar.  I have to tweak the header a bit too and get the search working too.

image

After this comes me attacking SubText to add in pagination on the home page.  I also fixed, in my opinion, a bug in the PreviousNext control.  I don’t think it is coded properly, but is shouldn’t assume I have to use a worthless control on my page just for formatting.

Here is what they did:

LeftPipe.Visible = false;                            
SetNav(NextLink, entries[0]);

My fix:

if (LeftPipe != null)
    LeftPipe.Visible = false;                            
SetNav(NextLink, entries[0]);

Now the bigger issue is why that control even exists on the control and why they didn’t use FindControl instead of hard coding it in there like the other controls.  An example of what I’m talking about is this from the Header.cs:

if (null != this.FindControl("HeaderTitle"))
{
    HeaderTitle.NavigateUrl = HomeUrl;
    HeaderTitle.Text = Title;
    ControlHelper.SetTitleIfNone(HeaderTitle, "The Title Of This Blog.");
}

This code is far more defensive and doesn’t make the assumption that control is there.  However, I got away with just checking for null.  Here they are far more verbose.  To be honest, I’m not sure why they didn’t just check for null here too as they don’t set the control anywhere from FindControl also.

And yes, I’m fully aware I coded on a Friday night instead of going out.  In my defense, it is cold and very wet outside.

Coding4Fun Book!

Coding4Fun the book 

Little close up!

I'm an author!

You can buy the Coding4Fun book at Amazon and get the source code at www.c4fbook.com.  Thanks O’Reilly Publishing!

What was big and clunky is now small with LINQ

Don’t tell anyone but I’ve realized there are people smarter than me.  I’ve been slow like most getting up to speed with the new technologies, one being LINQ.  The demos I’ve seen of it have always been SQL based.  SQL and myself never really liked one another so LINQ has always been something I gave the evil eye to.  I knew it was powerful, just didn’t realize how wide spread it actually is!

So I wanted to grab a few unique images from a directory on a computer then out put them to a user.  Now the code to do this was big and could be slow but there are algorithms out there to make this faster.  Now what if there was a way to have this magically be done for me?

Old Code:

private string getUniqueFile(string[] files, 
    string currentMapPath, params string[] usedNames)
{
    string randomName = "";

    for (int i = usedNames.Length - 1; i >= 0; i--)
    {
        if (i == usedNames.Length - 1)
            randomName = getRandomFile(files, currentMapPath);

        if (randomName == usedNames[i])
            i = usedNames.Length;
    }

    return randomName;
}

Random random = new Random((int)DateTime.Now.Ticks);
private string getRandomFile(string[] files, string currentMapPath)
{
    return files[random.Next(files.Length)]
        .Remove(0, currentMapPath.Length + 1)
        .Replace("\\", "/");
}

New Code with LINQ:

private string getUniqueFile(IEnumerable<string> files, 
    string currentMapPath, params string[] usedNames)
{
    return getRandomFile(files.Except(usedNames), currentMapPath);
}

Random random = new Random((int)DateTime.Now.Ticks);
private string getRandomFile(IEnumerable<string> files, string currentMapPath)
{
    return files.ElementAt(random.Next(files.Count()))
        .Remove(0, currentMapPath.Length + 1)
        .Replace("\\", "/");
}
 

So the big thing we see here is how small the new code is.  Also how much more readable it is.  Also someone far smarter than me created the algorithm for the Except method.

As you can see, LINQ isn’t just SQL like styles, it is built into collections so use it!  It will make your life far easier.

New Skin, same ego

My friend Jeff Couturier over at 10volt Media helped re-skin my site for me.  This will be going online shortly.  It is now CSS 2.1 and XHTML 1.0 Transitional valid too!

Here is a quickie shot of it.

image

Now, on top of that, I’ll be adding in some eye candy upgrades such as using Lightbox for images, JQuery for certain things, and a new code output highlighter.  And since I love using Windows Live Writer, I’ll need the the plug-in.  I’ll also be adding in some minimizers to reduce the size of the CSS and JS.

In addition to this, I will do my best to track down some time to help add in paging support in SubText’s home page.  It took a while for me to get a dev environment again on my laptop but now that it is there, it is all night donkey kong.

But seriously, how sweet is my new logo?

Upgrade time!

8206134_e3df7a23d7[1] I upgraded my blog to Subtext 2.1.0.5 today along with upgrading my mail server 2 days ago.  I discovered a few interesting things in my failures.

First thing is if you want to do something creative is to test before you attempt to deploy live.  I should have tested upgrading subtest to .Net 3.5 before just shoving it on my live server.

Secondly is to merge your Skins.config with the new one if you have a custom skin.  The new skins.config has a mobile phone skin that you won’t want to live without.

Next is to trim your database.  Phil Haack talks about how to shrink your SubText database size on his blog.  I had to tweak my database name as it isn’t Subtextdata.  I also emptied my error logs.  Doing all these brought my database from 120mb down to 20mb!

Since Subtext included new features for Live Writer support, you’ll have to refresh your settings in Live Writer.  This is super simple.  All you need to do is go to Weblog->Edit Weblog Settings then click “update account configuration”.  Then you just click “next” the 5 or so times and bam, you’re all good.  If you’re like me, you’ll want to turn back off the Using theme view by going to View->Edit using Theme

Thanks Phil for the awesome update.  Now I do believe I’ll be adding in home page paging.

Better Than Everyone now works on mobile devices too!

subtext 2.0 upgrade fail

image My attempt to upgrade my blog engine from Subtext 1.9.5 to Subtext 2.0.1 failed tonight so there may have been a bit of triage as I attempted to roll back.

Things I learned but forgot about doing deployments.

  1. copy all files to server in a different directory first
  2. copy current app directory on SERVER
    1. doesn’t hurt to have a local copy too
  3. verify you have done those two steps in case of failure

I FTP’ed up my files to the running app directory like a stupid, stupid person and didn’t have a local server back up.  So it took me better part of a few hours to get everything corrected again.  It was one of those crashes you just can’t look away from.

Subtext 2.0.1, I’m gunning for you tomorrow night.

MORE COWBELL, we need more windows mobile cowbell!

More-Cowbell Just did an article on how to create a full blown cowbell windows mobile professional application over at Coding4Fun.  Shows how to do pInvoke calls, touch screen, image resizing (in source, not in article), resource embedding, creation and deployment.

Read the article out and play with the source code.  Also if you want some other windows mobile intro level topics, I have a tag called “Getting Started with Windows Mobile” that has everything I’ve learned step by step.

My PDC 2008 Coding4Fun Talk

image

I had the chance of a life time on Tuesday and got to be a speaker at PDC 2008 with the Coding4Fun talk.  The session had some amazing presenters and was extremely time boxed due to 4 demos in 40 minutes. 

I start at 29:18 and talk about TwitterVote.  Some of the other topics are:

  • WiiEarthVR – Brian Peek
  • InnerTube – Dan Fernandez
  • BabySmash – Scott Hanselman

For the full video, head over to Channel9.

  • About
  • Clint Rutkas: I build stuff that will eventually hurt me. I'm your average nerd.
  • Follow Clint on Twitter