diff --git a/hyde/ext/plugins/urls.py b/hyde/ext/plugins/urls.py new file mode 100644 index 0000000..13fc181 --- /dev/null +++ b/hyde/ext/plugins/urls.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +""" +Contains classes and utilities related to hyde urls. +""" +import re + +from hyde.fs import File, Folder +from hyde.model import Expando +from hyde.plugin import Plugin +from hyde.site import Site, Node, Resource + +from functools import wraps + +class UrlCleanerPlugin(Plugin): + """ + Url Cleaner plugin for hyde. Adds to hyde the ability to generate clean + urls. + + Configuration example + --------------------- + #yaml + urlcleaner: + index_file_names: + # Identifies the files that represents a directory listing. + # These file names are automatically stripped away when + # the content_url function is called. + - index.html + strip_extensions: + # The following extensions are automatically removed when + # generating the urls using content_url function. + - html + # This option will append a slash to the end of directory paths + append_slash: true + """ + + def __init__(self, site): + super(UrlCleanerPlugin, self).__init__(site) + + def begin_site(self): + """ + Replace the content_url method in the site object with a custom method + that cleans urls based on the given configuration. + """ + config = self.site.config + + if not hasattr(config, 'urlcleaner'): + return + + if (hasattr(Site, '___url_cleaner_patched___')): + return + + settings = config.urlcleaner + + print settings.to_dict() + + def clean_url(urlgetter): + @wraps(urlgetter) + def wrapper(site, path): + url = urlgetter(site, path) + index_file_names = getattr(settings, + 'index_file_names', + ['index.html']) + rep = File(url) + if rep.name in index_file_names: + url = rep.parent.path.rstrip('/') + if hasattr(settings, 'append_slash') and \ + settings.append_slash: + url += '/' + elif hasattr(settings, 'strip_extensions'): + if rep.kind in settings.strip_extensions: + url = rep.parent.child(rep.name_without_extension) + return url or '/' + return wrapper + + Site.___url_cleaner_patched___ = True + Site.content_url = clean_url(Site.content_url) \ No newline at end of file diff --git a/hyde/tests/ext/test_urlcleaner.py b/hyde/tests/ext/test_urlcleaner.py new file mode 100644 index 0000000..2db7686 --- /dev/null +++ b/hyde/tests/ext/test_urlcleaner.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +""" +Use nose +`$ pip install nose` +`$ nosetests` +""" +from hyde.fs import File, Folder +from hyde.generator import Generator +from hyde.site import Site + +import yaml + +from hyde.model import Config + +TEST_SITE = File(__file__).parent.parent.child_folder('_test') + + +class TestUrlCleaner(object): + + def setUp(self): + TEST_SITE.make() + TEST_SITE.parent.child_folder( + 'sites/test_jinja').copy_contents_to(TEST_SITE) + + def tearDown(self): + TEST_SITE.delete() + + def test_url_cleaner(self): + s = Site(TEST_SITE) + cfg = """ + plugins: + - hyde.ext.plugins.urls.UrlCleanerPlugin + urlcleaner: + index_file_names: + - about.html + strip_extensions: + - html + append_slash: true + """ + s.config = Config(TEST_SITE, config_dict=yaml.load(cfg)) + text = """ + {% extends "base.html" %} + + {% block main %} + + + {% endblock %} + """ + + about2 = File(TEST_SITE.child('content/test.html')) + about2.write(text) + gen = Generator(s) + gen.generate_all() + + from pyquery import PyQuery + target = File(Folder(s.config.deploy_root_path).child('test.html')) + text = target.read_all() + q = PyQuery(text) + assert q('a#index').attr("href") == '/' + assert q('a#blog').attr("href") == '/blog/2010/december/merry-christmas' \ No newline at end of file