The last few days have beendistracting. Everything from a new Harry Potter book (a good one, by the way) to a subpoena from Microsoft (!) has kept me from working all day, every day the way I'd prefer. Nonetheless, I've made a lot of progress.
You can now see this progress in my Subversion repository. Since I last wrote, I've:
I think I may put up a preliminary release soon; said release will probably come once I have the page creation and editing UIs in. After that, most of what's left will be the Kolophon parser, documentation and help pages, user authentication system, a couple more page classes, and several administrative-type pages.
Oh, and I have screenshots. (Large, oddly-shaped ones, because my laptop has the rather bizarre resolution of 1280x768.)
Users page, HTML view. This page uses the Kategory class.
Users page, XML view. Note that the <content> field contains the same information as the HTML viewjust rendered differently. (The XML view's <content> field is basically a direct translation of the skeleton.)
Root page, HTML view. This page uses the Kiki class.
Root page, XML view. Note the rather different set of attributes.
Root page, HTML history. Clicking on the dates would yield the indicated revision of the page.
So, I made revisions work, at least with my k_manip command-line tool. I also did a great deal of work on renderers, writing an XML dump renderer and enhancing the HTML renderer to support a revision history mode. The next step is to write the HTML renderer's edit mode, although I have some non-SoC stuff to do in the next couple days as well.
It's turning out to be somewhat more difficult than I suspected to be productive with an experimental interpreter. Bugs in Pugs come and go daily, and sometimes (as I mentioned yesterday with the
.execute() problems) a bug can simply stop me in my tracks for a while. Having said that, the Pugs people are amazingly responsiveI mentioned a bug with closure interpolation on #perl6 yesterday and it was fixed within hours. Still, debugging is a much more difficult task when the interpreter is suspectI thought I'd hit upon another Pugs bug today, but it turned out that I had made a mistake in my own code.
I'm still working on the revision stuff; I got some work done on the plane home, but then I had to do some schoolwork over the weekend, and I spent much of Monday fighting with Perl 5 interop, which was refusing to let me execute statement handles in mysterious-but-present-in-my-code circumstances. Grr.
I'm starting to realize that roles are unlikely to be finished in time for me to use them; as such, I'll probably implement page classes as actual classes for the moment, store instances of those classes in the revision objects, and use the
handles built-in to delegate the appropriate methods (
children, and maybe
parent) to it. I can always change it later if roles become available.
With that in mind, I may be starting to implement page classes soon...once I finish this revision stuff, that is.
Yesterday I started on the basic SQL store, WWW::Kontent::Store::NarrowDBI, and today I finished the reading component of it. Writing will be somewhat harder, because I have three requirements:
One helpful point is that I don't actually want concurrent edits to work; I'd rather have the edit that starts second fail. If Alice and Bob are both revising the same page at the same time, and Alice saves first, Bob should have to examine Alice's edits instead of blindly reverting them.
The name of the store might strike people as a bit odd. NarrowDBI is "narrow" because the
attrs table with all of the actual data has only three columns
value. (Alternatives I've imagined are "wide", which has a table with a column for each possible attribute, and "deep", which uses several different tables.)
Basically, each revision has a bunch of attributes, like "content" and "title" and so on. Precisely which attributes a revision has will depend on its class (annoyingly, one of its attributes); the three SQL stores reflect three different ways to organize the attributes.
To save time, I'll only be implementing NarrowDBI for the Summer of Code project. I chose this store for three reasons:
That last point is important, because they are changing; for example, I realized about half an hour ago that DeepDBIand general good designwill require some way to separate different classes' attributes, so I'll be adding prefixes to indicate which part of the system owns the attribute in question. (For example, the revision-wide attributes that were previously called "author" and "date" will now be "kontent:author" and "kontent:date"or maybe "rev:author" and "rev:date", I'll need to think about it.)
Tomorrow, the Revision::revise method, the Page::create method, and the Draft class to go with them.
Today was one of those days where I did a lot (including some restructuring of yesterday's work), but all of it was too small to really talk about or even truly recall. So instead I'll answer a question and talk about the project in general.
The goal of Kontent is to write a dynamic, extensible, versioned, database-driven CMS. Think of it as a wiki site plus a message board plus an Everything Engine site plus a Scoop or Slash news site, all in one system and possibly all coexisting. Anything that can be represented as a set of discrete documents can be represented in Kontent.
And oh, by the way, each document needs to support multiple actions and render in multiple formats. And the system has to work with multiple database engines, even ones that aren't SQL-based, and on multiple web/script interfaces, not just CGI. And it has to be easy to design new types of pages, so it needs a clear separation between different concerns. And it should be written as cleanly as possible, since one of the most painful things about the systems it replaces (MediaWiki, Everything, Slash, etc.) is that the code is so spaghettied together that it's impossible to work on.
To achieve all of this, Kontent is divided into five major components. The supervisor is the top-level component; it talks to the web server and coordinates the other four components. The store translates whatever data source is being used into simple page objects. The driver implements any special behavior a page needs that involves calculating data or retrieving additional pages from the store. The adapter translates the page, including whatever data the driver may have prepared, into a format-independent "skeleton" representing the final, formatted output. (The driver and adapter are per-page roles composed into the page object, and are collectively called the page's "class".) And finally, the renderer takes the adapter's skeleton and fleshes it out into a beautifully-rendered document in whatever format the user asked for.
Anyway, I finally got a build of Pugs on this machine with working Perl 5 interop, so tomorrow I think I'll work on a DBI store module.
(This was written yesterday, but I wasn't able to post it until today.)
I've decided to use this old blog as a log of my activities on Kontent, my Summer of Code project. The goal of the project is to build a dynamic, versioning, highly-customizable CMS in Perl 6.
My family had a vacation planned for the Fourth of July--we're visiting family in Michigan. However, I'm not letting that stop me from working on my project, so I brought a laptop loaded with Ubuntu, Eclipse, Apache, MySQL and Pugs so I can work.
I got in about four hours of work today. (A lot of my time was lost fiddling with Linux's suspend-to-disk behavior; my laptop has a slightly exotic wide screen that requires special treatment whenever the system boots.) In that time, I managed to stub out the basics of Kontent. My "test.p6" looks like this:
say "Content-Type: $request.type()";
If you're familiar with Kontent's five-part design, you may be asking, "where's the class?" Well, the two calls for it are there (driver and adapter). In the final version, the so-called "class" will actually be a role composed into the Page object, but Pugs doesn't support roles yet, so that isn't really possible.
At this point, everything is stubbed well enough that this produces a hello world. Huzzah.
In other news, I'm starting a college class this week--Intro to Software Engineering. The teacher is a pretty funny guy, but he focuses too much on how to make money from the software engineering. It should be a pretty easy class. I have to do a project for it; I'm thinking about doing a little language that uses Parrot as a backend, partially to figure out how real languages should configure and interface with Parrot.
This week I managed to get some hacking done. It's all related to the Parrot regular expression engine. Since I'm writing the third major version of it (the first was crap and the second was okay but was never released) I'm calling it Rx3. It has some cool features, like being able to find the rightmost match and being able to advance backwards through the string. It's still missing a ton of stuff--among them the regex compiler (although there is a stub in place) and full support for most of the modifiers--but it works. Or at least it should--I haven't worked up the courage to compile and run it yet!
In preparation for that, I also wrote two fairly minor patches for Parrot. The first added a function to allocate stacks. The second added a new PMC type, the Handle; it hasn't gone in yet because Dan has doubts about its usefulness. Hopefully I'll be able to change his mind.
In other news, I'm thinking about rewriting Parrot's Configure system to make it modular. Then again, I think about that at least twice a month and never decide to do anything about it...