| @@ -4,6 +4,7 @@ Contains classes and utilities related to tagging | |||||
| resources in hyde. | resources in hyde. | ||||
| """ | """ | ||||
| import re | import re | ||||
| from hyde.fs import File, Folder | |||||
| from hyde.model import Expando | from hyde.model import Expando | ||||
| from hyde.plugin import Plugin | from hyde.plugin import Plugin | ||||
| from hyde.site import Node, Resource | from hyde.site import Node, Resource | ||||
| @@ -58,16 +59,19 @@ class TaggerPlugin(Plugin): | |||||
| tagger: | tagger: | ||||
| sorter: kind # How to sort the resources in a tag | sorter: kind # How to sort the resources in a tag | ||||
| archives: | archives: | ||||
| template: tagged_posts.j2 | |||||
| target: tags | |||||
| archive_extension: html | |||||
| blog: | |||||
| template: tagged_posts.j2 | |||||
| source: blog | |||||
| target: blog/tags | |||||
| archive_extension: html | |||||
| """ | """ | ||||
| def __init__(self, site): | def __init__(self, site): | ||||
| super(TaggerPlugin, self).__init__(site) | super(TaggerPlugin, self).__init__(site) | ||||
| def begin_site(self): | def begin_site(self): | ||||
| """ | """ | ||||
| Initialize plugin. Add tag to the site context variable. | |||||
| Initialize plugin. Add tag to the site context variable | |||||
| and methods for walking tagged resources. | |||||
| """ | """ | ||||
| self.logger.debug("Adding tags from metadata") | self.logger.debug("Adding tags from metadata") | ||||
| @@ -92,4 +96,45 @@ class TaggerPlugin(Plugin): | |||||
| else: | else: | ||||
| tags[tag].append(resource) | tags[tag].append(resource) | ||||
| self.site.tagger = Expando(dict(tags=tags)) | |||||
| self.site.tagger = Expando(dict(tags=tags)) | |||||
| def site_complete(self): | |||||
| """ | |||||
| Generate archives. | |||||
| """ | |||||
| content = self.site.content | |||||
| archive_config = None | |||||
| try: | |||||
| archive_config = attrgetter("tagger.archives")(self.site.config) | |||||
| except AttributeError: | |||||
| return | |||||
| self.logger.debug("Generating archives for tags") | |||||
| for name, config in archive_config.to_dict().iteritems(): | |||||
| if not 'template' in config: | |||||
| raise self.template.exception_class( | |||||
| "No Template sepecified 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 tag, resources in self.site.tagger.tags.to_dict().iteritems(): | |||||
| archive_text = self.template.render(text, dict( | |||||
| site=self.site, | |||||
| node=source, | |||||
| walker=getattr(source, | |||||
| "walk_resources_tagged_with_%s" % tag) | |||||
| )) | |||||
| archive_file = File(target.child("%s.%s" % (tag, extension))) | |||||
| archive_file.write(archive_text) | |||||
| @@ -65,26 +65,52 @@ class TestTagger(object): | |||||
| assert len(sad_thought_posts) == 1 | assert len(sad_thought_posts) == 1 | ||||
| assert "sad-post.html" in sad_thought_posts | assert "sad-post.html" in sad_thought_posts | ||||
| def test_tagger_archives_generated(self): | |||||
| gen = Generator(self.s) | |||||
| gen.load_site_if_needed() | |||||
| gen.load_template_if_needed() | |||||
| gen.generate_all() | |||||
| tags_folder = self.deploy.child_folder('blog/tags') | |||||
| assert tags_folder.exists | |||||
| tags = ['sad', 'happy', 'angry', 'thoughts', 'events'] | |||||
| archives = (File(tags_folder.child("%s.html" % tag)) for tag in tags) | |||||
| for archive in archives: | |||||
| assert archive.exists | |||||
| from pyquery import PyQuery | |||||
| 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' | |||||
| q = PyQuery(File(tags_folder.child('happy.html')).read_all()) | |||||
| assert q | |||||
| assert q('li').length == 1 | |||||
| assert q('li a:first-child').attr('href') == '/blog/happy-post.html' | |||||
| q = PyQuery(File(tags_folder.child('angry.html')).read_all()) | |||||
| assert q | |||||
| assert q('li').length == 1 | |||||
| assert q('li a:first-child').attr('href') == '/blog/angry-post.html' | |||||
| q = PyQuery(File(tags_folder.child('thoughts.html')).read_all()) | |||||
| assert q | |||||
| assert q('li').length == 3 | |||||
| assert q('li a:eq(0)').attr('href') == '/blog/happy-post.html' | |||||
| assert q('li a:eq(1)').attr('href') == '/blog/angry-post.html' | |||||
| assert q('li a:eq(2)').attr('href') == '/blog/sad-post.html' | |||||
| q = PyQuery(File(tags_folder.child('events.html')).read_all()) | |||||
| assert q | |||||
| # def test_tagger_archives_generated(): | |||||
| # gen = Generator(self.s) | |||||
| # gen.load_site_if_needed() | |||||
| # gen.load_template_if_needed() | |||||
| # gen.generate_all() | |||||
| # tags_folder = self.deploy.child_folder('blog/tags') | |||||
| # | |||||
| # blog_node = self.s.node_from_relative_path('blog') | |||||
| # res_by_tag = | |||||
| # for resource in blog_node.walk_resources(): | |||||
| # | |||||
| # | |||||
| # assert tags_folder.exists | |||||
| # tags = ['sad', 'happy', 'angry', 'thoughts'] | |||||
| # | |||||
| # archives = (File(tags_folder.child("%s.html" % tag)) for tag in tags) | |||||
| # for archive in archives: | |||||
| # assert archive.exists | |||||
| # assert | |||||
| assert q('li').length == 1 | |||||
| assert q('li a:first-child').attr('href') == '/blog/another-sad-post.html' | |||||
| @@ -1,9 +1,8 @@ | |||||
| {% if tag and tag.resources -%} | |||||
| <h1>Posts tagged: {{ tag }} in {{ node.name|title }}</h1> | |||||
| <ul> | <ul> | ||||
| {% for resource in tag.resources -%} | |||||
| {% for resource in walker() -%} | |||||
| <li> | <li> | ||||
| <a href="{{ content_url(resource.url) }}">{{ resource.meta.title }}</a> | <a href="{{ content_url(resource.url) }}">{{ resource.meta.title }}</a> | ||||
| </li> | </li> | ||||
| {%- endfor %} | {%- endfor %} | ||||
| </ul> | |||||
| {%- endif %} | |||||
| </ul> | |||||