Created
November 7, 2009 21:42
-
-
Save seanh/228907 to your computer and use it in GitHub Desktop.
An in-progress PyBlosxom plugin for handling slug URLs.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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