Browse Source

Add related_posts option RELATED_POSTS_SKIP_SAME_CATEGORY

Posts in the same category may sometimes (depending on the
overall site design) have a lot of tags in common. Thus the
`article.related_posts` holds only the posts that are tightly
(perhaps too tightly) related to the original post, and no
posts from other categories, since those, with only one or two
tags in common, can't as effectively compete.
Kernc 10 years ago
parent
commit
ab63994cf9
2 changed files with 20 additions and 7 deletions
  1. 10 3
      related_posts/Readme.rst
  2. 10 4
      related_posts/related_posts.py

+ 10 - 3
related_posts/Readme.rst

@@ -20,8 +20,15 @@ For example::
 
 
 
 
 Your related posts should share a common tag. You can also use ``related_posts:`` in your post's meta data.
 Your related posts should share a common tag. You can also use ``related_posts:`` in your post's meta data.
-The 'related_posts:' meta data works together with your existing slugs:
+The 'related_posts:' meta data works together with your existing slugs::
 
 
-    related_posts: slug1,slug2,slug3...slugN 
+    related_posts: slug1, slug2, slug3, ... slugN
 
 
-N represents the RELATED_POSTS_MAX
+``N`` represents the ``RELATED_POSTS_MAX``.
+
+Additionally, you can specify::
+
+    RELATED_POSTS_SKIP_SAME_CATEGORY = True
+
+in your settings file. With this setting, ``article.related_posts`` will
+contain only related posts from categories other than the original article's.

+ 10 - 4
related_posts/related_posts.py

@@ -7,12 +7,15 @@ Adds related_posts variable to article's context
 
 
 from pelican import signals
 from pelican import signals
 from collections import Counter
 from collections import Counter
+from itertools import chain
 
 
 
 
 def add_related_posts(generator):
 def add_related_posts(generator):
     # get the max number of entries from settings
     # get the max number of entries from settings
     # or fall back to default (5)
     # or fall back to default (5)
     numentries = generator.settings.get('RELATED_POSTS_MAX', 5)
     numentries = generator.settings.get('RELATED_POSTS_MAX', 5)
+    # Skip all posts in the same category as the article
+    skipcategory = generator.settings.get('RELATED_POSTS_SKIP_SAME_CATEGORY', False)
     for article in generator.articles:
     for article in generator.articles:
         # set priority in case of forced related posts
         # set priority in case of forced related posts
         if hasattr(article,'related_posts'):
         if hasattr(article,'related_posts'):
@@ -22,6 +25,7 @@ def add_related_posts(generator):
             # get related articles
             # get related articles
             for slug in related_posts:
             for slug in related_posts:
                 i = 0
                 i = 0
+                slug = slug.strip()
                 for a in generator.articles:
                 for a in generator.articles:
                     if i >= numentries: # break in case there are max related psots
                     if i >= numentries: # break in case there are max related psots
                         break
                         break
@@ -36,12 +40,14 @@ def add_related_posts(generator):
                 continue
                 continue
 
 
             # score = number of common tags
             # score = number of common tags
-            scores = Counter()
-            for tag in article.tags:
-                scores += Counter(generator.tags[tag])
+            related = chain(*(generator.tags[tag] for tag in article.tags))
+            if skipcategory:
+                related = (other for other in related
+                                 if other.category != article.category)
+            scores = Counter(related)
 
 
             # remove itself
             # remove itself
-            scores.pop(article)
+            scores.pop(article, None)
 
 
             article.related_posts = [other for other, count 
             article.related_posts = [other for other, count 
                 in scores.most_common(numentries)]
                 in scores.most_common(numentries)]