Categories #121

Open
eshlox opened this Issue Feb 15, 2013 · 6 comments

Comments

Projects
None yet
5 participants

eshlox commented Feb 15, 2013

It would be great to have possibility to use categories, not just tags. ;-)

I also think categories are very important for separating posts. Pelican supports it while nikola not. So I have to escape from nikola.

Owner

posativ commented Apr 14, 2013

Support for categories will make it definitely into the next major release (0.8).

Contributor

maphew commented Apr 29, 2013

This is possible now, from the github version; the below adapted from an email exchange between myself and Martin:

... I want example.com/Musings/foo-baz, as the permanent URL,
where "Musings" is the primary or first tag assigned to the post.

the current syntax only allows access to a single attribute (e.g. :name gets the attribute "name" from the entry instance), but what you want is basically categories (I think) and you can achieve this with a custom attribute, let's call it "category":

---
title: Foo
category: musings  # or musings/baz
---

and add /:category/:slug/ as URL rule, so in conf.py:

    '/:category/:slug/': {'views': ['entry', 'draft']},    #new way 
    #'/:year/:slug/': {'views': ['entry', 'draft']},        #default blog way, now commented out

You'll need to delete the .cache and output before compiling again (the former to avoid tracebacks and the latter to avoid duplicates posts between the old and new path structures).

I'm using this method right now at www.maphew.com

Owner

posativ commented Apr 30, 2013

You'll need to delete the .cache [...] to avoid tracebacks

This is definitely a bug, the cache should not throw tracebacks when you change your configuration.

posativ added a commit that referenced this issue May 20, 2013

initial category support, part of #121
Add support for categories to Acrylamid. Categories are either explicitly set
in the metadata section (`category: foo/bar`) or derived from the path of the
post, e.g. `content/projects/python/foo-bar.txt` will set the category to
`projects/python`.

    content/
    ├── projects
    │   ├── bla.txt
    │   └── python
    │       └── fuu.txt
    └── test
        └── sample-entry.txt

The directory structure above and the following conf.py configuration

    '/category/:name/': {'view': 'category', 'filters': 'summarize',
                         'pagination': '/category/:name/:num/'},

renders the following on `$ acrylamid compile`:

     create  [0.34s] output/2013/i-am-only-in-python/index.html
     create  [0.02s] output/2013/i-m-a-projects-post/index.html
     create  [0.01s] output/2012/die-verwandlung/index.html
     create  [0.00s] output/category/test/index.html
     create  [0.00s] output/category/projects/index.html
     create  [0.00s] output/category/projects/python/index.html

Both, bla.txt and fuu.txt are shown on the project listing, but only the
fuu.txt post appears on the projects/python listing.

To link to the category listing, use the following Jinja2 code instead of
the tag code:

   {% if 'category' in env.views and entry.category %}
       <p>categorized in
           {% for link in entry.category | categorize %}
               <a href="{{ env.path + link.href }}" rel="category">{{ link.title }}</a>
               {%- if loop.revindex > 2 -%}
               ,
               {%- elif loop.revindex == 2 %}
               and
               {% endif %}
           {% endfor %}
       </p>

This uses the new `categorize` filter which is available when you have the
category view enabled. It takes the category list from `entry.category` and
yields the hierarchical categories, e.g. projects/python yields projects and
projects/python.
Contributor

hooli commented May 27, 2013

Similar to maphew comment, I found this rule works, which might be helpful for 0.7

'/:topic/:slug.html': {'view': 'page', 'template': 'flatpage.html' , "if": lambda e: hasattr(e, 'topic') },
'/:slug.html': {'view': 'page', 'template': 'flatpage.html' , "if": lambda e: hasattr(e, 'topic') == False },

The page will use the second rule if it doesn't have a topic.

The initial category support looks great. Just wondered:

a) Would it be possible to have a list of root directories to exclude from being categorized?

b) Could be useful to have the full category path "x/y/z" as a variable for any route rule, in addition to :name on category views.

c) Presume infile metadata overriding the defaults for directory path and the category array will be available in the templates

Owner

posativ commented May 29, 2013

The page will use the second rule if it doesn't have a topic.

Yes, I implemented the "if": lambda ... exactly for such purposes, but I am still not satisfied with this solution as the lambda expression grows bigger as you want more filtering rules. I still think about a exclusion of posts that match the "if": lambda-clause like this:

VIEWS = {
    '/:topic/slug.html': {..., 'if': lambda ..., exclude=True},
    '/:slug.html': {...}  # no lambda expression required
}

Should be possible with an ordered dict (some ast magic).

The initial category support looks great. Just wondered:

a) Would it be possible to have a list of root directories to exclude from being categorized?

It should be definitely possible to exclude certain root directories and/or sub directories. Maybe with a path translation lambda/function, where you can modify the directory inserted as :name, e.g.:

def foo(category):
    # do something with category, e.g. category.replace('topic/', '')
    return category

[...]

`/category/:name.html`: {'view': category, 'translate': foo},

b) Could be useful to have the full category path "x/y/z" as a variable for any route rule, in addition to :name on category views.

Should be possible, if you add e.g. /:category/:year-:month-:day/:slug.html as entry route. This replaces :category with entry.category which is either set in the metadata or retrieved from the path (but it is not affected by a path translation function mentioned above, though). (entry.category should probably always return the category name after the path translation has been performed.)

c) Presume infile metadata overriding the defaults for directory path and the category array will be available in the templates

Yes, that's still on my todo list.

posativ added a commit that referenced this issue Jun 7, 2013

initial category support, part of #121
Add support for categories to Acrylamid. Categories are either explicitly set
in the metadata section (`category: foo/bar`) or derived from the path of the
post, e.g. `content/projects/python/foo-bar.txt` will set the category to
`projects/python`.

    content/
    ├── projects
    │   ├── bla.txt
    │   └── python
    │       └── fuu.txt
    └── test
        └── sample-entry.txt

The directory structure above and the following conf.py configuration

    '/category/:name/': {'view': 'category', 'filters': 'summarize',
                         'pagination': '/category/:name/:num/'},

renders the following on `$ acrylamid compile`:

     create  [0.34s] output/2013/i-am-only-in-python/index.html
     create  [0.02s] output/2013/i-m-a-projects-post/index.html
     create  [0.01s] output/2012/die-verwandlung/index.html
     create  [0.00s] output/category/test/index.html
     create  [0.00s] output/category/projects/index.html
     create  [0.00s] output/category/projects/python/index.html

Both, bla.txt and fuu.txt are shown on the project listing, but only the
fuu.txt post appears on the projects/python listing.

To link to the category listing, use the following Jinja2 code instead of
the tag code:

   {% if 'category' in env.views and entry.category %}
       <p>categorized in
           {% for link in entry.category | categorize %}
               <a href="{{ env.path + link.href }}" rel="category">{{ link.title }}</a>
               {%- if loop.revindex > 2 -%}
               ,
               {%- elif loop.revindex == 2 %}
               and
               {% endif %}
           {% endfor %}
       </p>

This uses the new `categorize` filter which is available when you have the
category view enabled. It takes the category list from `entry.category` and
yields the hierarchical categories, e.g. projects/python yields projects and
projects/python.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment