@@ -5,6 +5,8 @@ Contains classes and utilities related to meta data in hyde. | |||
import re | |||
from operator import attrgetter | |||
from itertools import ifilter | |||
from functools import partial | |||
from hyde.model import Expando | |||
from hyde.plugin import Plugin | |||
from hyde.fs import File, Folder | |||
@@ -394,3 +396,120 @@ extends: false | |||
archive_file.write(text.strip()) | |||
self.site.content.add_resource(archive_file) | |||
def filter_method(item, settings=None): | |||
""" | |||
Returns true if all the filters in the | |||
given settings evaluate to True. | |||
""" | |||
all_match = True | |||
default_filters = {} | |||
filters = {} | |||
if hasattr(settings, 'filters'): | |||
filters.update(default_filters) | |||
filters.update(settings.filters.__dict__) | |||
for field, value in filters.items(): | |||
try: | |||
res = attrgetter(field)(item) | |||
except: | |||
res = None | |||
if res != value: | |||
all_match = False | |||
break | |||
return all_match | |||
def attributes_checker(item, attributes=None): | |||
""" | |||
Checks if the given list of attributes exist. | |||
""" | |||
try: | |||
x = attrgetter(*attributes)(item) | |||
return True | |||
except AttributeError: | |||
return False | |||
def sort_method(node, settings=None): | |||
""" | |||
Sorts the resources in the given node based on the | |||
given settings. | |||
""" | |||
attr = 'name' | |||
if settings and hasattr(settings, 'attr') and settings.attr: | |||
attr = settings.attr | |||
reverse = False | |||
if settings and hasattr(settings, 'reverse'): | |||
reverse = settings.reverse | |||
if not isinstance(attr, list): | |||
attr = [attr] | |||
filter_ = partial(filter_method, settings=settings) | |||
excluder_ = partial(attributes_checker, attributes=attr) | |||
resources = ifilter(lambda x: excluder_(x) and filter_(x), | |||
node.walk_resources()) | |||
return sorted(resources, | |||
key=attrgetter(*attr), | |||
reverse=reverse) | |||
class SorterPlugin(Plugin): | |||
""" | |||
Sorter plugin for hyde. Adds the ability to do | |||
sophisticated sorting by expanding the site objects | |||
to support prebuilt sorting methods. These methods | |||
can be used in the templates directly. | |||
Configuration example | |||
--------------------- | |||
#yaml | |||
sorter: | |||
kind: | |||
# Sorts by this attribute name | |||
# Uses `attrgetter` on the resource object | |||
attr: source_file.kind | |||
# The filters to be used before sorting | |||
# This can be used to remove all the items | |||
# that do not apply. For example, | |||
# filtering non html content | |||
filters: | |||
source_file.kind: html | |||
is_processable: True | |||
meta.is_listable: True | |||
""" | |||
def __init__(self, site): | |||
super(SorterPlugin, self).__init__(site) | |||
def begin_site(self): | |||
""" | |||
Initialize plugin. Add a sort and match method | |||
for every configuration mentioned in site settings | |||
""" | |||
config = self.site.config | |||
if not hasattr(config, 'sorter'): | |||
return | |||
for name, settings in config.sorter.__dict__.items(): | |||
sort_method_name = 'walk_resources_sorted_by_%s' % name | |||
self.logger.debug("Adding sort methods for [%s]" % name) | |||
add_method(Node, sort_method_name, sort_method, settings=settings) | |||
match_method_name = 'is_%s' % name | |||
add_method(Resource, match_method_name, filter_method, settings) | |||
prev_att = 'prev_by_%s' % name | |||
next_att = 'next_by_%s' % name | |||
setattr(Resource, prev_att, None) | |||
setattr(Resource, next_att, None) | |||
walker = getattr(self.site.content, | |||
sort_method_name, | |||
self.site.content.walk_resources) | |||
for prev, next in pairwalk(walker()): | |||
setattr(prev, next_att, next) | |||
setattr(next, prev_att, prev) | |||
@@ -5,7 +5,7 @@ base_url: / # The base url for autogenerated links. | |||
plugins: | |||
- hyde.ext.plugins.meta.MetaPlugin | |||
- hyde.ext.plugins.meta.AutoExtendPlugin | |||
- hyde.ext.plugins.sorter.SorterPlugin | |||
- hyde.ext.plugins.meta.SorterPlugin | |||
- hyde.ext.plugins.meta.TaggerPlugin | |||
- hyde.ext.plugins.text.SyntextPlugin | |||
- hyde.ext.plugins.text.TextlinksPlugin | |||
@@ -12,7 +12,7 @@ plugins: | |||
- hyde.ext.plugins.meta.MetaPlugin | |||
- hyde.ext.plugins.meta.AutoExtendPlugin | |||
# Plugins needed for the advances section. | |||
- hyde.ext.plugins.sorter.SorterPlugin | |||
- hyde.ext.plugins.meta.SorterPlugin | |||
- hyde.ext.plugins.grouper.GrouperPlugin | |||
- hyde.ext.plugins.meta.TaggerPlugin | |||
context: | |||
@@ -5,7 +5,7 @@ Use nose | |||
`$ nosetests` | |||
""" | |||
from hyde.ext.plugins.meta import MetaPlugin | |||
from hyde.ext.plugins.sorter import SorterPlugin | |||
from hyde.ext.plugins.meta import SorterPlugin | |||
from hyde.ext.plugins.grouper import GrouperPlugin | |||
from hyde.generator import Generator | |||
from hyde.site import Site | |||
@@ -30,7 +30,7 @@ class TestGrouperSingleLevel(object): | |||
nodemeta: meta.yaml | |||
plugins: | |||
- hyde.ext.plugins.meta.MetaPlugin | |||
- hyde.ext.plugins.sorter.SorterPlugin | |||
- hyde.ext.plugins.meta.SorterPlugin | |||
- hyde.ext.plugins.grouper.GrouperPlugin | |||
sorter: | |||
kind: | |||
@@ -236,7 +236,7 @@ class TestGrouperSingleLevel(object): | |||
nodemeta: meta.yaml | |||
plugins: | |||
- hyde.ext.plugins.meta.MetaPlugin | |||
- hyde.ext.plugins.sorter.SorterPlugin | |||
- hyde.ext.plugins.meta.SorterPlugin | |||
- hyde.ext.plugins.grouper.GrouperPlugin | |||
sorter: | |||
kind: | |||
@@ -321,4 +321,4 @@ class TestGrouperSingleLevel(object): | |||
gen.load_site_if_needed() | |||
gen.load_template_if_needed() | |||
out = gen.template.render(text, {'site':self.s}) | |||
assert_html_equals(out, expected) | |||
assert_html_equals(out, expected) |
@@ -5,7 +5,12 @@ Use nose | |||
`$ nosetests` | |||
""" | |||
from hyde.ext.plugins.meta import MetaPlugin | |||
<<<<<<< HEAD | |||
from hyde.ext.plugins.sorter import SorterPlugin | |||
======= | |||
from hyde.ext.plugins.meta import SorterPlugin | |||
from hyde.fs import File, Folder | |||
>>>>>>> Move the sorter plugin into the meta module. | |||
from hyde.generator import Generator | |||
from hyde.site import Site | |||
from hyde.model import Config, Expando | |||
@@ -30,7 +35,7 @@ class TestSorter(object): | |||
def test_walk_resources_sorted(self): | |||
s = Site(TEST_SITE) | |||
s.load() | |||
s.config.plugins = ['hyde.ext.sorter.SorterPlugin'] | |||
s.config.plugins = ['hyde.ext.meta.SorterPlugin'] | |||
s.config.sorter = Expando(dict(kind=dict(attr=['source_file.kind', 'name']))) | |||
SorterPlugin(s).begin_site() | |||
@@ -54,7 +59,7 @@ class TestSorter(object): | |||
def test_walk_resources_sorted_reverse(self): | |||
s = Site(TEST_SITE) | |||
s.load() | |||
s.config.plugins = ['hyde.ext.sorter.SorterPlugin'] | |||
s.config.plugins = ['hyde.ext.meta.SorterPlugin'] | |||
s.config.sorter = Expando(dict(kind=dict(attr=['source_file.kind', 'name'], reverse=True))) | |||
SorterPlugin(s).begin_site() | |||
@@ -80,7 +85,7 @@ class TestSorter(object): | |||
s = Site(TEST_SITE) | |||
cfg = """ | |||
plugins: | |||
- hyde.ext.sorter.SorterPlugin | |||
- hyde.ext.meta.SorterPlugin | |||
sorter: | |||
kind2: | |||
filters: | |||
@@ -104,7 +109,7 @@ class TestSorter(object): | |||
s = Site(TEST_SITE) | |||
cfg = """ | |||
plugins: | |||
- hyde.ext.sorter.SorterPlugin | |||
- hyde.ext.meta.SorterPlugin | |||
sorter: | |||
multi: | |||
attr: | |||
@@ -142,7 +147,7 @@ class TestSorter(object): | |||
s = Site(TEST_SITE) | |||
cfg = """ | |||
plugins: | |||
- hyde.ext.sorter.SorterPlugin | |||
- hyde.ext.meta.SorterPlugin | |||
sorter: | |||
kind2: | |||
filters: | |||
@@ -167,7 +172,7 @@ class TestSorter(object): | |||
s = Site(TEST_SITE) | |||
cfg = """ | |||
plugins: | |||
- hyde.ext.sorter.SorterPlugin | |||
- hyde.ext.meta.SorterPlugin | |||
sorter: | |||
kind2: | |||
filters: | |||
@@ -203,7 +208,7 @@ class TestSorter(object): | |||
s = Site(TEST_SITE) | |||
cfg = """ | |||
plugins: | |||
- hyde.ext.sorter.SorterPlugin | |||
- hyde.ext.meta.SorterPlugin | |||
sorter: | |||
folder_name: | |||
attr: | |||
@@ -244,7 +249,7 @@ class TestSorter(object): | |||
title: NahNahNah | |||
plugins: | |||
- hyde.ext.plugins.meta.MetaPlugin | |||
- hyde.ext.plugins.sorter.SorterPlugin | |||
- hyde.ext.plugins.meta.SorterPlugin | |||
sorter: | |||
time: | |||
attr: meta.time | |||
@@ -290,7 +295,7 @@ class TestSorterMeta(object): | |||
def test_attribute_checker_no_meta(self): | |||
s = Site(TEST_SITE) | |||
s.load() | |||
from hyde.ext.plugins.sorter import attributes_checker | |||
from hyde.ext.plugins.meta import attributes_checker | |||
for r in s.content.walk_resources(): | |||
assert not attributes_checker(r, ['meta.index']) | |||
@@ -298,7 +303,7 @@ class TestSorterMeta(object): | |||
s = Site(TEST_SITE) | |||
s.load() | |||
MetaPlugin(s).begin_site() | |||
from hyde.ext.plugins.sorter import attributes_checker | |||
from hyde.ext.plugins.meta import attributes_checker | |||
have_index = ["angry-post.html", | |||
"another-sad-post.html", | |||
"happy-post.html"] | |||
@@ -4,7 +4,7 @@ media_url: /media # URL where the media files are served from. | |||
base_url: / # The base url for autogenerated links. | |||
plugins: | |||
- hyde.ext.plugins.meta.MetaPlugin | |||
- hyde.ext.plugins.sorter.SorterPlugin | |||
- hyde.ext.plugins.meta.SorterPlugin | |||
- hyde.ext.plugins.structure.PaginatorPlugin | |||
meta: | |||
nodemeta: meta.yaml | |||
@@ -5,7 +5,7 @@ base_url: / # The base url for autogenerated links. | |||
plugins: | |||
- hyde.ext.plugins.meta.MetaPlugin | |||
- hyde.ext.plugins.meta.AutoExtendPlugin | |||
- hyde.ext.plugins.sorter.SorterPlugin | |||
- hyde.ext.plugins.meta.SorterPlugin | |||
- hyde.ext.plugins.text.TextlinksPlugin | |||
meta: | |||
nodemeta: meta.yaml | |||
@@ -5,7 +5,7 @@ base_url: / # The base url for autogenerated links. | |||
plugins: | |||
- hyde.ext.plugins.meta.MetaPlugin | |||
- hyde.ext.plugins.meta.AutoExtendPlugin | |||
- hyde.ext.plugins.sorter.SorterPlugin | |||
- hyde.ext.plugins.meta.SorterPlugin | |||
- hyde.ext.plugins.meta.TaggerPlugin | |||
- hyde.ext.plugins.text.TextlinksPlugin | |||
meta: | |||
@@ -5,7 +5,7 @@ base_url: / # The base url for autogenerated links. | |||
plugins: | |||
- hyde.ext.plugins.meta.MetaPlugin | |||
- hyde.ext.plugins.meta.AutoExtendPlugin | |||
- hyde.ext.plugins.sorter.SorterPlugin | |||
- hyde.ext.plugins.meta.SorterPlugin | |||
- hyde.ext.plugins.meta.TaggerPlugin | |||
- hyde.ext.plugins.text.SyntextPlugin | |||
- hyde.ext.plugins.text.TextlinksPlugin | |||