Browse Source

Issue #77: Tagger now generates archives upfront in begin_site

* Archives are generated in begin_site to honour meta data
* Archives are first class resources
* Archive configuration now accepts an additional meta parameter
* The default nodemeta property now points to meta.yaml
main
Lakshmi Vyasarajan 14 years ago
parent
commit
ec011bfda6
5 changed files with 100 additions and 58 deletions
  1. +86
    -52
      hyde/ext/plugins/tagger.py
  2. +4
    -1
      hyde/model.py
  3. +1
    -1
      hyde/tests/ext/test_meta.py
  4. +8
    -4
      hyde/tests/ext/test_tagger.py
  5. +1
    -0
      hyde/tests/test_model.py

+ 86
- 52
hyde/ext/plugins/tagger.py View File

@@ -93,7 +93,7 @@ class TaggerPlugin(Plugin):
Initialize plugin. Add tag to the site context variable Initialize plugin. Add tag to the site context variable
and methods for walking tagged resources. and methods for walking tagged resources.
""" """
self.logger.debug("*************************************")
self.logger.debug("Adding tags from metadata") self.logger.debug("Adding tags from metadata")
config = self.site.config config = self.site.config
content = self.site.content content = self.site.content
@@ -102,24 +102,17 @@ class TaggerPlugin(Plugin):
'walk_resources_tagged_with', walk_resources_tagged_with) 'walk_resources_tagged_with', walk_resources_tagged_with)
walker = get_tagger_sort_method(self.site) walker = get_tagger_sort_method(self.site)
for resource in walker(): for resource in walker():
try:
taglist = attrgetter("meta.tags")(resource)
except AttributeError:
continue
for tagname in taglist:
if not tagname in tags:
tag = Tag(tagname)
tags[tagname] = tag
tag.resources.append(resource)
add_method(Node,
'walk_resources_tagged_with_%s' % tagname,
walk_resources_tagged_with,
tag=tag)
else:
tags[tagname].resources.append(resource)
if not hasattr(resource, 'tags'):
setattr(resource, 'tags', [])
resource.tags.append(tags[tagname])
self._process_tags_in_resource(resource, tags)
self._process_tag_metadata(tags)
self.site.tagger = Expando(dict(tags=tags))
self._generate_archives()
self.logger.debug("*************************************")

def _process_tag_metadata(self, tags):
"""
Parses and adds metadata to the tagger object, if the tagger
configuration contains metadata.
"""
try: try:
tag_meta = self.site.config.tagger.tags.to_dict() tag_meta = self.site.config.tagger.tags.to_dict()
except AttributeError: except AttributeError:
@@ -133,14 +126,36 @@ class TaggerPlugin(Plugin):
del(meta['name']) del(meta['name'])
if tagname in tags: if tagname in tags:
tags[tagname].update(meta) tags[tagname].update(meta)
self.site.tagger = Expando(dict(tags=tags))


def site_complete(self):
def _process_tags_in_resource(self, resource, tags):
""" """
Generate archives.
Reads the tags associated with this resource and
adds them to the tag list if needed.
""" """
try:
taglist = attrgetter("meta.tags")(resource)
except AttributeError:
return


content = self.site.content
for tagname in taglist:
if not tagname in tags:
tag = Tag(tagname)
tags[tagname] = tag
tag.resources.append(resource)
add_method(Node,
'walk_resources_tagged_with_%s' % tagname,
walk_resources_tagged_with,
tag=tag)
else:
tags[tagname].resources.append(resource)
if not hasattr(resource, 'tags'):
setattr(resource, 'tags', [])
resource.tags.append(tags[tagname])

def _generate_archives(self):
"""
Generates archives if the configuration demands.
"""
archive_config = None archive_config = None


try: try:
@@ -151,33 +166,52 @@ class TaggerPlugin(Plugin):
self.logger.debug("Generating archives for tags") self.logger.debug("Generating archives for tags")


for name, config in archive_config.to_dict().iteritems(): for name, config in archive_config.to_dict().iteritems():
self._create_tag_archive(config)


if not 'template' in config:
raise self.template.exception_class(
"No Template specified in tagger configuration.")
source = content.node_from_relative_path(config.get('source', ''))
target = self.site.config.deploy_root_path.child_folder(
config.get('target', 'tags'))
extension = config.get('extension', 'html')

if not target.exists:
target.make()

template = config['template']
text = "{%% extends \"%s\" %%}" % template

for tagname, tag in self.site.tagger.tags.to_dict().iteritems():
context = {}
context.update(self.site.context)
context.update(dict(
time_now=datetime.now(),
site=self.site,
node=source,
tag=tag,
walker=getattr(source,
"walk_resources_tagged_with_%s" % tagname)
))
archive_text = self.template.render(text, context)
archive_file = File(target.child("%s.%s" % (tagname, extension)
if extension is not None else tagname))
archive_file.write(archive_text)

def _create_tag_archive(self, config):
"""
Generates archives for each tag based on the given configuration.
"""
if not 'template' in config:
raise self.template.exception_class(
"No Template specified in tagger configuration.")
content = self.site.content.source_folder
source = Folder(config.get('source', ''))
target = content.child_folder(config.get('target', 'tags'))
if not target.exists:
target.make()

# Write meta data for the configuration
meta = config.get('meta', {})
meta_text = u''
if meta:
import yaml
meta_text = yaml.dump(meta, default_flow_style=False)

extension = config.get('extension', 'html')
template = config['template']

archive_text = u"""
---
extends: false
%(meta)s
---

{%% set tag = site.tagger.tags['%(tag)s'] %%}
{%% set source = site.content.node_from_relative_path('%(node)s') %%}
{%% set walker = source.walk_resources_tagged_with_%(tag)s %%}
{%% extends "%(template)s" %%}
"""
for tagname, tag in self.site.tagger.tags.to_dict().iteritems():
tag_data = {
"tag": tagname,
"node": source.name,
"template": template,
"meta": meta_text
}
text = archive_text % tag_data
archive_file = File(target.child("%s.%s" % (tagname, extension)))
archive_file.delete()
archive_file.write(text.strip())
self.site.content.add_resource(archive_file)

+ 4
- 1
hyde/model.py View File

@@ -150,7 +150,10 @@ class Config(Expando):
base_url="/", base_url="/",
not_found='404.html', not_found='404.html',
plugins = [], plugins = [],
ignore = [ "*~", "*.bak", ".hg", ".git", ".svn"]
ignore = [ "*~", "*.bak", ".hg", ".git", ".svn"],
meta = {
"nodemeta": 'meta.yaml'
}
) )
self.config_file = config_file self.config_file = config_file
self.config_dict = config_dict self.config_dict = config_dict


+ 1
- 1
hyde/tests/ext/test_meta.py View File

@@ -138,7 +138,7 @@ title: Even nicer title
""" """
about2 = File(TEST_SITE.child('content/about2.html')) about2 = File(TEST_SITE.child('content/about2.html'))
about2.write(text % d) about2.write(text % d)
meta = File(TEST_SITE.child('content/nodemeta.yaml'))
meta = File(TEST_SITE.child('content/meta.yaml'))
meta.write(yaml.dump(d)) meta.write(yaml.dump(d))
s = Site(TEST_SITE) s = Site(TEST_SITE)
s.config.plugins = ['hyde.ext.plugins.meta.MetaPlugin'] s.config.plugins = ['hyde.ext.plugins.meta.MetaPlugin']


+ 8
- 4
hyde/tests/ext/test_tagger.py View File

@@ -27,7 +27,6 @@ class TestTagger(object):
def tearDown(self): def tearDown(self):
TEST_SITE.delete() TEST_SITE.delete()



def test_tagger_walker(self): def test_tagger_walker(self):
gen = Generator(self.s) gen = Generator(self.s)
gen.load_site_if_needed() gen.load_site_if_needed()
@@ -86,7 +85,6 @@ class TestTagger(object):
q = PyQuery(File(tags_folder.child('sad.html')).read_all()) q = PyQuery(File(tags_folder.child('sad.html')).read_all())
assert q assert q



assert q('li').length == 2 assert q('li').length == 2
assert q('li a:first-child').attr('href') == '/blog/another-sad-post.html' assert q('li a:first-child').attr('href') == '/blog/another-sad-post.html'
assert q('li a:eq(1)').attr('href') == '/blog/sad-post.html' assert q('li a:eq(1)').attr('href') == '/blog/sad-post.html'
@@ -165,7 +163,10 @@ class TestTagger(object):
"template": "emotions.j2", "template": "emotions.j2",
"source": "blog", "source": "blog",
"target": "blog/tags", "target": "blog/tags",
"extension": "html"
"extension": "html",
"meta": {
"author": "Tagger Plugin"
}
} }
}, },
"tags": { "tags": {
@@ -180,13 +181,14 @@ class TestTagger(object):
} }


text = """ text = """
<div id="author">{{ resource.meta.author }}</div>
<h1>Posts tagged: {{ tag }} in {{ node.name|title }}</h1> <h1>Posts tagged: {{ tag }} in {{ node.name|title }}</h1>
Emotions: Emotions:
<ul> <ul>
{% for emotion in tag.emotions %} {% for emotion in tag.emotions %}
<li class="emotion"> <li class="emotion">
{{ emotion }} {{ emotion }}
</li>'
</li>
{% endfor %} {% endfor %}
<ul> <ul>
{% for resource in walker() -%} {% for resource in walker() -%}
@@ -215,7 +217,9 @@ Emotions:
from pyquery import PyQuery from pyquery import PyQuery


q = PyQuery(archives['sad'].read_all()) q = PyQuery(archives['sad'].read_all())
print q
assert len(q("li.emotion")) == 2 assert len(q("li.emotion")) == 2
assert q("#author").text() == "Tagger Plugin"


q = PyQuery(archives['angry'].read_all()) q = PyQuery(archives['angry'].read_all())
assert len(q("li.emotion")) == 3 assert len(q("li.emotion")) == 3


+ 1
- 0
hyde/tests/test_model.py View File

@@ -114,6 +114,7 @@ class TestConfig(object):
assert c.ignore == ["*~", "*.bak", ".hg", ".git", ".svn"] assert c.ignore == ["*~", "*.bak", ".hg", ".git", ".svn"]
assert c.deploy_root_path == TEST_SITE.child_folder('deploy') assert c.deploy_root_path == TEST_SITE.child_folder('deploy')
assert c.not_found == '404.html' assert c.not_found == '404.html'
assert c.meta.nodemeta == 'meta.yaml'


def test_conf1(self): def test_conf1(self):
c = Config(sitepath=TEST_SITE, config_dict=yaml.load(self.conf1)) c = Config(sitepath=TEST_SITE, config_dict=yaml.load(self.conf1))


Loading…
Cancel
Save