Browse Source

Move the grouper plugin into meta module.

main
Elliott Sales de Andrade 13 years ago
committed by Lakshmi Vyasarajan
parent
commit
b7ce44f305
3 changed files with 213 additions and 5 deletions
  1. +205
    -2
      hyde/ext/plugins/meta.py
  2. +1
    -1
      hyde/layouts/starter/site.yaml
  3. +7
    -2
      hyde/tests/ext/test_grouper.py

+ 205
- 2
hyde/ext/plugins/meta.py View File

@@ -4,14 +4,15 @@ Contains classes and utilities related to meta data in hyde.
"""

import re
from collections import namedtuple
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
from hyde.site import Node
from hyde.util import add_method
from hyde.site import Node, Resource
from hyde.util import add_method, add_property, pairwalk
import yaml


@@ -513,3 +514,205 @@ class SorterPlugin(Plugin):
setattr(prev, next_att, next)
setattr(next, prev_att, prev)


Grouper = namedtuple('Grouper', 'group resources')

class Group(Expando):
"""
A wrapper class for groups. Adds methods for
grouping resources.
"""

def __init__(self, grouping, parent=None):
self.name = 'groups'
self.parent = parent
self.root = self
self.root = parent.root if parent else self
self.groups = []
self.sorter = getattr(grouping, 'sorter', None)
if hasattr(parent, 'sorter'):
self.sorter = parent.sorter
super(Group, self).__init__(grouping)

add_method(Node,
'walk_%s_groups' % self.name,
Group.walk_groups_in_node,
group=self)
add_method(Node,
'walk_resources_grouped_by_%s' % self.name,
Group.walk_resources,
group=self)
add_property(Resource,
'%s_group' % self.name,
Group.get_resource_group,
group=self)
add_method(Resource,
'walk_%s_groups' % self.name,
Group.walk_resource_groups,
group=self)

def set_expando(self, key, value):
"""
If the key is groups, creates group objects instead of
regular expando objects.
"""
if key == "groups":
self.groups = [Group(group, parent=self) for group in value]
else:
return super(Group, self).set_expando(key, value)

@staticmethod
def get_resource_group(resource, group):
"""
This method gets attached to the resource object.
Returns group and its ancestors that the resource
belongs to, in that order.
"""
try:
group_name = getattr(resource.meta, group.root.name)
except AttributeError:
group_name = None

return next((g for g in group.walk_groups()
if g.name == group_name), None) \
if group_name \
else None

@staticmethod
def walk_resource_groups(resource, group):
"""
This method gets attached to the resource object.
Returns group and its ancestors that the resource
belongs to, in that order.
"""
try:
group_name = getattr(resource.meta, group.root.name)
except AttributeError:
group_name = None
if group_name:
for g in group.walk_groups():
if g.name == group_name:
return reversed(list(g.walk_hierarchy()))
return []

@staticmethod
def walk_resources(node, group):
"""
The method that gets attached to the node
object for walking the resources in the node
that belong to this group.
"""
for group in group.walk_groups():
for resource in group.walk_resources_in_node(node):
yield resource

@staticmethod
def walk_groups_in_node(node, group):
"""
The method that gets attached to the node
object for walking the groups in the node.
"""
walker = group.walk_groups()
for g in walker:
lister = g.walk_resources_in_node(node)
yield Grouper(group=g, resources=lister)

def walk_hierarchy(self):
"""
Walks the group hierarchy starting from
this group.
"""
g = self
yield g
while g.parent:
yield g.parent
g = g.parent

def walk_groups(self):
"""
Walks the groups in the current group
"""
yield self
for group in self.groups:
for child in group.walk_groups():
yield child

def walk_resources_in_node(self, node):
"""
Walks the resources in the given node
sorted based on sorter configuration in this
group.
"""
walker = 'walk_resources'
if hasattr(self, 'sorter') and self.sorter:
walker = 'walk_resources_sorted_by_' + self.sorter
walker = getattr(node, walker, getattr(node, 'walk_resources'))
for resource in walker():
try:
group_value = getattr(resource.meta, self.root.name)
except AttributeError:
continue
if group_value == self.name:
yield resource

class GrouperPlugin(Plugin):
"""
Grouper plugin for hyde. Adds the ability to do
group resources and nodes in an arbitrary
hierarchy.

Configuration example
---------------------
#yaml
sorter:
kind:
atts: source.kind
grouper:
hyde:
# Categorizes the nodes and resources
# based on the groups specified here.
# The node and resource should be tagged
# with the categories in their metadata
sorter: kind # A reference to the sorter
description: Articles about hyde
groups:
-
name: announcements
description: Hyde release announcements
-
name: making of
description: Articles about hyde design decisions
-
name: tips and tricks
description: >
Helpful snippets and tweaks to
make hyde more awesome.
"""
def __init__(self, site):
super(GrouperPlugin, self).__init__(site)

def begin_site(self):
"""
Initialize plugin. Add the specified groups to the
site context variable.
"""
config = self.site.config
if not hasattr(config, 'grouper'):
return
if not hasattr(self.site, 'grouper'):
self.site.grouper = {}

for name, grouping in self.site.config.grouper.__dict__.items():
grouping.name = name
prev_att = 'prev_in_%s' % name
next_att = 'next_in_%s' % name
setattr(Resource, prev_att, None)
setattr(Resource, next_att, None)
self.site.grouper[name] = Group(grouping)
walker = Group.walk_resources(
self.site.content, self.site.grouper[name])

for prev, next in pairwalk(walker):
setattr(next, prev_att, prev)
setattr(prev, next_att, next)


+ 1
- 1
hyde/layouts/starter/site.yaml View File

@@ -13,7 +13,7 @@ plugins:
- hyde.ext.plugins.meta.AutoExtendPlugin
# Plugins needed for the advances section.
- hyde.ext.plugins.meta.SorterPlugin
- hyde.ext.plugins.grouper.GrouperPlugin
- hyde.ext.plugins.meta.GrouperPlugin
- hyde.ext.plugins.meta.TaggerPlugin
context:
data:


+ 7
- 2
hyde/tests/ext/test_grouper.py View File

@@ -6,7 +6,12 @@ Use nose
"""
from hyde.ext.plugins.meta import MetaPlugin
from hyde.ext.plugins.meta import SorterPlugin
<<<<<<< HEAD
from hyde.ext.plugins.grouper import GrouperPlugin
=======
from hyde.ext.plugins.meta import GrouperPlugin
from hyde.fs import File, Folder
>>>>>>> Move the grouper plugin into meta module.
from hyde.generator import Generator
from hyde.site import Site
from hyde.model import Config, Expando
@@ -31,7 +36,7 @@ class TestGrouperSingleLevel(object):
plugins:
- hyde.ext.plugins.meta.MetaPlugin
- hyde.ext.plugins.meta.SorterPlugin
- hyde.ext.plugins.grouper.GrouperPlugin
- hyde.ext.plugins.meta.GrouperPlugin
sorter:
kind:
attr:
@@ -237,7 +242,7 @@ class TestGrouperSingleLevel(object):
plugins:
- hyde.ext.plugins.meta.MetaPlugin
- hyde.ext.plugins.meta.SorterPlugin
- hyde.ext.plugins.grouper.GrouperPlugin
- hyde.ext.plugins.meta.GrouperPlugin
sorter:
kind:
attr:


Loading…
Cancel
Save