Pingly – a Roxen module for automatic Twingly pinging
Twingly is a blog search engine that focus on indexing the “blogosphere” rather than being a generic search engine. Twingly has a ping service that let you ping Twingly when you have new content on your blog so that Twingly can head over there and index the new content asap.
Since Roxen CMS have event hooks this module listens for newly published files and when found automatically notifies Twingly about it.
The only thing needed is to set up a config file in the SiteBuilder’s workarea so that this module knows under which paths newly published content should notify Twingly and with which arguments. But all this is documented in the module.
One note! If you run a replicated environment install this module on one of the frontend servers, not the backend. If installed on a backend Twingly might head over to your site before the new content has been replicated.
JavaScript minifier filter module for Roxen
Nowadays web sites and web applications tend to be more and more JavaScript driven which results in humongous JavaScript files. It’s not uncommon to have several 100 of bytes of JavaScript on a site. Of course web browsers cache stuff like JavaScript so that it only is requested from the server once. But judging from the visitor logs at work most people only visit our site once a month or so which means that cache will expire and all those scripts has to be requested upon the first visit.
Now, there are several ways to compact JavaScripts: Packer, YUI Compressor, Shrink Safe, jsmin and many more. Some of these just remove redundant white space and comments, some obfuscates the code and shortens variable and function names and what not. Many of these scripts and programs are very fine but they require you to manually minify your scripts, and that’s just a hassle!
But since we use Roxen CMS at work things get much easier if you write your own Roxen filter module which automatically minifies JavaScripts on the fly, given they meet certain criteria. And so I did!
I ported the original jsmin code written in C to Pike. Then it was just a matter of creating a simple filter module for Roxen. And then it was all done.
You can use two criteria to determine if a script should be minified or not:
- Path glob: In the module settings you can specify any number of directory globs or full paths. If a requested JavaScript either is in a directory matching a glob or is a direct match it will be minified.
- Query string variable: In the module settings you can define a variable name that if exists as a query string variable in the request the JavaScript will be minified. So:
<script type="text/javascript" src="myscript.js?jsmin=1"></script>
will minify
myscript.js
And that’s that!
Roxen Application Launcher 0.4.5
Okey, here comes an update of my Roxen Application Launcher (come again?) for Linux.
There’s no major changes to this release. The connection to the Roxen server is now stored in a shared object so that it can use a “keep-alive” connection. Not that I think it matters a great deal.
There’s now an option to change the behavior of the applications window close button so that it hides the application to the tray – or notification area as it’s called in Gnome – rather than closes the application.
More Vala programming to the people – Sources at Github.
Roxen Appliction Launcher 0.4.5 23:00, Tue 13 April 2010 :: 375.9 kB
Roxen Application Launcher 0.4.4
So, here’s a new release of the Roxen Application Launcher for Linux (RAL). The previous versions used my home made (sloppy so) HTTP client which didn’t handle redirects or secure connections – thank you tec for the feed back – since I had some major problems getting libsoup working with binary files like images and such. Binary files was heavily scrambled when read from or written to disk so I made my own simple HTTP client that kept the data as a byte array to prevent some underlying libraries (GLib) from fiddling with it.
But I solved the libsoup issue so now the RAL handles redirects and secure connections. This is how I solved it:
The libsoup issue
When uploading a file back to the Roxen server I use IOChannel (g_io_channel in plain C) instead of Gio. So the upload works like this:
- var sess = new Soup.SessionSync();
- var mess = new Soup.Message("PUT", get_uri());
- mess.request_headers.append("Cookie", get_cookie());
- mess.request_headers.append("Translate", "f");
- IOChannel ch = new IOChannel.file(local_file, "r");
- ch.set_encoding(null); // Enables reading of binary data
- string data;
- size_t len;
- ch.read_to_end(out data, out len);
- mess.request_body.append(Soup.MemoryUse.COPY, data, len);
- sess.send_message(mess);
And that seems to work like a charm!
When downloading data it’s a bit more tricky! Of course I tried using IOChannel in this case also but that made no difference. Downloaded images ended up 4 bytes long! But then I thought: You can make your own C bindings in Vala (remember the Vala compiler generates C code) through what is called Vapi files. So what I did was writing a C function that takes a SoupMessageBody object/struct passed from Vala and writes the data part to a file given as argument.
- gboolean save_soup_data(SoupMessageBody *data, const char *file)
- {
- FILE *fh;
- if ((fh = fopen(file, "w")) == NULL) {
- fprintf(stderr, "Unable to open file \"%s\" for writing!\n", file);
- return FALSE;
- }
- int wrote = fwrite(data->data, 1, data->length, fh);
- if (wrote != (int)data->length) {
- fprintf(stderr, "wrote (%d) != data->length (%d). Data may have been "
- "truncated", wrote, (int)data->length);
- }
- fclose(fh);
- return TRUE;
- }
And this was then made available to Vala by the following Vapi file:
- [CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "")]
- namespace Soppa // Soppa is Swedish for Soup ;)
- {
- [CCode (cname = "save_soup_data")]
- public bool save_soup_data(Soup.MessageBody data, string file);
- }
And this is how the actual Vala code downloading the files looks like:
- var sess = new Soup.SessionSync();
- var mess = new Soup.Message("GET", get_uri());
- mess.request_headers.append("Cookie", get_cookie());
- mess.request_headers.append("Translate", "f");
- sess.send_message(mess);
- if (mess.status_code == Soup.KnownStatusCode.OK) {
- // Here I call the C function made available through the Vapi file
- if (Soppa.save_soup_data(mess.response_body, local_file)) {
- message("The file was downloaded and written to disk OK");
- }
- else {
- message("Failed writing data to disk!");
- }
- }
So that’s that on that!
The notification
I also – just for fun – implemented a notification mechanism through libnotify. Since I believe that can be rather annoying it’s not activated by default but can easily be activated by a checkbox in the user interface.
The packages
The Roxen Application Launcher for Linux can be downloaded at the download page at Github where also the work in progress sources is available or downloaded below!
Roxen Application Launcher 0.4.4 23:06, Wed 13 January 2010 :: 373.5 kB
Stay black!
New Roxen Application Launcher for Linux written in Vala
A couple of weeks ago I stumbled upon a fairly new programming language named Vala. I thought it looked promising and since Vala is developed by the GNOME project – with the purpose of making software development for, primarily, GNOME easier – and I’m an avid GNOME user I wanted to look deeper into the world of Vala.
I, and most programmers I believe, work in that way that I need a real and useful project when learning a new programming language. So I thought why not re-writing the Roxen Application Launcher I wrote in C#/Mono a couple of years ago in Vala – which by the way is syntactically very, very similar to C# and Java. I’d gotten tired of always having to fiddle with the C# code with every new version of Mono since something always broke when Mono was updated so a re-write wasn’t going to be totally pointless. The good thing about Vala is that the Vala compiler generates C code and that’s what you compile the program from. Fast code and hopefully more mature and stable libraries that won’t break backwards compatibility with every new release.
What about Vala
So, on I went about it and I think that Vala is a really promising language. It’s still a very young language so some library bindings isn’t behaving exactly as expected and the documentation isn’t directly redundant – although the Vala reference documentation site isn’t half bad. But since Vala pretty much is a wrapper for, or binding to, the underlying C libraries you can find answers to your questions that way. All in all I think Vala has a promising future: Way more simple than C and almost as fast and light on memory (remember the Vala compiler generates C code) and way faster than C#/Mono and free from any Microsoft associations
.
What about the Roxen Application Launcher
In this new version I utilize GConf for storing application settings. I also made use of – for the first time – the GNU Build Tools for compilation which also makes it easier to distribute and for others to compile from the sources. This also means that the distributed version compiles from the C sources and not the Vala sources so there’s no need for the Vala compiler to build the program.
Other than that there’s nothing fancy about it. The Vala sources is available at my Github repository.
Roxen Appliction Launcher 0.4.2 19:38, Sun 20 December 2009 :: 374 kB
Screenshots
The screenshots is showing the Swedish translation.
Gravatar module for Roxen
Although I’m working on some social web related Pike modules where a Gravatar module is included I needed a Gravatar module right now at work so I hacked up a standalone Gravatar Roxen module.
This is how it works
- <ul>
- <emit source="sql" host="mydb"
- query="SELECT name, email, `date`, body FROM my_comments"
- >
- <li>
- <gravatar-img email="&_.email;" rating="pg" size="32"
- default-image="/path/to/icon.png"
- /> &_.name; wrote at <date iso-time="&_.date;" />
- <wash-html paragraphify="">&_.body;</wash-html>
- </li>
- </emit>
- </ul>
Download the Gravatar Roxen module 14:20, Wed 09 December 2009 :: 7 kB
Useful 404 page
I read an article on A List Apart about creating “A More Useful 404”. I also think that it’s important to give better feedback to the visitor who ends up on a missing page. But I think that the customized 404 page should differ remarkably from the original site layout so that there’s no doubt about you’ve ended up on a “missing” page. I’ve seen 404 pages that are impossible to tell apart from the site and it can take quite some time before you realize you’ve reached a dead end.
I’ve used a customized 404 page on our sites at work almost since day one. The feedback to the visitor can be better but I have an email function – like suggested in the article at A List Apart – that sends an email to me, telling which URL the visitor tried to access and which URL the visitor came from, when someone reaches a missing page from a link, internal or external.
And I must say that this function is really, really helpful. If the broken link is on another site I usually send them an email notifying them about the problem and giving them the correct link – sometimes you just need to re-structure your site, even though it should be avoided when possible – and mostly they appreciate it and alter their link immediately. Also, when re-structuring, it’s easy to miss a few of your own internal links and with the little email notification the problem can be fixed right away.
In Roxen (the CMS we use at work) terms, all that needs to be done is adding this little snippet to the 404 page template in the administration site, under the “settings” tab for the site in question.
- <email to="you@your-domain.com" subject="Error 404">
- Requested URL: &page.virtfile;
- Referring URL: &client.referrer;
- ---
- UA: &client.fullname;
- </email>
Roxen User Conference (cont’d)
So the Roxen User Conference has come to an end. It’s always nice to meet with people who speak the same “language” (the language of the geeks perhaps), to share experiences and solutions. And of course it was nice to see the Roxen Editorial Portal in action. That’s a pretty cool piece of web based software. It was also nice to get a preview of Roxen CMS 5.0. It will have a few new features that will be nice and perhaps the greatest thing is that it will incorporate Pike 7.8 (which in it self hasn’t been released yet).
Anyway! For me it was a great experience talking to other Roxen customers and share some ideas and views. Oh, and one more nice thing: during the conference Roxen released a community site – planet.roxen.com. I hope it will be a great resource for us Roxen customers and users.
Roxen User Conference
Ok, so now the first day of Roxen User Conference is about to end. The has been some interesting speaks today and a few new acquaintances. The most impressive thing is to have see how different companies and institutions have implemented the Roxen platform. To me Roxen is not just a CMS but a great development platform and from my new experiences from all over the world today my conclusion is I’m not the only one with that standpoint.
Of course there’s been a few drinks (beer, wine, whiskey and what not) but also some new friends and faces to known names. And of course there’s also been some sharing of code concepts and what not.
Tomorrow there will be some more hands on workshops. Roxen will demo their new “Link management module” which will be part of the 5.0 release. It looks really promising from the previews we’ve seen today.
In the 5.0 release they will also bring to live a new patch module which will ease the maintenance of a Roxen empowered server park in a tremendous way. That feature will be awesome.
One cool thing in particular is to have seen a demo of the Roxen Editorial Portal. A few newspapers are already running it located from Sweden to USA to Australia. A really cool achievement for such a new product! You guys at Roxen rules!
I will give a new sum-up of tomorrow’s events!
Back from vacation
So after five weeks of vacation I’m back at work. The most sensational thing must be that I didn’t write a single line of code in these five weeks! It was a much needed break from computers and the longest one I’ve had for the nine years or so I’ve been programming. The vacation it self isn’t much to talk about. I visited friends and family and spent a lot of time in the sofa watching the olympics – and playing some Play Station 3 as well
I also just bought an Asus EEE which I think is quite cool. I’m actually writing this blog post on it. I threw out the Xandros operating system and installed Ubuntu EEE instead which feels a great deal better. I’ve installed a lot of developer tools and they actually run rather smoothly.
Roxen user conference
Next week, Thursday and Friday, I will attend the Roxen user conference which I’m really looking forward to. I’ll give a report from there when it happens.
Roxen Application Launcher 0.3
I just created an updated version of Roxen Launcher. I got an error report from one who tried to build the application:
./ApplCon.cs(232,24): error CS0122:
‘System.Net.Sockets.TcpListener.Server’ is inaccessible due
to its protection level
An explanation of the error can be found at MSDN. The reason seems to be due to TcpListener.Server being a protected property but I tried to access it as public. The strange thing is that I didn’t get an error about it nor on my machine at home or at work. Now I created a derived class of TcpListener.Server so that I can access the protected property.
We’ll see if it works!
Roxen Application Launcher 17:31, Sat 17 October 2009 :: 97.3 kB
Roxen Application Launcher for Linux
I thought I should broaden my C# knowledge a bit and you know how it is: To learn new stuff you need a real project to work on or else you will lose the fire sooner than later. So I came up with a good project that is actually useful to me: Porting Roxen’s “Application Launcher” to C#. There’s nothing wrong with the original one, written in Pike, except that it uses GTK 1 which is quite hideous (in an aesthetic meaning) compared to the newer GTK 2. And I also though it would be cool to create a panel applet (in the notification area of Gnome so you could put the Application Launcher in the background).
BTW: For those of you not knowing what the heck Roxen’s Application Launcher (AL here after) is here’s a brief explanation: Files in Roxen CMS is stored in a CVS file system which means that you don’t deal with files the way you normally do. To manage files you use a web browser interface (which is a darn good one I might add) but sometimes you actually want to edit files in your standard desktop application. And it is here the AL comes to play. You can download a file through the browser interface so that the file is opened in the AL. AL will then open the file in the desktop application you have associated with the file’s content-type. When you make your changes and saves them the AL will directly upload the changes to the server. So in short I could have said: The Application Launcher is a means to edit files on a remote Roxen server with a preferred desktop application.
The obstacles
I must say I’ve learned a lot from this project!
First off: If you download a file for editing and the AL is already started you don’t want to start a new instance of AL (this is something I have never ever thought about before – in general terms, not just concerning AL) but when you do think about it you find that it’s not a piece of cake to solve. I solved it the way it is solved in the original AL. The first instance of AL that is started also starts a “socket server” that listens for incoming traffic on a given port on the local IP. When a new instance is started it first checks if it can connect to said port and if it can it sends the arguments through the socket to the first instance which then handles the request. The second instance is simply terminated when it has send the data though the socket.
So there I had to do some socket programming. Great fun
Secondly: Stuff happens in the background of AL – data send through the socket remember – which means that nothing happens when you try to update the Graphical User Interface. (NOTE! This is the first more advanced desktop application I’ve done.) After “Google-ing” around a bit I came to know that this was a real newbie problem
The thing is that the GUI can only be updated through the same thread that started it so when using background threads – implicitly that’s what I’m doing although handled by the asynchronous callback infrastructure of C# – you need to make sure the GUI is updated through the main thread. This is the most simple way so solve it:
- Gtk.Application.Invoke(delegate{
- CallFunctionToUpdateGUI();
- });
That’s not too difficult when you know it
Thirdly: The AL is sending data back and forth through the HTTP protocol which means we have to use some sort of HTTP client. C# has a couple of ways to do this but unfortunately they came up short, or I couldn’t use them anyway. I didn’t manage to figure out exactly why I always caught an exception saying something like: A protocol violation occurred!. I’m far from the only one who have fought with this and it has something to do with the headers sent from the remote server. You can invoke “unsafe header parsing” but that was to much of a hassle so I created my own little HTTP client.
One big annoying thing with C# is that is seems almost impossible to turn data from streams into strings without having to use any one of the System.Text.Encoding.* classes/objects which in my case meant that images and files in binary form got seriously fucked up. I manged to solve this my never turning the data into a string but keeping it as a System.Text.Encoding.* all the way from request to response to saving to disk. It was rather irritating but at the same time nice when solved (and I learned a whole bunch about System.Text.Encoding.*, System.Text.Encoding.*, System.Text.Encoding.* and System.Text.Encoding.*.)
Finally: Of course I learned a great deal more about C# but this blog post is starting to get pretty excessive so I will round it off by saying that MonoDevelop is starting to become pretty darn good! I just upgraded to the latest version of Ubuntu and that also meant that I got the latest MonoDevelop and I must say it’s more stable than ever (although it occasionally crashes) and a whole bunch of new features are in place. One I havn’t used before – although it might have existed before – is the “Deployment” stuff. It creates a package with configure and make files for optimal compilation. Really smooth!
Source and screens
I will finish off by adding the source files and a few screen shots:
Roxen Application Launcher 17:31, Sat 17 October 2009 :: 96.7 kB
Screen shot 1: Just a standard view

Screen shot 2: The panel applet in action

Better late than never
It’s amazing that I havn’t posted an entry here for more than six months! I’ve had so much to do at work so I havn’t had the driving force to bother! We’re about to release a redesign of www.tekniskaverken.se which have taken quite much time. We’re also about to update both the server hardware and software. We’re going to use Roxen replication and load balancing which means we’re going from one standalone server to three servers!
I’ve also been busy developing “My Pages” at Tekniska Verken where our customers can log on and view consumption statistics for water, district heating, electricity and waste and much more. The statistics part has existed for years but the functionality has been rewritten from scratch where webservices SOAP) for our business system has been developed and the overall functionality has been extended and improved.
The fun thing is that I have written the SOAP clients in Java – since Pike (the language used in Roxen) doesn’t have a SOAP implementation yet but do talk to Java quite nicely – which I’ve never touched before. Java is a nice language but the Classpath thing drives you crazy! Anyway, with WSDL and Eclipse there has been no problems. There’s currently 13 webservices available and I don’t think I’ve even written 2000 lines of Java to implement them. SOAP is really nice I must say! So now I also can add Java to my CV
Hopefully the new www.tekniskaverken.se will be released within a month or so!
Updated Roxen trim tag
Jonas Walldén, CTO at Roxen, has improved my RXML tag contribution <trim></trim>. The code is now really beautiful and you can tell the difference from the code written by a lamer, as myself, and a real programmer, as Jonas. Jonas told me that the <trim></trim> tag will be part of the next Roxen release
Download
Roxen trim tag 17:31, Sat 17 October 2009 :: 4.8 kB
Pike trim module 17:31, Sat 17 October 2009 :: 4 kB
A Pike syntax highlighting module
So I thought I should try to port my syntax highlighting script, Syntaxer, written in PHP to Pike. Mostly for the fun of it but also to improve my knowledge of string handling in Pike. The greatest concern here is that PHP is a dynamic language and Pike is not (in the same sense) and the PHP version of Syntaxer heavily depends on dynamic loading of PHP files. The reason for this is that I generate the “syntax maps” dynamically from syntax files of Edit+. That means that if you want support for a new language just drop a .stx file in the right location and there you go. My script will convert that into a static PHP file, so that the conversion only needs to be done once, and load that file on the fly when that particular language is requested.
I thought that this method would be hard to implement in Pike – although it might be possible – so I had to come up with a slightly different approach. Frankly; it’s not that often you alter the .stx files or implement support for new languages so my solution is to manually create definitions for what ever language. But I still use the .stx files from Edit+ although one needs to copy and paste bit.
In the Pike solution each language is its own class that inherits the master class .stx. The only thing you pretty much need to put in the derived class is some .stx, .stx and .stx that specify what is what in the language. For example, the C++ definition looks like this:
- inherit .Hilite;
- public string title = "C++";
- //| Override the keywords mapping
- private mapping(string:multiset(string)) keywords = ([
- "keywords" : (<
- "auto","bool","break","case","catch","char","cerr","cin",
- "class","const","continue","cout","default","delete","do",
- "double","else","enum","explicit","extern","float","for",
- "friend","goto","if","inline","int","long","namespace","new",
- "operator","private","protected","public","register","return",
- "short","signed","sizeof","static","struct","switch","template",
- "this","throw","try","typedef","union","unsigned","virtual",
- "void","volatile","while","__asm","__fastcall","__based",
- "__cdecl","__pascal","__inline","__multiple_inheritance",
- "__single_inheritance" >),
- "compiler" : (<
- "define","error","include","elif","if","line","else","ifdef","pragma" >)
- ]);
- //| Override the default since # is no line comment in C++
- protected array(string) linecomments = ({ "//" });
- void create()
- {
- ::create();
- colors += ([ "compiler" : "#060" ]);
- styles += ([ "compiler" : ({ "<b>", "</b>" }) ]);
- }
And you really don’t need to make it more fancy than that. For most C-based languages the definitions in the master class .stx is enough. Just add the keywords to the .stx mapping and it looks better than nothing
HTML parser
One thing that differs from the PHP version of Syntaxer is that SGML-based, or tag based, languages will be run through a HTML-parser. The downside of the PHP version is that tag content will be highlighted as well, which of course isn’t what we want, but since Pike has a decent HTML parser that behaves like a SAX parser so I wrote a class, .stx, that uses that for highlighting tag based stuff. The .stx class also inherits .stx so the methods and members are the same.
I wonder why there’s no, built-in, HTML parser for PHP?
A Roxen tag module
Of course I had to write a Roxen tag module so that we can highlight source code in Roxen web pages. This was the reason for writing the Pike module at all. The tag is named .stx which might not be the most innovative name but what the heck! The beauty of it is that I made it possible, in the module settings tab, to create a surrounding HTML template for the output. When you run some code through the parser you get the highlighted source code as well as the name of the language and how many lines of code was highlighted and it might be nice to present that as well (just like the code blocks on this site). It’s tedious writing that surrounding HTML every time so now it’s just to put that in the settings and the code blocks will always look the same.
Finally
There’s some stuff left to do but the code works well enough to be usable. And I must say that the speed of the Pike version is like a thousand times faster than the PHP version!
Oh, and I have implemented support for the following language:
- ActionScript
- C
- C++
- C#
- CSS
- Java
- JavaScript
- HTML
- Perl
- PHP
- Pike
- Python
- Ruby
- RXML
- XSL
And that’s that for now.
Codify RXML tag and Syntaxer.pmod 17:31, Sat 17 October 2009 :: 183.9 kB
A Pike module and a Roxen tag
When you’r used to one programming language and start learning a new one you sometimes miss some features from the former. That happened to me a couple of years ago when we started using Roxen at work. What I missed was the trim functions from PHP. Sure, Pike and RXML can trim strings from whitespace but the beauty of trim, trim and trim in PHP is that you can trim characters as well as whitespace. And to my knowledge there’s no equivalent to trim and trim – that is only trim the left and right side respectively of the string.
So I wrote a Pike module that did that and also created an RXML tag of it. Just yesterday I rewrote that code since I do think I’ve become a better programmer and have come to learn Pike a lot better since my first try.
And I also wrote a method to shorten a string from the center and out, i.e. trim.
So here are some examples of usage:
- import .trim;
- string path = "/this/is/a/path/";
- write("%s\\n", rtrim(path, "/"));
- // Will output: /this/is/a/path
- write("%s\\n", trim(path, "/"));
- // Will output: this/is/a/path
- string long_str = "This is some string that's too long for us";
- write("%s\\n", ctrim(long_str, 20));
- // Will output: This is...for us
And here’s the RXML implementation:
- <trim right="" char="/">/this/is/a/path/</trim>
- <!-- /this/is/a/path -->
- <trim center="" length="20">This is some string that's too long for us</trim>
- <!-- This is...for us -->
And that’s that.
Trim Pike module 17:31, Sat 17 October 2009 :: 4 kB
Trim Roxen tag module 17:31, Sat 17 October 2009 :: 4.8 kB
Beautiful Roxen
I’ve been really busy lately at work with various things – developing a blogging system for starters. Most of the stuff you need for a blogging system is already available in Roxen CMS that we use at work. But one thing I needed, that isn’t available, was some commenting functionality. This is something that you could quite easily implement in the templates – Roxen uses XSLT for the templating system, or their own extension of XSLT so that you can write RXML code in the XSL templates.
RXML handles database driven things quite alright but if you develop things in this layer, the presentation layer, it gets harder to maintain or implement on a different server. What you can do then is writing a Roxen Module in Pike. You can create different types of modules – provider modules, RXML tag modules and so on – and you can also combine two or more modules into one. All RXML tags in Roxen is just wrappers for underlying Pike code, so you hide the logic in Pike and provide simple interfaces in RXML. First, let me give an example of how you loop over a database record set in RXML:
- <emit source="sql" host="myhost" query="SELECT name, email FROM employees">
- <a href="mailto:&_.email;">&_.name;</a>
- </emit><else>
- No records found
- </else>
It doesn’t get more simple than that! Another thing that’s great about the modules is that you can run arbitrary functions when you load the module which means that you can create databases and database tables when you first load the module. Roxen runs on MySQL internally and Roxen provide API:s to the internal MySQL database. What this means is that if you create database driven modules it’s just to install the module and the database and its tables will be created. No fuss!
Roxen, without the CMS, is a standalone open source web server and support the same kind of modules as the CMS does, but there’s more to the CMS!
The CMS modules
I’ve been poking around in the Roxen CMS source code for a while now and I have written some pure RXML tag modules – which is quite simple – but now I saw the opportunity to extend my knowledge and make a real CMS module. Since the CMS provide access control you don’t want emit tags to list stuff that the user don’t have access to. For instance: There’s a emit tag that you can use to list the most recent pages for a given path or pats. For example:
- <h2>Latest news</h2>
- <ul class='newslist'>
- <emit source="site-news" unique-paths="" maxrows="20"
- path="/comp-a/news/*/*.xml,/comp-b/news/*/*.xml,/secret/*/*.xml"
- >
- <li><a href='&_.path;'>
- <date type='iso' date='' iso-time='&_.published;' /> |
- <span>&_.title;</span>
- </a></li>
- </emit>
- </ul>
Now, you don’t want unauthorized users to see the items from the emit path do you. This tag in particular won’t show them either and I wanted the same kind of functionality in my set of emit tags. So I poked some more!
Another thing: Each file in Roxen CMS is version controlled through CVS and I needed to get some information about the first published version so I needed to find out how to access the CVS logs. The CVS thing also means that the files in Roxen CMS is saved to a virtual file system with an actual path, i.e emit, and what if there are comments to a page and that page gets moved? Thankfully Roxen CMS provides an API to run your own code when some kind of action takes place on a particular file – if it get moved, edited, deleted, purged and so forth. And I came to understand that I needed to poke around even more
Anyway; the more you dig around at the dark side of Roxen the more impressed you get by how clean the code is, how nice the API:s are and so on. I’m no Roxen beginner by now but up until now I haven’t really used the API:s to the internal workings of Roxen and I must say that after all, it was a bliss.
The comments module
So what will all this babbling lead up to? Well, what my module now does is:
- Upon load it creates an internal database with the table in which to store the comments. Here you can also make a dump or load a dump of the comments DB. In the settings you can set the default value for how long commenting should be enabled – lets say that after 30 days no further commenting should be allowed. You can also set a default author name if you allow anonymous commenting.
- It listens to the
emitwhich means that when actions takes place on web pages in the CMS the module will be notified and take actions if necessary. If the pageemithas comments to it and the page get moved the paths in the comments table will be updated to the new path so that comments always stick to its page even if the page is moved. Also, if a page gets deleted so will the comments. - It provides a set of RXML tags, one for listing comments – either to the page to which they belong or through globs so that you can make lists of “latest comments”, one for listing a particular comment for lets say editing, one tag for adding, one for updating, one for deleting a comment, one
emittag for checking if a user have admin permission to a given comment and oneemittag to check if the commenting form has expired or not and last one tag for counting the comments for a given page. - Not the least: I followed through and really documented, through Roxens module documentation functionality, the usage of the RXML tags
So I think that it covers what you’d expect a “commenting system” should be capable of doing. There’s may be some small things to solve as always when you develop stuff but it seems to work quite satisfying.
For anyone curious, here’s the source code:
Comments – Roxen CMS Module 17:31, Sat 17 October 2009 :: 36.3 kB
Here’s some screen dumps
Generating PDFs on the fly
One time or another you come to the point, at least when you work as a web developer, when you need to generate PDFs on the fly. In principle this wouldn’t be too hard: pass the document you want to convert through a PDF printer. Well, it doesn’t sound that hard but talk is one thing and implementation another! I came to the point recently where I, or we, really needed to generate PDFs on the fly. The question of just converting one document to a PDF was not the only problem ahead: We also needed to alter the content, which is some tremendously complex content, of the PDF on the fly.
The workflow is as follows: A person submits a web based application through a web form. The commision is received by a handling officer who continues the application. The commision is sent back to the applier who in turn continues the application. The commision is once again sent to the handling officer who finish the application.
The application form, originally a Word document with loads of checkboxes, input fields and what not it’s the document at the top), at hand here is really, really complex and more or less industry standard. The pure complexity of the form is the reason why we wanted to digitalize it and make it into a more workflow like thing. Since the application form is more or less a standard we wanted the ability to see what the web based application would look like in reality if it was handled the old way through the Word document and of course give us the ability to archive the application in a constant format. And this is the type of document that people like to put in a binder so it needs to be printable and look like it always has looked like.
The first problem
So how do you go about and fill the Word document with values from a database, or how do you dynamically create a PDF that looks exactly like that complex Word document? Creating simple PDFs from a PDF API is not that hard but this really isn’t a simple structured document we’re talkning about so that didn’t sound likely. So I started looking at Adobes LiveCycle products but that would be really expensive (I mean really, really, really expensive) so we had to throw that idea away.
Then it hit me: We’re running Windows servers at work so couldn’t I build a COM based solution and use the COM interface for Word and in that way use the original Word document as a template and dynmialcally fill it with content from the database? I had never touched COM before but I thoght nothing is impossible!
The first solution
So I fired up Visual C# Express and began writing a console application that could be called from the web server. The first thing to solve was how to get all the data from the web server to the console application. Of course the console application could call the database directly but that would make the application hard to maintain, it would make it less dynamic and in general no good (and there are more documents to create and alter than the one I’ve mentioned). XML is no news to me so I though that passing an XML tree as an argument with what fields to fill and with what values would be a good idea. And since during the commision there are several types of documents to generate another argument would be what Word template to use.
So the question of how to get what information to fill the Word document with to the console application was easily solved (I love XPath).
The next question was how to use the Word COM interface, and frankly that was quite easy (thanks to Google). If you use bookmarks in the Word document you can loop over them with ease and just as easily fill them with content. So the principle I used was the following: The XML tree passed to the console application looks like this:
- <!-- The name of the root node doesn't matter -->
- <n>
- <field name="Some_Bookmark1" type="text">The value</field>
- <field name="Some_Bookmark2" type="text">Another value</field>
- <field name="Some_Bookmark3" type="checkbox">true</field>
- <!--
- ... and just as many nodes neccessary ...
- -->
- </n>
so the name attribute is correponding to the name of the bookmark/data field to alter and the node value is quite obvious the value to assign to the bookmark/data field. Text fields and checkboxes is delt with in different ways in the COM API so that’s why the name attribute.
When the bookmarks/data fields has been altered the document is saved in a temporary directory with a uniq name and the path to that document is returned by the console application.
Up to this point…
This is how things work so far:
- The console application is called with two aruments:
- What template to use
- An XML tree with what bookmarks/data fields to fill with what values
- The console application opens the template and fill it with data according to the XML tree passed as the second argument.
- The console application saves the document with a uniq name in a temporary directory and the path to that document is returned by the console application.
Quite clear I’d say
The second problem
Okey, so now this application needed to be callable from a web page. And frankly that seemed like a minor problem, and so it was. The only minor concern was that the overall web based application workflow was (is) developed by Roxen as a consultant job so the implementaion of this little Word to PDF thing needed to be as simple as possible. So it was time to fire up JEdit and do some Pike hacking.
The second solution
Thanks to the fact that there’s a module in Roxen that can execute external applications and thanks to the fact that the source code of Roxen is available I borrowed some of the code written by Marcus Wellhardt at Roxen
. I’m no wicked Pike expert like the dudes at Roxen so I borrowed the code from name that creates a background process and altered it slightly to fit my needs. On top of that I wrote a RXML tag that would be the wrapper to call to create the background process. The tag, a container tag, takes one required argument, the Word template to use, and one optional argument, the path to the directory where the template is stored (this argument is optional because it can be set globally in the module settings), and the XML tree with the bookmarks to fill as content. So the tag would be used like this (still, not all functionallity is there yet):
- <word2pdf template='the-template.doc'>
- <d>
- <field name="Some_Bookmark1" type="text">The value</field>
- <field name="Some_Bookmark2" type="text">Another value</field>
- <field name="Some_Bookmark3" type="checkbox">true</field>
- </d>
- </word2pdf>
So I tried the tag and indeed a Word document with my given data was created in the temp directory on the server!
The third problem
Now it was time to create a PDF from the temporary Word document. I found an open source PDF printer software called PDFCreator and it looked promising so I went for it. PDFCreator can be installed in “server mode” which was what I wanted and thanks to this guide it was easy to set it up as a service as well.
First I wrote a standalone Pike script for debugging and testing that would kind of emulate a web page request (it’s some what tiresome developing new thing directly through Roxen since the module needs to be reloaded/re-compiled for every change you make to the code). Anyhow, things started to work pretty well: The script created a Word document by calling my console application, the script passed the path to that document to PDFCreator and MS Word was launched and a PDF was printed to the given temp directory. Yes! PDFCreator relies on the software the orginal document is associated with.
Okey, so the code worked fine so I altered my Roxen tag module so that my tag name would behave in the same manner as the standalone Pike script. But when I ran the tag through a web page request PDFCreator hung, or rather the MS Word process created by PDFCreator hung!
The third solution
It really puzzeled me: Everything went ok if I ran the process as my user through my standalone Pike script, but when the process was created by the web server (local system) MS Word got stuck. So I changed the server process to run as an ordinary user account, my user (local administrator) and now it worked perfectly. Then it hit me: maybe the MS Office applications relies on the directory name in name and the user name doesn’t have that (it’s no ordinary user). So it seems that to get MS office apps to run from another process, that process needs to have been created by a normal user account. I dunno, maybe there’s a way around this, like installing MS Office in some kind of server mode or something like that!
Anyhow, my little RXML tag name now did what I wanted and the result of the tag is the raw data of the created PDF, the temporary Word document and the PDF is wiped clean from the server, so we can just store the raw data in a database and deliver it easily to a user when the PDF is requested.
Word2pdf wrapped up
I’m quite satisfied with the solution I came up with: The console application I wrote (I call it WordWriter) seems to work like a charm and the fact that what data to fill the template with is passed as an XML tree makes it really easy to use for more than the specific purpose it was developed for. Plus, if the over all web application Roxen developed (is developing) is changed I don’t need to change the WordWriter application
Finally this is how this little name can be used in real life:
- <?comment
- Here data is pulled from the database according to the
- application being handled
- ....
- ?>
- <define variable="var.pdfdata" trimwhites="">
- <word2pdf temlplate="my-template.doc">
- <n>
- <field name="My_Bookmark1" type="text">&sql.data1;</field>
- <field name="My_Bookmark2" type="text">&sql.data2;</field>
- <field name="My_Bookmark3" type="text">&sql.data3;</field>
- <!-- ... -->
- <field name="My_Bookmark10" type="checkbox">
- <if variable="&sql.data10; = 1">true</if>
- <else>false</else>
- </field>
- </n>
- </word2pdf>
- </define>
- <sqlquery host="dbhost"
- query="UPDATE table SET pdf1 = :pdf WHERE id = :id"
- bindings="pdf=var.pdfdata, id=sql.id"
- />
And that should do the trick!
The synergy
At my job we’re like 1200 people and sometimes people want to create PDFs either to put on our web site or e-mail to someone and of course not all computers have Adobe Acrobat installed so wouldn’t it be nice to have a form on the intranet where people could upload a file and get it back as a PDF? Since most of the PDF generating functionality was already at hand I just had to write another RXML tag that just creates a PDF from a document. Said and done so now we have PDF generating form on the intranet.
Finally
This has been a really fun thing to do from which I have learned alot of new stuff, and that is probably why I love my work so much: There’s always new things to dive into.
Blogging at work!?
Corporate blogging is getting more and more common and me and the editor at work have been talking about trying to get people at work adapting that as well. Since we’re a utility company dealing with stuff like district heating and cooling, waste and recycling, we’re operating power supply systems, municpality broadband network, we’re producing biogas and what not, there are plenty of knowledge in and about our corridors that would be worth writing about.
What’s important I think is that we find the right incentive for people to start blogging. Many people don’t really understand what it’s all about and what the gain would be. I can see two major reasons for blogging:
- Public opinion building/public education
You primarily write to create opinion, to share knowledge, to debate and so forth. In our case I can see how to apply this on our line of business: We do stuff that can have inflictions on the environment but everything we do we do with the environment in mind (we’re ISO 14001 certified). If you live in the municipality of Linköping you most certainly get a bill from Tekniska Verken (we supply water, broadband, heating, waste management, electricity and so on) so of course our activities, pricing and so forth is often up to debate.I think blogging would be a great way to give the inhabitants of Linköping better insight into what we do, why we do it, how we are govern by the municipality, why our pricings are as they are and so on. We have experts on energy efficency who could educate people on how to decrease their usage of energy (a contradiction of terms for an energy company right!) and so on.
- Personal knowledge aggregation/documentation
You necessarily don’t have to write primarily for the public, but rather write for your self as a way to document your work, to keep gained knowledge/progress at the same place (my primary reason for this blog). Since alot of the work we’re doing is project based blogging could serve as a way to document projects, and of course share knowledge between projects, departments and subsidiaries.
Implementation
So, I think we will manage to find the right incentives to get a few people blogging so I started working on creating a blogging system on our Roxen CMS platform. I think the right way to get people blogging is to go along the line of the second reason above, so I though beginning on the intranet is the way to go. Now, it hit me that we have all the modules (foremost the category module) and that Roxen have alot of to the infrastructure already built in to easily create a blogging system.
The only thing I had to implement from scratch was the commenting feature which I created a Pike module for. The module is a couple of RXML tags; emit blog-comments to list comments to a specific entry, emit blog-comments to save a comment, emit blog-comments does speak for its self, and emit blog-comments which returns 1 if a comment is written by the author of the blog post and 0 otherwise.
Then I fixed some with a few XSL templates and then it was done! It took me about 6 hours to create a multi blog system we’re each blog can have multiple authors and that features searching, archiving and categorization. I don’t know how many hours I’ve spent on my PHP blog engine that I’m running this blog on, but I can tell you it’s 6 multiplied with alot
Roxen simply is really nice to work with!
Well, there’s a little polishing to do and some work to do to sell the blogging idea to the co-workers but I don’t think it will take too long before we’re blogging on the intranet and hopefully we’ll get some blogs out into the public as well later on.













