Showing posts for tag "blog"

The Basic Xots Tasklet in the Blog

Sep 6, 2014, 9:28 AM

Tags: blog xots

Continuing in my two-day spat of blog posts shamelessly containing "blog" in the title, I figured I'd mention how I'm using Xots for new-comment notifications.

If you're not familiar with it, Xots is a recent addition to the OpenNTF Domino API (added in the recently-released M5 RC1 build), intended to replace both agents and DOTS. There's still more work to be done on the scheduling portion, but Xots is perfectly capable of running manually-created tasks in a similar manner to Threads and Jobs as well as, to a slightly-lesser extent, responding to custom-named events.

The latter is the way I'm using it. I created a Tasklet class and told it to be triggered when something sends an event named "newBlogComment". The code therein is pretty simple: there's a handleEvent method that is fired when an event with that name is fired (by any app on the server, but it's just the one currently), and that code is pretty bog-standard Domino emailing code. The trigger happens in the Comment model class, and it's just a basic one-line affair.

Now, admittedly, in order to get the Xots task working, I had to write an agent to specifically name the class in the $Xots field of the icon note, but that is something that will be handled by a Designer plugin eventually - it's just the price of being an early adopter for now.

So is this a big, world-changing paradigm shift? Not in this instance, but it demonstrates that it's pretty straightforward to start writing multi-threaded and decoupled code using Xots, including custom events. Over time, it will expand to cover scheduled tasks and API-triggered database events ("document saved", etc.). It's pretty cool stuff.

How I'm Handling URLs for the Blog

Sep 5, 2014, 8:27 PM

Tags: blog

As I mentioned in the introductory post for the blog, I'm putting my investigation into RequestCustomizerFactory classes to work in the blog.

At its core, the point of what I'm doing is to allow me to write code like this:

<xp:link text="whatever" value="/post.xsp?id=somepostid">

...and have the generated link be something like:

<a href="/blog/posts/somepostid">whatever</a>

The core of this is the ability of a RequestCustomizerFactory to specify a UrlProcessor that is used by basically every URL-generation routine in XPages to map the XSP-side URLs to their final HTML version. You can find the code in the config.ConfigRequestCustomizerFactory class. What I do is make use of a List of Maps in my config document to represent a configurable list of known redirections (which correspond to Substitution rules in the Directory). The UI in the configuration page looks like this (kindly ignore the unsightly buttons):

Alias Configuration

The first two columns are regular expressions to match the server name (to ensure that the DB still works if copied to another server or accessed by a different set of web rules) and XSP-side URLs, while the last is a replaceAll replacement pattern, where $1 represents "group #1" from the regular expression - the text enclosed by the first set of parentheses.

Using this, I'm able to keep my XSP code agnostic as to what cleaner routing is available on the server - I don't have to hard-code assumptions about "/blog/posts/somepostid" anywhere in XSP or Java. Instead, that's handled entirely via the user-editable configuration document.

Now, ideally, you wouldn't even need the configuration document. Ideally, the code would look to the Directory to figure out which web site is active and if it has any Substitution or (maybe) Redirection rules that apply to the current database. That's on the docket for future improvement, but for now the current method strikes a reasonable balance of agnostic code with user-level configurability.

New Blog Structure

Sep 5, 2014, 5:37 PM

Tags: blog

So I finally got around to re-doing my blog app after letting the previous one wither on the vine for years. The main things this new template has over the previous one are:

  • A properly responsive design care of WrapBootstrap. Conveniently, it's the same design I use for our internal task-tracking app, so I had most of the renderers ready.
  • Along those lines, the XSP structure is heavily based on standard/ExtLib components when at all possible, rather than putting the Bootstrap structure into the page code.
  • I've also switched it to being based on the Framework, which I'd darn well better, since it's the name of the blog.
  • I've finally separated the app and data NSFs, which I should have done a long time ago.
  • I'm trying out a RequestCustomizerFactory combined with some web rules to generate somewhat-better URLs while still writing the normal ".xsp" page names and query strings in the XSP code itself, so it remains portable. I'll have to go into how I'm doing that eventually... and I'll also have to expand how it works to cover RT data as well.
  • I put an actual license statement at the bottom of the page (again: finally).
  • Translation support for the app UI if I bother to add that.

One thing it doesn't have is any amount of professionalism in the development and deployment: it's the work of part of the last couple days and accordingly lacks a lot of even basic features (tags, threads, a proper search UI, etc.) and is probably buggy as sin. Still, I wanted to get something shipped instead of letting it linger forever. I've got a reasonably-lengthy TODO list in mind. As expected, it's been a good exercise in finding out what I still need to do both in the Framework and in my renderer.

For those curious, the code is up on GitHub:

Making the Dogfooding Switch

Apr 7, 2012, 11:55 PM

Tags: domino blog

I've finally done it: I've switched my blog over to Domino. I did it for a couple reasons:

  • To silence the voice in the back of my head constantly saying "why are you using WordPress? You're a freaking web programmer! Write your own!"
  • To put my Ruby-in-XPages code through its paces in the way only a live site can.

I've already had to fix a couple holes in my Ruby adapter, mostly revolving around the fact that I haven't bothered to properly handle serialization and JSF's StateHolder interfact. For now, I've patched the worst problems, but this gives me a great reason to come up with a proper solution. To test it out, I'm making sure to avoid "#{javascript: ...}" code blocks in favor of using plain-EL and "#{ruby: ... }" exclusively. So far, the only really awkward parts are the giant swaths of yellow-squiggly "I don't understand this" underlining in Designer and having to put xp:repeat values on xp:dataContexts rather than writing the computation inline. Not too shabby.

The whole thing's a bit shoot-from-the-hip at the moment, since it's only existed for a day. There's no search (though that'll be easy), the site design is from my old college-era blog, and I have to write the posts' HTML by hand in the Notes client (you know, like on all modern blogging platforms). But hey, I have the old posts in there, plus an archives list and, as long as it doesn't mysteriously die again like it did a minute ago, Akismet-backed commenting.

So let's see how this thing works! Don't be surprised to see the WordPress version again if things go catastrophically wrong.