diff --git a/categories/templatetags/categories.py b/categories/templatetags/categories.py deleted file mode 100644 index 9e23903..0000000 --- a/categories/templatetags/categories.py +++ /dev/null @@ -1,62 +0,0 @@ -from django import template -from ellington.categories.models import Category - -class CategoryNode(template.Node): - def __init__(self, category, varname, hierarchy): - # TODO: improve quote removal. ``[1:-1]`` feels icky. - if '\"' in category: - self.category = category[1:-1] - else: - self.category = category - self.varname = varname - if '\"' in hierarchy: - self.hierarchy = hierarchy[1:-1] - else: - self.hierarchy = hierarchy - - def render(self, context): - try: - context[self.varname] = Category.objects.get( - hierarchy__slug=self.hierarchy, - slug_path=self.category) - except Category.DoesNotExist: - context[self.varname] = None - return '' - -def get_category(parser, token): - """ - Retrieves the specified category. - - Syntax:: - - {% get_category [category] as varname [hierarchy slug] %} - - Example:: - - {% get_category "/agriculture/dairy" as dairy hierarchy "business" %} - - [hierarchy slug] is optional. If not specified, the "news" hierarchy - will be used. - """ - bits = token.contents.split() - if len(bits) < 4: - raise template.TemplateSyntaxError, "%s tag requires at least three arguments." % bits[0] - if bits[2] != 'as': - raise template.TemplateSyntaxError, "%s tag requires the third argument to be 'as'." % bits[0] - if not len(bits) in (4, 6): - raise template.TemplateSyntaxError, "%s tag requires exactly 3, or 5 arguments." % bits[0] - category = bits[1] - varname = bits[3] - hierarchy = "news" - if len(bits) == 4: - return CategoryNode(category, varname, hierarchy) - elif len(bits) == 6: - if bits[4] == 'hierarchy': - return CategoryNode(category, varname, bits[5]) - else: - raise template.TemplateSyntaxError, "Fifth argument to %s tag must be 'hierarchy'" % bits[0] - else: - raise template.TemplateSyntaxError, "Arguments to %s tag are malformed." % bits[0] - -register = template.Library() -register.tag(get_category) diff --git a/categories/templatetags/category_tags.py b/categories/templatetags/category_tags.py new file mode 100644 index 0000000..4b18261 --- /dev/null +++ b/categories/templatetags/category_tags.py @@ -0,0 +1,64 @@ +from django import template +from categories.models import Category +from mptt.utils import drilldown_tree_for_node + +class CategoryNode(template.Node): + + def __init__(self, category, varname): + if category.startswith('"') and category.endswith('"'): + self.category = category[1:-1] + else: + self.category = category + + if self.category.startswith('/'): + self.category = self.category[1:] + else: + self.category = category + if self.category.endswith('/'): + self.category = self.category[:-1] + + self.varname = varname + + def render(self, context): + try: + cat_list = self.category.split('/') + categories = Category.objects.filter(name = cat_list[-1], level=len(cat_list)-1) + + if len(cat_list) == 1 and len(categories) > 1: + context[self.varname] = None + return '' + if len(categories) == 1: + context[self.varname] = drilldown_tree_for_node(categories[0]) + else: + for item in categories: + if item.parent.name == cat_list[-2]: + context[self.varname] = drilldown_tree_for_node(item) + except Category.DoesNotExist: + context[self.varname] = None + return '' + + +def get_category(parser, token): + """ + Retrieves the specified category tree. + + Syntax:: + + {% get_category "category name" as varname %} + + Example:: + + {% get_category "/agriculture/dairy" as dairy %} + + """ + bits = token.contents.split() + error_str = '%(tagname)s tag should be in the format {%% %(tagname)s ' \ + '"category name" as varname %%}.' + if len(bits) != 4 or bits[2] != 'as': + raise template.TemplateSyntaxError, error_str % {'tagname': bits[0]} + category = bits[1] + varname = bits[3] + return CategoryNode(category, varname) + +register = template.Library() +register.tag(get_category) diff --git a/categories/tests/__init__.py b/categories/tests/__init__.py index d247ec3..68846cb 100644 --- a/categories/tests/__init__.py +++ b/categories/tests/__init__.py @@ -1,8 +1,4 @@ -from ellington.categories.tests import views -from ellington.categories.tests.templatetags import * +from categories.tests import views +from categories.tests.templatetags import * -__fixtures__ = ['categories.yaml'] - -__test__ = { -'VIEWS': views -} +__fixtures__ = ['categories.json'] diff --git a/categories/tests/category_import.py b/categories/tests/category_import.py index a0d2a57..ead1514 100644 --- a/categories/tests/category_import.py +++ b/categories/tests/category_import.py @@ -5,7 +5,7 @@ import unittest, os from categories.models import Category from categories.management.commands.import_categories import Command -class CategoryTest(unittest.TestCase): +class CategoryImportTest(unittest.TestCase): def setUp(self): pass diff --git a/categories/tests/templatetags.py b/categories/tests/templatetags.py index 201fa32..d49bb82 100644 --- a/categories/tests/templatetags.py +++ b/categories/tests/templatetags.py @@ -1,36 +1,46 @@ -from ellington.core.utils.test import TemplateTestCase +from django.test import TestCase +from django import template -class GetCategory(TemplateTestCase): - fixtures = ['categories.yaml'] +class GetCategoryTest(TestCase): + + fixtures = ['musicgenres.json'] + + def render_template(self, template_string, context={}): + """ + Return the rendered string or raise an exception. + """ + tpl = template.Template(template_string) + ctxt = template.Context(context) + return tpl.render(ctxt) - def test_too_few_arguments(self): - """Ensure that get_cateogry bails is we don't give it enough arguments.""" - ex = self.render('{% load categories %}{% get_category %}') - self.assertEqual(str(ex), 'get_category tag requires at least three arguments.') - self.assertTemplateSyntaxError(ex) + def testTooFewArguments(self): + """ + Ensure that get_cateogry raises an exception if there aren't enough arguments. + """ + self.assertRaises(template.TemplateSyntaxError, self.render_template, '{% load category_tags %}{% get_category %}') - def test_as(self): - """Test that the second argument to get_category is 'as'.""" - ex = self.render('{% load categories %}{% get_category "foo" notas bar %}') - self.assertEqual(str(ex), "get_category tag requires the third argument to be 'as'.") - self.assertTemplateSyntaxError(ex) + def testTooManyArguments(self): + """ + Ensure that get_category raises an exception if there are too many arguments. + """ + self.assertRaises(template.TemplateSyntaxError, self.render_template, '{% load category_tags %}{% get_category "/Rock" as too many arguments %}') - def test_wrong_length(self): - """Test that calling get_category with the wrong number of arguments properly raises an exception.""" - ex = self.render('{% load categories %}{% get_category one as three hierarchy four five %}') - self.assertEqual(str(ex), "get_category tag requires exactly 3, or 5 arguments.") - self.assertTemplateSyntaxError(ex) - ex2 = self.render('{% load categories %}{% get_category one as three four five six seven %}') - self.assertEqual(str(ex2), "get_category tag requires exactly 3, or 5 arguments.") - self.assertTemplateSyntaxError(ex2) + def testAsIsSecondArgument(self): + """ + Test that the second argument to get_category is 'as'. + """ + self.assertRaises(template.TemplateSyntaxError, self.render_template, '{% load category_tags %}{% get_category "Rock" notas rock %}') - def test_basic_usage(self): - """Test that we can properly retrieve a category with the default hierarchy.""" - resp = self.render('{% load categories %}{% get_category "/monster-attacks" as cat %}{{ cat }}') - self.assertEqual(resp, u'[News] /Monster Attacks') - - def test_hierarchy(self): - """Verify that we can summon Mothra.""" - resp = self.render('{% load categories %}{% get_category "/weather/disasters/mothra" as cat hierarchy "news" %}{{ cat }}') - self.assertEqual(resp, u'[News] /Weather/Disasters/Mothra') + def testBasicUsage(self): + """ + Test that we can properly retrieve a category. + """ + rock_resp = u'Rock\rRock > Surf rock\rRock > Southern rock\rRock > Soft rock\rRock > Rock and roll\rRock > Rap rock\rRock > Punk rock\rRock > Psychedelic rock\rRock > Progressive rock\rRock > Power pop\rRock > Paisley Underground\rRock > New Wave\rRock > J-Rock\rRock > Heavy metal\rRock > Hard rock\rRock > Glam rock\rRock > Garage rock\rRock > Folk rock\rRock > Desert rock\rRock > Dark cabaret\rRock > C-Rock\rRock > Blues-rock\rRock > Alternative rock\r' + resp = self.render_template('{% load category_tags %}{% get_category "/Rock" as cat_list %}{% for cat in cat_list %}{{ cat }}\r{% endfor %}') + self.assertEqual(resp, rock_resp) + + crock_resp = u'Rock\rRock > C-Rock\r' + resp = self.render_template('{% load category_tags %}{% get_category "/Rock/C-Rock" as cat_list %}{% for cat in cat_list %}{{ cat }}\r{% endfor %}') + self.assertEqual(resp, crock_resp) + \ No newline at end of file