| @@ -13,3 +13,4 @@ build | |||||
| *egg* | *egg* | ||||
| .idea | .idea | ||||
| PYSMELLTAGS | PYSMELLTAGS | ||||
| .noseids | |||||
| @@ -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 | |||||
| @@ -1,5 +1,5 @@ | |||||
| """ | """ | ||||
| Less css plugin | |||||
| Blockdown css plugin | |||||
| """ | """ | ||||
| from hyde.plugin import Plugin | from hyde.plugin import Plugin | ||||
| @@ -89,6 +89,8 @@ class MetaPlugin(Plugin): | |||||
| text = text[match.end():] | text = text[match.end():] | ||||
| data = match.group(1) | data = match.group(1) | ||||
| if not hasattr(resource, 'meta') or not resource.meta: | 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) | resource.meta = Metadata(data, resource.node.meta) | ||||
| else: | else: | ||||
| resource.meta.update(data) | resource.meta.update(data) | ||||
| @@ -48,7 +48,7 @@ class Generator(object): | |||||
| res = function(*args) | res = function(*args) | ||||
| if res: | if res: | ||||
| targs = list(args) | targs = list(args) | ||||
| last = targs.pop | |||||
| last = targs.pop() | |||||
| targs.append(res if res else last) | targs.append(res if res else last) | ||||
| args = tuple(targs) | args = tuple(targs) | ||||
| return res | return res | ||||
| @@ -35,13 +35,37 @@ class Template(object): | |||||
| def exception_class(self): | def exception_class(self): | ||||
| return HydeException | 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): | 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. | given the path to include. | ||||
| """ | """ | ||||
| return "{%% include '%s' %%}" % 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): | def get_block_open_statement(self, block_name): | ||||
| """ | """ | ||||
| Returns a open block statement for the current template, | Returns a open block statement for the current template, | ||||
| @@ -56,6 +80,21 @@ class Template(object): | |||||
| """ | """ | ||||
| return "{%% endblock %s %%}" % block_name | 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 | @staticmethod | ||||
| def find_template(site): | def find_template(site): | ||||
| """ | """ | ||||
| @@ -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() | |||||
| @@ -23,7 +23,7 @@ class TestBlockdown(object): | |||||
| def tearDown(self): | def tearDown(self): | ||||
| TEST_SITE.delete() | TEST_SITE.delete() | ||||
| def test_can_execute_less(self): | |||||
| def test_can_parse_blockdown(self): | |||||
| s = Site(TEST_SITE) | s = Site(TEST_SITE) | ||||
| s.config.plugins = ['hyde.ext.plugins.blockdown.BlockdownPlugin'] | s.config.plugins = ['hyde.ext.plugins.blockdown.BlockdownPlugin'] | ||||
| txt ="This template tests to make sure blocks can be replaced with markdownish syntax." | txt ="This template tests to make sure blocks can be replaced with markdownish syntax." | ||||
| @@ -169,7 +169,6 @@ class TestPlugins(object): | |||||
| gen = Generator(self.site) | gen = Generator(self.site) | ||||
| gen.generate_all() | gen.generate_all() | ||||
| assert begin_node_stub.call_count == len(self.content_nodes) | 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]) | called_with_nodes = sorted([arg[0][0].path for arg in begin_node_stub.call_args_list]) | ||||
| assert called_with_nodes == self.content_nodes | assert called_with_nodes == self.content_nodes | ||||
| @@ -188,7 +187,6 @@ class TestPlugins(object): | |||||
| gen = Generator(self.site) | gen = Generator(self.site) | ||||
| gen.generate_all() | gen.generate_all() | ||||
| assert node_complete_stub.call_count == len(self.content_nodes) | 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]) | called_with_nodes = sorted([arg[0][0].path for arg in node_complete_stub.call_args_list]) | ||||
| assert called_with_nodes == self.content_nodes | assert called_with_nodes == self.content_nodes | ||||
| @@ -207,7 +205,6 @@ class TestPlugins(object): | |||||
| gen = Generator(self.site) | gen = Generator(self.site) | ||||
| gen.generate_all() | gen.generate_all() | ||||
| called_with_resources = sorted([arg[0][0].path for arg in begin_text_resource_stub.call_args_list]) | 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 begin_text_resource_stub.call_count == len(self.content_text_resources) | ||||
| assert called_with_resources == self.content_text_resources | assert called_with_resources == self.content_text_resources | ||||
| @@ -230,7 +227,6 @@ class TestPlugins(object): | |||||
| gen = Generator(self.site) | gen = Generator(self.site) | ||||
| gen.generate_all() | gen.generate_all() | ||||
| called_with_resources = sorted([arg[0][0].path for arg in begin_binary_resource_stub.call_args_list]) | 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 begin_binary_resource_stub.call_count == len(self.content_binary_resources) | ||||
| assert called_with_resources == 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') | path = self.site.content.source_folder.child('favicon.ico') | ||||
| gen.generate_resource_at_path(path) | gen.generate_resource_at_path(path) | ||||
| called_with_resources = sorted([arg[0][0].path for arg in begin_binary_resource_stub.call_args_list]) | 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 begin_binary_resource_stub.call_count == 1 | ||||
| assert called_with_resources[0] == path | assert called_with_resources[0] == path | ||||