From dc6b0e6bb35514cf19bd13f56c20e4c0a358089e Mon Sep 17 00:00:00 2001 From: Lakshmi Vyasarajan Date: Wed, 5 Jan 2011 11:16:38 +0530 Subject: [PATCH] Added auto extend plugin --- .gitignore | 1 + hyde/ext/plugins/auto_extend.py | 39 +++++++++++++++++++++++ hyde/ext/plugins/blockdown.py | 2 +- hyde/ext/plugins/meta.py | 2 ++ hyde/generator.py | 2 +- hyde/template.py | 41 +++++++++++++++++++++++- hyde/tests/ext/test_auto_extend.py | 50 ++++++++++++++++++++++++++++++ hyde/tests/ext/test_blockdown.py | 2 +- hyde/tests/test_plugin.py | 5 --- 9 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 hyde/ext/plugins/auto_extend.py create mode 100644 hyde/tests/ext/test_auto_extend.py diff --git a/.gitignore b/.gitignore index 1479702..3087f00 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ build *egg* .idea PYSMELLTAGS +.noseids diff --git a/hyde/ext/plugins/auto_extend.py b/hyde/ext/plugins/auto_extend.py new file mode 100644 index 0000000..ffdea40 --- /dev/null +++ b/hyde/ext/plugins/auto_extend.py @@ -0,0 +1,39 @@ +""" +Autoextend css plugin +""" + +from hyde.plugin import Plugin + +import re + +class AutoExtendPlugin(Plugin): + """ + The plugin class for less css + """ + + def __init__(self, site): + super(AutoExtendPlugin, self).__init__(site) + + def template_loaded(self, template): + self.template = template + + def begin_text_resource(self, resource, text): + """ + If the meta data for the resource contains a layout attribute, + and there is no extends statement, this plugin automatically adds + an extends statement to the top of the file. + """ + layout = None + try: + layout = resource.meta.extends + except AttributeError: + pass + if layout: + extends_pattern = self.template.extends_pattern + + if not re.search(extends_pattern, text): + extended_text = self.template.get_extends_statement(layout) + extended_text += '\n' + extended_text += text + text = extended_text + return text \ No newline at end of file diff --git a/hyde/ext/plugins/blockdown.py b/hyde/ext/plugins/blockdown.py index 9b735d1..80c1889 100644 --- a/hyde/ext/plugins/blockdown.py +++ b/hyde/ext/plugins/blockdown.py @@ -1,5 +1,5 @@ """ -Less css plugin +Blockdown css plugin """ from hyde.plugin import Plugin diff --git a/hyde/ext/plugins/meta.py b/hyde/ext/plugins/meta.py index fe80f35..1831e18 100644 --- a/hyde/ext/plugins/meta.py +++ b/hyde/ext/plugins/meta.py @@ -89,6 +89,8 @@ class MetaPlugin(Plugin): text = text[match.end():] data = match.group(1) if not hasattr(resource, 'meta') or not resource.meta: + if not hasattr(resource.node, 'meta'): + resource.node.meta = Metadata({}) resource.meta = Metadata(data, resource.node.meta) else: resource.meta.update(data) diff --git a/hyde/generator.py b/hyde/generator.py index fc7fe13..fb3f994 100644 --- a/hyde/generator.py +++ b/hyde/generator.py @@ -48,7 +48,7 @@ class Generator(object): res = function(*args) if res: targs = list(args) - last = targs.pop + last = targs.pop() targs.append(res if res else last) args = tuple(targs) return res diff --git a/hyde/template.py b/hyde/template.py index 17355b9..801dbeb 100644 --- a/hyde/template.py +++ b/hyde/template.py @@ -35,13 +35,37 @@ class Template(object): def exception_class(self): return HydeException + @property + def include_pattern(self): + """ + The pattern for matching include statements + """ + + return '\s*\{\%\s*include\s*(?:\'|\")(.+?\.[^.]*)(?:\'|\")\s*\%\}' + def get_include_statement(self, path_to_include): """ - Returns a include statement for the current template, + Returns an include statement for the current template, given the path to include. """ return "{%% include '%s' %%}" % path_to_include + @property + def block_open_pattern(self): + """ + The pattern for matching include statements + """ + + return '\s*\{\%\s*block\s*([^\s]+)\s*\%\}' + + @property + def block_close_pattern(self): + """ + The pattern for matching include statements + """ + + return '\s*\{\%\s*endblock\s*([^\s]*)\s*\%\}' + def get_block_open_statement(self, block_name): """ Returns a open block statement for the current template, @@ -56,6 +80,21 @@ class Template(object): """ return "{%% endblock %s %%}" % block_name + @property + def extends_pattern(self): + """ + The pattern for matching include statements + """ + + return '\s*\{\%\s*extends\s*(?:\'|\")(.+?\.[^.]*)(?:\'|\")\s*\%\}' + + def get_extends_statement(self, path_to_extend): + """ + Returns an extends statement for the current template, + given the path to extend. + """ + return "{%% extends '%s' %%}" % path_to_extend + @staticmethod def find_template(site): """ diff --git a/hyde/tests/ext/test_auto_extend.py b/hyde/tests/ext/test_auto_extend.py new file mode 100644 index 0000000..eb352ab --- /dev/null +++ b/hyde/tests/ext/test_auto_extend.py @@ -0,0 +1,50 @@ +# -*- 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 + +from pyquery import PyQuery + +TEST_SITE = File(__file__).parent.parent.child_folder('_test') + + +class TestAutoExtend(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_can_auto_extend(self): + s = Site(TEST_SITE) + s.config.plugins = ['hyde.ext.plugins.meta.MetaPlugin', + 'hyde.ext.plugins.auto_extend.AutoExtendPlugin', + 'hyde.ext.plugins.blockdown.BlockdownPlugin'] + txt ="This template tests to make sure blocks can be replaced with markdownish syntax." + templ = """ +--- +extends: base.html +--- +===========================////title\\\\============================ +%s +===========================\\\\title////============================""" + + content = (templ.strip() % txt).strip() + bd = File(TEST_SITE.child('content/auto_extend.html')) + bd.write(content) + gen = Generator(s) + gen.generate_resource_at_path(bd.path) + res = s.content.resource_from_path(bd.path) + target = File(s.config.deploy_root_path.child(res.relative_deploy_path)) + assert target.exists + text = target.read_all() + q = PyQuery(text) + assert q('title').text().strip() == txt.strip() \ No newline at end of file diff --git a/hyde/tests/ext/test_blockdown.py b/hyde/tests/ext/test_blockdown.py index bc25986..fa700e9 100644 --- a/hyde/tests/ext/test_blockdown.py +++ b/hyde/tests/ext/test_blockdown.py @@ -23,7 +23,7 @@ class TestBlockdown(object): def tearDown(self): TEST_SITE.delete() - def test_can_execute_less(self): + def test_can_parse_blockdown(self): s = Site(TEST_SITE) s.config.plugins = ['hyde.ext.plugins.blockdown.BlockdownPlugin'] txt ="This template tests to make sure blocks can be replaced with markdownish syntax." diff --git a/hyde/tests/test_plugin.py b/hyde/tests/test_plugin.py index 7da189c..8d996a7 100644 --- a/hyde/tests/test_plugin.py +++ b/hyde/tests/test_plugin.py @@ -169,7 +169,6 @@ class TestPlugins(object): gen = Generator(self.site) gen.generate_all() - assert begin_node_stub.call_count == len(self.content_nodes) called_with_nodes = sorted([arg[0][0].path for arg in begin_node_stub.call_args_list]) assert called_with_nodes == self.content_nodes @@ -188,7 +187,6 @@ class TestPlugins(object): gen = Generator(self.site) gen.generate_all() - assert node_complete_stub.call_count == len(self.content_nodes) called_with_nodes = sorted([arg[0][0].path for arg in node_complete_stub.call_args_list]) assert called_with_nodes == self.content_nodes @@ -207,7 +205,6 @@ class TestPlugins(object): gen = Generator(self.site) gen.generate_all() - called_with_resources = sorted([arg[0][0].path for arg in begin_text_resource_stub.call_args_list]) assert begin_text_resource_stub.call_count == len(self.content_text_resources) assert called_with_resources == self.content_text_resources @@ -230,7 +227,6 @@ class TestPlugins(object): gen = Generator(self.site) gen.generate_all() - called_with_resources = sorted([arg[0][0].path for arg in begin_binary_resource_stub.call_args_list]) assert begin_binary_resource_stub.call_count == len(self.content_binary_resources) assert called_with_resources == self.content_binary_resources @@ -242,7 +238,6 @@ class TestPlugins(object): path = self.site.content.source_folder.child('favicon.ico') gen.generate_resource_at_path(path) - called_with_resources = sorted([arg[0][0].path for arg in begin_binary_resource_stub.call_args_list]) assert begin_binary_resource_stub.call_count == 1 assert called_with_resources[0] == path