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 13 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
and methods for walking tagged resources.
"""
self.logger.debug("*************************************")
self.logger.debug("Adding tags from metadata")
config = self.site.config
content = self.site.content
@@ -102,24 +102,17 @@ class TaggerPlugin(Plugin):
'walk_resources_tagged_with', walk_resources_tagged_with)
walker = get_tagger_sort_method(self.site)
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:
tag_meta = self.site.config.tagger.tags.to_dict()
except AttributeError:
@@ -133,14 +126,36 @@ class TaggerPlugin(Plugin):
del(meta['name'])
if tagname in tags:
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

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

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="/",
not_found='404.html',
plugins = [],
ignore = [ "*~", "*.bak", ".hg", ".git", ".svn"]
ignore = [ "*~", "*.bak", ".hg", ".git", ".svn"],
meta = {
"nodemeta": 'meta.yaml'
}
)
self.config_file = config_file
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.write(text % d)
meta = File(TEST_SITE.child('content/nodemeta.yaml'))
meta = File(TEST_SITE.child('content/meta.yaml'))
meta.write(yaml.dump(d))
s = Site(TEST_SITE)
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):
TEST_SITE.delete()


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


assert q('li').length == 2
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'
@@ -165,7 +163,10 @@ class TestTagger(object):
"template": "emotions.j2",
"source": "blog",
"target": "blog/tags",
"extension": "html"
"extension": "html",
"meta": {
"author": "Tagger Plugin"
}
}
},
"tags": {
@@ -180,13 +181,14 @@ class TestTagger(object):
}

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

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

q = PyQuery(archives['angry'].read_all())
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.deploy_root_path == TEST_SITE.child_folder('deploy')
assert c.not_found == '404.html'
assert c.meta.nodemeta == 'meta.yaml'

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


||||||
x
 
000:0
Loading…
Cancel
Save