Tigraine

Daniel Hoelbling-Inzko talks about programming

New stuff in .less

Do you remember that little project I am involved in? That .less thingy I always forget to write about? Well, it’s still around and we are going very strong. We are seeing a decent amount of activity on our mailing list and people throw code at me at various occasions for fixing different problems within the the project.

One of those persons is James Foster, a really nice guy from the UK with some mad programming skills who set out to make .less awesome. Well, he sort of did already, by contributing some major code changes to the .less parser that enabled him to port over some SASS functions to .less. Sadly he does not blog himself, so the honor is mine to report to the world what he did.

Color functions

Before going into details, the main idea is that you are now able to modify any component of a color separately. So far .less has only supported arithmetic operations on colors (like #abc000+ #000def => #abcdef) so if you e.g. want to darken a color while adding 10 points of green to it you where out of luck, making the feature not really all that useful. Well, thanks to James now we can!

Creating colors

.less understands that #FFFF is supposed to be treated as a color, so if you start working off web colors you can just use the hex notation and ignore the following functions. In case you are more the designer type settled in the RGB world and want to have lightness and alpha around, you will need functions to create the colors. And while at it James also added color literals so .less detects a @color: blue; instruction just like it would a @color:#0000FF one. Anyway, if you have your colors RGB or HSL you need to use the following functions to create them:

rgb(red, green, blue) rgba(red, green, blue, alpha) hsl(hue, saturation, lightness) hsla(hue, saturation, lightness, alpha)
You might guess from the parameter names how they work. But to be thorough:
@mainColor: rgb(0, 0, 255); //Blue
Modifying colors

Now, once you hold on to a variable that contains a color you can do some pretty exciting stuff with the following color manipulation functions:

red(color, value) green(color, value) blue(color, value) hue(color, value) saturation(color, value) lightness(color, value) alpha(color, value)

the value can be positive or negative, for instance, to darken a color by 20% you can use "lightness(color, -20%)".

You pass in a color and then the amount you want to change it. If you omit the change value part the method will return the appropriate component of the given color (meaning: red(@color) will return the red portion of that color, while red(@color, 10%) will increase the amount of red by 10%).

And while at it, James also added some convenience functions for good measure to make your day easier:

greyscale(color) this is equivalent to saturation(color, -100%)

complement(color) this is equivalent to hue(color, 180)

mix(color1, color2, weight) mixes 2 colors together. The weight argument is optional and specifies the percentage of the first color to use compared to the second color. it also takes into account transparency - if a color is more transparent it has less effect on the resulting color.

You can get all of that functionality through the latest .less build from our website http://www.dotlesscss.com or just grab the code from GitHub. If you have any questions or suggestions feel free to participate through our mailing list.

And lastly, let’s give credit where credit is due: Thanks to James for the great work he put into .less. James himself stated that he based most of his work on stuff he saw on the Sass project, you can read about their color functions implementation here: Powerful Color Manipulation with Sass. The initial code for Sass was created by Chris Eppstein for the “compass-colors” project which has now been merged into the main Sass codebase. You can also see his pretty impressive demo here: http://chriseppstein.github.com/compass-colors/

dotless Presentation slides from Barcamp Klagenfurt

I just finished my presentation about dotless at Barcamp Klagenfurt and promised to upload my presentation slides to Slideshare.

The feedback for the talk was quite good. Turned out better than I hoped. I just hope that the slides do make some sense without me talking alongside.

Presenting .less at the Barcamp Klagenfurt 2010

Barcamp Klagenfurt 2010

Time goes by way faster than I’d like it to and the Barcamp Klagenfurt 2010 is coming up really fast. (6-7. February)

While usually I was quite hesitant to choose a topic due to the diversity of the attending crowd (unfortunately not really enough real technical topics represented there), this year I think I can bring something very interesting to the camp: .less.

The advantages are obvious, with a crowd of bloggers, artists and also technical people talking about something as ubiquitous as CSS, and ways to improve it, will surely resonate well, allowing me to be a bit technical without raising too many question marks above my audience’s heads like last year (where I talked about IoC and Windsor).

As for the talk itself, I plan on first going over general features of Less (since we are a port I can also point people over to the Ruby version if they are more comfortable with that than with .NET ), and then into a tiny bit of detail about how .less works internally.

Finally, I hope to see as many people as possible at Barcamp Klagenfurt! Thanks to the team for organizing this year after year!

Filed under barcamp, dotless, personal

.Less now supports files from the VirtualPathProvider!

Ok, I’ve just spent almost the whole day refactoring the hell out of our .less codebase just to add one tiny change:

Allow users to not only load files present on the current file system, but also directly from in-memory strings and VirtualPaths (as requested on the list). The problem here being that not everyone wants to serve his .less files right from the server’s file system but sometimes people have pretty sophisticated virtualized storage systems in place that require them to use the VirtualPathProvider abstraction that was added to .NET 2.0.
You can read up on that in ScottGu’s blog or David Ebbo’s blog, but in a nutshell it’s just another way to open files besides using System.IO.File.Open(), letting you forget about all the nasty stuff of where the file is really located. 

To do so I had to allow uses to plug in different “Sources” for .less code, and so I also had to make a breaking change to the main ILessEngine interface. The Interface was taking a filename as parameter, but in light of our recent support emails on the development list I decided that has to go away in favor of a more open approach (mainly to allow users to simply throw in-memory strings at the engine).

Because I know this will break some code, all implementors of ILessEngine still offer the old string parameter as an overload that then defaults to the default FileSource.

Now, for changing the source provider:

If you want to use anything besides the default filesystem based FileSource provider, you now have the ability to plug in a type implementing ILessSource through the DotLessConfiguration (thus through web.config).
.Less comes with three sources built in: VirtualPathSource, FileSource (default).

FileSource by default just opens a file through System.IO.File, while VirtualPathSource will use the HostingEnvironment.VirtualPathProvider.GetFile() method to open a Stream and read the .less code from there.

To enable the VirtualPathSource in your web application you simply need to modify your web.config a bit:

<dotless minifyCss="false" cacheEnabled="true" source="dotless.Core.VirtualPathSource">
  
</dotless>

The important part is the source attribute as it has to reference a type name implementing ILessSource. So if you want to create your own less source you could simply create another implementation of ILessSource and reference it’s name in the .less config.

If you want to use .less directly from your code to transform something you can just new up a LessSourceObject (the very output we get from ILessSource) and throw your code in there like this:

ILessEngine lessEngine = new EngineFactory().GetEngine(new DotlessConfiguration());
var output = lessEngine.TransformToCss(new LessSourceObject() {Content = "my .less code here"});

As always you can get the latest code from GitHub, or the latest binary release through our TeamCity build server. You can read more about .less (pronounced dot-less) on the project’s website at http://www.dotlesscss.com.


And while at it, we’d appreciate it if you spread the word about .less :).

Pandora used in dotless and moved to GitHub

Pandora, my personal IoC Container (mostly written for educational purposes) has recently been integrated into dotless. This has helped us improve the design of dotless without having to take on a big dependency like Windsor or StructureMap.

I chose to implement Pandora through the Common Service Locator interface by Microsoft, so if we ever feel restricted by Pandora we can easily switch to a more potent container without touching the actual dotless code.

This step also made me bring the Pandora repository from mercurial to git with some help from Horst. He was kind enough to run hg-fast-import for me.

Pandora can now be found on GitHub with a similar build process as dotless and elms-connector.

Pandora on GitHub

The joy of working with dotless

Ok, I just spent some time on the imagineClub website adding our board’s bio page. The HTML is not really interesting, but since imagineClub was written while dotless was still in development I wrote the CSS the old fashioned way.

Since dotless has reached some maturity I’ve been dogfooding it on imagineClub to make use of the minifier and the caching, but never had any real LESS code in there.
When I had to fix something today I was so happy to be able to write CSS like this:

div#team
{
    width: 414px;
    p
    {
        float: right;
        width: 300px;
    }
    h2
    {
        clear: right;
        font-size: @title-fontsize - 4;
    }
    img
    {  
        width: 100px;
        margin-bottom: 4px;
    }
}

This is how CSS was supposed to be, and with dotless it has become just mindlessly easy to do..

Setting up TeamCity + git + psake for dotless

Let me say one thing upfront: Setting this up has been a HUGE pain in the ass (PITA for short), and I really hope this gets fixed sometime in the future, because those 3 hours I just spent getting this done are never coming back..

Ok, just to make sure everybody understands: dotless is built using a PSake build script that has to be run through Powershell. The script itself calls out to git and therefore relies on git being installed into the PATH.

First: Git-Teamcity

Since our build relies on executing a git command during build the official JetBrains plugin doesn’t cut it (it only copies the sources, not the .git folder). So I downloaded git-teamcity from GitHub and built it using maven (at least something worked).

After that I followed this tutorial on how to install the plugin on TeamCity:

  • package the plugin by following the steps outlined in file pkg in the Git plugin folder: create a foldergitAgent/lib in the folder target, copy all the .jar files (should only be Git-vcs.jar) to this folder, and then zip gitAgent to gitAgent.zip
  • deploy the plugin by following the steps outlined in file deploy in the Git plugin folder: copygitAgent.zip to \webapps\ROOT\update\plugins, and copy Git-vcs.jar to\webapps\ROOT\WEB-INF\lib

Well, after setting up a new VCS Root inside TeamCity the most important part is to set the VCS checkout mode to “Automatically on agent (if supported by VCS roots)”

image

Warning: Also make sure that you have git installed at C:\Program Files\git, because that is the only place git-teamcity will look for the bin (unless you change the code).

Second: Execute Powershell

Apparently there is some major bug with the ConsoleRunner inside TeamCity so all attempts to simply run the Powershell didn’t work. Directly invoking Powershell led to the build timing out. After some digging I found this thread that explained the problem and hinted at a possible solution: Touble with Powershell and NAnt during build

So, I created a .bat file called TeamCity.bat that calls Powershell directly from it’s full path (C:\Windows\System32\…) like this:

C:\WINDOWS\system32\windowspowershell\v1.0\Powershell.exe .\psake.ps1

But this doesn’t work due to the above bug in TeamCity. The build kept hanging and eventually got terminated due to an timeout. So I had to change it to something like this:

echo abc | C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe .\psake.ps1

Putting echo in front of it made it work, I have no idea why, but id worked.
Now the next problem came up: although I explicitly ran Set-Executionpolicy on the box the runner’s executionpolicy was not set. So I added the Set-Executionpolicy to the .bat file:

echo abc | C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe Set-ExecutionPolicy remotesigned
echo abc | C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe .\psake.ps1

Now, finally the script was executing, but due to no environment variables, my buildscript could not locate git (due to the ConsoleRunner not having ANY environment variables present).

The final version of my TeamCity.bat then included a change to the PATH variable and it finally worked:

Set "path=%path%;C:\Program Files\git\bin" 
echo abc | C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe Set-ExecutionPolicy remotesigned
echo abc | C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe .\psake.ps1

At that point the build was finally executing and I then only had to tell TeamCity where to find the build artifacts and I was done.

Conclusion

Now that it works, I’m glad I took the time to set it up. But the process could have gone smoother.
Anyway, the good news is:

You can now get a release version from every future commit to the dotless repository right from our dotless TeamCity server!

My Photography business

Projects

dynamic css for .NET

Archives

more