LnBlog 2.3.2 - No Need for Ports

A new patch release is up.  You can get it from the download page.

This one fixes a small but significant bug, reported by atomGit via Github.  There was an issue with the CSRF protection code where it did not properly account for URLs with a port in them.  So if you tried to run LnBlog with a PHP test server on a non-standard port, the initial setup page would return a 400 Bad Request error.  Sadly, there was nothing particularly subtle or interesting about this bug - it's just something I didn't account for.  The CSRF code was blissfully unaware that a URL or hostname could contain a port.  This led to trying to compare an HTTP_HOST header with a port in it, e.g. localhost:8081 to a call to parse_url($_SERVER['HTTP_ORIGIN'], PHP_URL_HOST), which explicitly discards the port.

While I was at it, I also updated the defaults for the userdata path when the LnBlog directory is the server's document root.  This is because the normal default is to have userdata and LnBlog in the same directory, but right now LnBlog assumes that the userdata directory will be web-accessible.  So in that case, the default is now to put userdata inside of LnBlog, like in the "good ol' days".

LnBlog 2.3.1 - No need for pagination

Welp, it's time for a patch release.  This is a minor one, though.  It only fixes two small, but highly visible and annoying bugs:

  1. The internal version number was wrong.  This was version 2.3.0, but internally, LnBlog thought it was still 2.2.0.  That's because I forgot to update the version number in the config file.  This is not the first time I've done this, sadly, so I added a step to the build script to check that the build version matches the config file, which should keep this from happening again.
  2. The move of the entry-fetching code from the main Blog domain object to a repository object broke pagination because of the way the "has more entries" check worked.  That meant that the next/previous links never showed up at the bottom of the page, which was annoying.

That's it - nothing earth shattering here.  You can grab the new version from the download page.

LnBlog 2.3.0 - No Need for RSS

It's that time again - time for a new LnBlog release!  I'm averaging about one a year at this point, which isn't too bad considering how little time I get to work on it.  As usual, you can grab it from the download page or from the GitHub page.

Anyway, this release comes with several new features and some caveats.  While perhaps not earth-shattering, some of the changes are fairly substantial.  

But first, a compatibility warning: PHP versions prior to 7.4 are no longer supported.  That's right, we're moving into the "modern" era and making PHP 7.4 or greater a hard dependency.  So if you're still on 7.3, sorry, but the new release won't work.  But on the other hand, 7.3 has also reached end-of-life and no longer even gets security updates, so you probably shouldn't be running it anyway.  Also, updating to 7.4 means I can start using more fancy new language features.

As a side-note, the above also means that if you installed from source, or want to do an in-place upgrade by pulling from the Git repo, you'll need to do a "composer install --no-dev" to update the dependencies.

Anyway, on to the changes. One of the big ones is that the RSS support has been completely revamped.  The old plugins were, frankly, crappy and half-baked, and had lain mostly untouched for over a decade.  So I ripped them out and replaced them with a new, unified RssManagement plugin.  In the process, I pulled all the actual feed generation logic out of plugins and into the core.  This allows us to leverage that to support additional export formats.  So in addition to the WordPress export that we added in the last release, we can now do all the formats that we generate feeds in.  This also made it much easier to add new feed formats, so in addition to RSS 1.0 and RSS 2.0, we can now create Atom feeds as well!

The new RssManagement plugin settings.

Note that because we now have a new RSS plugin, you'll probably need to reconfigure the RssManagement plugin to match any customizations you had previously.  However, this time the config is all in one place.  So as you can above, there is now one config screen to choose what feed types to generate, where they appear, and what the sidebar panel looks like.  There are also some links to manually purge and recreate feed files (caveat: the UI needs a little work...).  These are useful if you decide to disable a particular format or want to migrate from RSS to Atom.

In addition to this, there are also some improvements to the post editor.  Instead of just supplying a couple of presets, you now have the ability to specify a full config object for TinyMCE.  That means you can customize the menus, toolbars, etc. to your liking.  (Of course, you'll need to look at the TinyMCE documentation to figure out the settings you want, but at least you can change them.)

We've also got some new changes to make dealing with post attachments easier.  The first is that you can now upload an attachment from the clipboard.  So you can copy an image from the web and paste it into the editor page with ctrl+V (or cmd+V if you're one of those people).  This will now actually upload the clipboard data and create an image attachment (note: you'll have to click outside of the actual editor box, otherwise TinyMCE will intercept the past).  We've also added controls next to the listed attachments that will insert links directly in the editor.  So once the attachment is uploaded, all you need to do to insert it at the cursor location is click the icon next to it in the attachment list.  When combined with the auto-scaling feature, I find that this takes nearly all of the friction out of adding image to your posts.  But that's just me.

Anyway, here's the official list of issues resolved in this release.  Enjoy!

  • #47 Improve RSS support (enhancement)
  • #44 Make TinyMCE editor configurable (enhancement)
  • #43 Better display of publication queue (enhancement)
  • #42 Support for "paste to upload" (enhancement)
  • #39 Encapsulation for controller logic (enhancement)
  • #38 Improve image quality for auto-scaling (enhancement)
  • #37 Move LBCode editor markup to a plugin (enhancement)
  • #36 Insert attachment links in editor (enhancement)
  • #35 Add cache busting for JS/CSS files (bug)
  • #33 Manage files for profiles (enhancement)
  • #32 TinyMCE not loading on generic file editor (bug)

We're making progress

I just wanted to post a quick update here because I'm actually very pleased with how LnBlog has been evolving lately.  As you may have noticed from the changes in the last few releases, this "my first PHP project" is actually turning into a real application.  In addition to having a bunch of features, I've squashed a bunch bugs, added some security, and implemented some more manageability features.

One of the things that I'm most pleased about, however, is that I've finally gotten around to some UI improvements.  Nothing radical, but just some stuff that makes my life easier.  One of the more recent ones is revamping the file upload interface.  Here's what it looks like at the moment.

The current LnBlog file upload and management interface

There are several new things here.  Starting at the bottom is the upload box, which uses Dropzone.  This isn't actually new, but I did add a handy feature to it: paste to upload.  So if you just click someplace outsize the edit box and paste some image data, the file will start to upload and appear in the Dropzone area.  Not a huge thing, but a handy feature that  cuts out a few steps when you just want to upload a screenshot or something.

Above that, you see the revamped file management interface.  For a long time, LnBlog didn't have any file management interface.  You just had to know what files you'd uploaded.  (No, I'm not kidding about that.)  Then I added the bare minimum: a list of files and a "delete" link.  It stayed like that for a long time.  Now, the name is actually a link you can click to open the file (you know, something actually useful) and there are up to four controls next to it. 

  1. First, the little "x" is the delete link.  That's pretty self-explanatory.
  2. Then there's the "add link" icon, which inserts a hyperlink to the file at the current cursor location in the editor.  Crazy, right? 
  3. After that is the "insert image" link, which does the same thing, but it only shows up for images and inserts an IMG tag instead of a hyperlink.  An interesting feature of this is that if an image has a "full sized" version and a "scaled down" version, then clicking this for the scaled down version will insert that image and make it a link to the full version.  So just that's a handy way to speed up a common workflow. 
  4. And last is a control that generates "scaled down" versions of images.  It's very simple and just supports four pre-defined sizes.  And, of course, this only shows up for images.

Clearly this is not revolutionary stuff.  However, I find that it actually makes a big difference.  Consider the amount of friction involved in the workflow for adding the above screenshot to this post:

  1. I grab a screenshot of the area using Greenshot and copy it to the clipboard.  (4 clicks)
  2. I click on the post editor page and press ctrl+V to paste the image.  (1 click, 2 keystrokes)
  3. After the image uploads, I click the "scale down image" link and select "medium" to get the 800x600 (max) version.  (2 clicks)
  4. When the scaled down version is created, I click the "insert image" link to insert the image with a link to the full-sized version.  (1 click)

Compare that to the old workflow.  Keep in mind that this is what I actually had to do, which is part of the reason I didn't post a lot of pictures in the past:

  1. Grab the screenshot, but save it to a file. (5 clicks, plus as many keystrokes as the filename takes)
  2. Use the "Convert Images" tool in Directory Opus to scale down the image to the desired size.  (Before I started using Directory Opus, I actually opened the image up in The GIMP and rescaled it that way.  Ugh!)  (3+ clicks, depending on your defaults in Directory Opus)
  3. Upload both the original and scaled versions of the image to the entry.  (2 clicks in the Dropzone era, more in the bad old days)
  4. Manually add the image tag for the scaled version, either typing or copy-pasting the file name.  (2 clicks, plus keystrokes or clicks for the filename, more if not using TInyMCE)
  5. Manually add a link tag around that image, either typing or copy-pasting the file name of the full version.  (2 clicks, plus keystrokes or clicks for the filename, more if not using TinyMCE)

Granted, that's only one extra step, but the new workflow is two keystrokes and 8 mouse clicks - and half of those clicks are just acquiring the screenshot.  In the old workflow, we're looking at a minimum of 14 mouse clicks, plus potentially a dozen or more keystrokes, plus switching windows multiple times between scaling and file selection dialogs.  I mean, it's not that bad if you really want to put a picture in your post, but if you're just casually posting something and aren't really committed to having a picture, it can be enough to make you think, "Eh, I don't feel like bothering with that."

I've also done a lot of other UI cleanup recently.  I still have some work to do (for instance, the layout of the post editor could stand improving), but it's getting to the point where I'm actually fairly happy with the UI.  And to think, it only took 16 years.

LnBlog 2.2.0 - No Need to Start Over

It's here!  We have a new LnBlog release, not quite a year after the last one.  By current standards, that's fast and furious.

Anyway, this release actually has some new and interesting (at least to me) features.   You can grab a copy from the download page or the GitHub release page.    Note that this release will require an upgrade of any existing blogs.  Also note that this release changes the way URLs are calculated, so you'll need to visit the admin page to go through the initial setup again.  If your blogs don't show up after that, you may need to re-register them from the admin page.

Now, on to the changes in this version.  And there's actually quite a few of them - and some pretty substantial ones, too.  Not bad for one guy developing it on an extremely-part-time basis.  In fact, the app is starting to look and work fairly well, if I do say so myself.  But anyway, here's what you need to know:

  • First, I finally fixed the stupid, ugly layout of the various forms.  They now use a standard vertical layout rather than the old, uneven, "I'm too lazy to style this" one.  I know this doesn't sound like a big deal, and it really isn't (I mean, I did it in like an hour), but it's been a long-standing issue and it made the entire app look crappy.
  • Another small but noteworthy change, the "DisableComments" plugin is now configured to disable TrackBacks on all entries by default.  Related to this, disabling TrackBacks on an entry will now disable all TrackBack-related UI elements.  Of course, you can still change that setting in the plugin configuration, but I don't even remember the last time I saw mention of TrackBacks on a blog, so I figured it was time to turn that stuff off.
  • Now the big one - import from WordPress!  This feature allows you to take a WordPress extended RSS export file and import it into LnBlog.  You can either import the data into an existing blog, or create a new one based on the export file.  This is the first iteration, and it has some limitations, but it works.  The biggest limitations are that the import process will not import media items and it will not touch the contents of the posts - everything is treated as raw HTML, so you're on your own as far as any WordPress markup magic.  (Note that if you keep the media files for your WordPress installation at the old URL, they should still work.  Alternatively, you can set up a mapping on your web server or just edit the URLs in the export file before you do the import.)  However, the process will import pages as LnBlog articles, published posts, draft posts, comments, and pingbacks.  You also have the option to import user accounts for any username in the export that doesn't already exist in LnBlog.  The import will attempt to map the WordPress usernames to LnBlog usernames and default to the blog owner if the username can't be found.
  • Here's one you'll definitely notice - the addition of the Tag-It widget.  This is now used in a couple of places, but the most obvious is the entry editor.  So instead of the text-box with the ghetto JS drop-down for selecting tags, we have an actual decent-looking widget.
  • Another noticeable feature is an auto-scaler for uploaded images.  In the collapsible file list for the upload box, we now have a little icon next to images that you can click to auto-generate a scaled version.  There are only a few pre-set choices for size, but it's a convenient way to create thumbnails or scale down high-def pictures.
  • Now the under-the-hood changes.  First, blog data upgrades can now be done from the command line.  Just run php cli.php --upgrade to upgrade all your blogs in one shot, or supply a blog ID to do just one.
  • Second, third-party JavaScript libraries have moved from whatever random CDN I could find to local files.  These are collected and put in the "third-party" directory by the build process.  Part of the blog upgrade process now includes making sure each blog has a references to these files.  (By this, I just mean that the upgrade gets around cross-domain JS issues by copying or symlinking this directory into any blog that's on a different domain than the LnBlog directory.)
  • Lastly, and most importantly, I completely changed the way LnBlog tries to deal with path and URL mapping.  The old version used some hair-brained and convoluted rules to try to auto-detect what path mapped to what URL.  This was fine...when it worked.  The problem was that it didn't work often enough, and when it failed, the failures were opaque and hard to diagnose.  So instead of that, LnBlog now requires you to explicitly tell it what path and URL each blog will have.  It also requires you to explicitly tell it the path and URL of the LnBlog installation and your userdata folder.  Of course, the UI will present you with reasonable defaults that you can edit if desired.  For blogs, it will even update these when you change the blog ID you enter (note: the "blog ID" is just a string identifying the blog - usually, it's just the name of the blog's folder).  I know this is a little bit of a pain, in that it adds some extra boxes to think about, but it shouldn't be too bad.  And it makes the URL resolution much more reliable.
  • One last note: Because of the above change to the URL and directory mapping, LnBlog will now generate a pathconfig.php file inside the LnBlog install directory.  So when upgrading, you may have to copy this file to the new version.  (Yes, I know this violates the whole "put everything in userdata" rule I had, but since it now stores the path to userdata, that obviously wasn't going to work.)  This file now stores the paths and URLs to your LnBlog install, your userdata folder, and each of your blogs.  However, that's all it stores.  So this file is critical to LnBlog working, but if anything happens to this file, there's nothing in it that can't be recreated through the admin page UI.  Just delete the broken file, go to the admin page to regenerate the basics, and then re-register each of your blogs.

Here's the list of GitHub issues closed in this release:

  • Cannot edit URL of current blog (#14)
  • Better subdomain resolution (#15)
  • Auto sitemap broken for subdomains (#17)
  • RSS links shown when plugin disabled (#18)
  • Add tag widget (#19)
  • Include files for third-party JavaScript (#20)
  • Import from WordPress (#25)
  • Comment delete link broken (#26)
  • Auto-scale feature (#27)
  • Upgrade from command-line (#29)

LnBlog 2.1.0 - No Need for a Crappy Mobile Experience

Hot on the heels of LnBlog 2.0.0 a mere year and five months ago, release 2.1.0 is here!  This one includes a bunch of quality-of-life and usability improvements, including some basic support for responsive layout, editor improvements, and a less crappy interface to change plugin load order (which tool me like half an hour, so I'm not sure why I didn't do that years ago).  This release also includes entry pagination for the main blog page which, again, didn't take that much work and is a basic feature I should have implemented years ago.

Another new feature is the introduction of a task queue.  This is a glorified way of referring to a command-line script that reads a JSON file and does stuff based on what it contains.  The idea is that you can just run this via a cron job or similar task scheduling system.  Right now it's only used for scheduled publication, but it will be useful in the future for other things.  Configuring it as a cron job is currently optional, but highly recommended (if you don't, the back-end of the script will just run on every request to the main page).  To set up the "cron" functionality, create an entry in your crontab (or wherever you create your cron entries) that runs: php /path/to/lnblog/cli.php --cron.  Then add the line USE_CRON_SCRIPT = true to your userdata/userconfig.cfg file.  (Note: if you prefer to use userconfig.php, you can add the constant definition there instead.)

We also have several security enhancements in this release, including login attempt throttling and CSRF protection.  Again, both long overdue.  The list of tickets with Github links is included below.  There's probably a bunch of other undocumented stuff I fixed and forgot about too.

You can grab the zip file from the download page.  As usual, the upgrade process is to just to move the old directory, extract the zip file, and copy your userdata (and any other custom files) into the new directory.  Or, if you moved userdata up one level (which you should), just move the old directory and extract the new one.  I think we're close to the point where nothing that you should care about is stored in the actual application directory, but I can't swear to it.

Also, you'll need to run a "blog upgrade" for each of your blogs from the admin page.  As always, it's wise to backup all your data before upgrading.  Remember, there's no warranty on this - if it breaks, you get to keep both parts.

Anywho, here's the ticket list.

LnBlog - Now on GitHub

Just as an FYI, since I haven't really been religious about updating the documentation, LnBlog is still alive and well and is now on GitHub.  You can find it here.

For years I hosted LnBlog on my personal Mercurial server running my own bug tracker for project management (first MantisBT, then The Bug Genie).  However, as I wrote in my regular blog, Mercurial has lost the DVCS war and I'm tired of having to manage and administer a bug tracker, so I've switched LnBlog to Git and moved the project management to GitHub.  Of course, I still run a private Git server, because I'm paranoid and I don't want to be totally dependent on a third-party, but I don't want to manage the public-facing stuff anymore.

On the up side, this will also make LnBlog more visible and make it more convenient for anyone who is interested to follow development.

And speaking of following development, I've added an awful lot of stuff since the last official release.  This includes some security enhancements, post auto-save, WYSIWYG editor enhancements (including mobile support), a responsive layout, and actual pagination.  All that stuff will go into the next release, but you can always clone the master branch if you want to try it out now.

LnBlog 2.0.0 - No Need for Regularity

Wow, three and a half years since the last release.  That's kind of a long time.  But on the other hand, seeing how this was my very first PHP project (back in the PHP 4 days), and I've now been writing PHP professionally for over a decade, it's a small miracle that it still works at all.

Anyway, there have actually been quite a few changes since the last release, although many of them have been under the hood.  Basically, I've been using LnBlog as a test bed to practice refactoring legacy code.  So I've done a bunch of restructuring, adding unit tests, fixing bugs, and generally trying to simplify things.  Among the bigger updates were removing most of the wrapper pages and reworking the post publication process.  There's a lot still to do, but the code is gradually getting better.

Since this is a major version, there are some feature additions as well.  Here's the full list of items in the milestone, but the big ones are support for sending and receiving Webmentions (they show up as Pingbacks, which are essentially the same thing anyway) and support for listing and deleting files attached to blogs and entries.

Note that my justification for calling this version 2 is that I'm requiring a data upgrade for older blogs, like this one.  So if you have entries with the old "current.htm" data files, the blog needs to be upgraded.  (Note: I am probably the only person in the world to whom this applies.)  This release adds support to the "blog upgrade" process on the admin page to migrate those files to the newer XML format.  The next release will remove support for the old file formats.

So feel free to check it out.  As usual, you can get the zip archive from the download page.  If you're so inclined, you can also grab the source directly from Mercurial.  You should be able to just drop it on your server, run composer install, and point a browser to the URL.

LnBlog 1.3.0 - No Need For Tenchi Muyo References

Hey, look at that - another release!  And just a little over a year since the previous one. 

There's not really much to this.  It's mostly under-the-hood improvements and cleanup, along with a few bug fixes.  I also played around with the edit form and added support for writing posts in Markdown.  But honestly, I just wanted to get a release out before trying to make bigger under-the-hood changes.  I know, not very exciting, but I just didn't want too many changes piling up.

Anywho, the installable ZIP archive is on the download page and the list of changes is on the isue tracker.  The full source is available from the Mercurial repository linked from the project page.  Please report any bugs.

Have fun!

Documentation update

I've uploaded an updated version of the official documentation.  You can view it here.

Sadly, I hadn't updated the documentation in years.  Some of it was misleadingly out of date — for instance, it still claimed to run on PHP 4.1, which hasn't been true since version 1.0, which I put out in 2011.  So, yeah, it was kind of embarassing.

The new documentation takes care of some details like that.  It also rounds out the documentation for all the standard plugins.  Or, rather, all the plugins that will be standard in the next release.  So it'll be slightly ahead of current until then (though the next release shouldn't be too far off).  It could probaby be a little more comprehensive, but at least every plugin has a page now.