Skip to content

Instantly share code, notes, and snippets.

@seanh
Created November 7, 2009 21:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seanh/228907 to your computer and use it in GitHub Desktop.
Save seanh/228907 to your computer and use it in GitHub Desktop.
An in-progress PyBlosxom plugin for handling slug URLs.
"""
A plugin for handling slug URLs. A slug is a nice, short URL for reaching a
particular post.
If a URL ending in /slug/hello-world is requested this plugin will search the
datadir for a post that has the metadata line:
#slug hello-world
If such a post is found the page for that post will be shown in the browser. So
by adding a #slug metadata key to your post you can create a custom, short
permalink for that post.
Unfortunately this plugin is not very efficient. When a slug URL is requested
the plugin searches the datadir constructing a FileEntry for every entry file
that it finds until it finds an entry with a matching slug or has searched the
entire datadir. A cached dictionary mapping slugs to entry filenames might be
more efficient, but it would need to be updated every time an entry is added,
deleted, moved or modified.
Warning: if two posts have the same slug this plugin will just return
whichever post it finds first.
No configuration is necessary to use this plugin, just put it in your plugins
directory and it to your load_plugins list in config.py if necessary.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Copyright 2009 Sean Hammond
"""
__author__ = "Sean Hammond, seanhammond -at- lavabit -dot- com
__version__ = '1'
__url__ = ''
__description = 'A plugin for handling slug URLs. A slug is a nice, short URL for reaching a particular post.'
import os
from Pyblosxom import entries
def cb_filelist(args):
"""If the requested URL ends with /slug/something then search for an entry
file in the datadir that has a metadata value '#slug something', if an
entry with the requested slug is found then provide Pyblosxom with an entry
list containing only that entry.
"""
request = args['request'] # The request object.
config = request.getConfiguration() # The configuration dict.
datadir = config['datadir'] # The datadir.
data = request.getData() # The data dict.
extensions = data['extensions'] # List of filename extensions for entries.
# pi_bl seems to be the end part of the requested URL, the part following
# base_url/. What does pi_bl stand for anyway?
pi_bl = data['pi_bl']
if not pi_bl.startswith('slug/'):
# The requested URL is not a slug/ URL, nothing for this plugin to do,
# allow another plugin or Pyblosxom to create the filelist instead.
return None
slug = pi_bl[5:]
# Recursively find all files in the datadir that have a filename extension
# that Pyblosxom is currently handling for entries, and construct a
# FileEntry for each.
# FIXME: this assumes FileEntry is the appropriate class for every type of
# entry. Is that correct?
for root, dirs, files in os.walk(datadir):
for f in files:
if not os.path.isfile(os.path.join(root,f)):
continue
elif os.path.splitext(f)[1][1:] not in extensions:
continue
else:
entry = entries.fileentry.FileEntry(request,os.path.join(datadir,os.path.join(root,f)),'','')
if entry.has_key('slug'):
if entry['slug'] == slug:
# bl_type = file tells pyblosxom that it's a file
# page (showing a single file) not an index page.
data['bl_type'] = 'file'
return [entry]
# If we get here then no entry with the requested slug was found. Return
# None, which will allow another plugin of Pyblosxom itself to handle
# generating the file list instead.
return None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment