@@ -13,3 +13,4 @@ build | |||
*egg* | |||
.idea | |||
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 | |||
@@ -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) | |||
@@ -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 | |||
@@ -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): | |||
""" | |||
@@ -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): | |||
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." | |||
@@ -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 |