Changeset 2538

Show
Ignore:
Timestamp:
02/24/10 10:00:22 (5 months ago)
Author:
JensDiemer
Message:
  • New: Blog plugin can send feeds
  • New: Blog tag filter can be combinied
  • Update Journal feeds used the "count" GET parameter
Location:
branches/0.9/pylucid_project
Files:
5 added
8 modified

Legend:

Unmodified
Added
Removed
  • branches/0.9/pylucid_project/pylucid_plugins/blog/preference_forms.py

    r2523 r2538  
    2424        ), 
    2525    ) 
     26     
     27    initial_feed_count = forms.IntegerField( 
     28        initial=5, min_value=1, 
     29        help_text=_("Default numbers of blog articles in RSS/Atom feed."), 
     30    ) 
     31    max_feed_count = forms.IntegerField( 
     32        initial=30, min_value=1, 
     33        help_text=_("The maximal numbers of blog articles in RSS/Atom feed."), 
     34    ) 
    2635    class Meta: 
    2736        app_label = 'blog' 
  • branches/0.9/pylucid_project/pylucid_plugins/blog/templates/blog/detail_view.html

    r2443 r2538  
    2121    <div class="content">{{ entry.get_html }}</div> 
    2222     
     23    {% if entry.lastupdateby %} 
    2324    <small><p class="date_info"> 
    24         {% if entry.lastupdateby %}(Last update: {{ entry.lastupdatetime|date:_("DATETIME_FORMAT") }} by {{ entry.lastupdateby }}.){% endif %} 
     25        (Last update: {{ entry.lastupdatetime|date:_("DATETIME_FORMAT") }} by {{ entry.lastupdateby }}.) 
    2526    </p></small> 
     27    {% endif %} 
    2628     
    2729    {% include "blog/includes/taglist.html" %} 
  • branches/0.9/pylucid_project/pylucid_plugins/blog/templates/blog/includes/tagcloud.html

    r2113 r2538  
    22{% for tag in tag_cloud %} 
    33    {% if not forloop.first %}|{% endif %} 
    4     <a href="{% url Blog-tag_view tag=tag.name %}" style="font-size:{{ tag.font_size }}em;">{{ tag.name }}</a> 
     4     
     5    {% if tag.name in used_tags %} 
     6        <strong style="font-size:{{ tag.font_size }}em;">{{ tag.name }}</strong> 
     7    {% else %} 
     8        <a href="{% url Blog-tag_view tags=tag.name %}" style="font-size:{{ tag.font_size }}em;">{{ tag.name }}</a> 
     9    {% endif %} 
     10     
     11    {% if add_tag_filter_link %} 
     12        {% include "blog/includes/add_tag_filter.html" %} 
     13    {% endif %} 
    514{% endfor %} 
    615</fieldset> 
  • branches/0.9/pylucid_project/pylucid_plugins/blog/templates/blog/includes/taglist.html

    r2250 r2538  
    55{% for tag in tags %} 
    66    {% if not forloop.first %}|{% endif %} 
    7     <a href="{% url Blog-tag_view tag=tag.name %}">{{ tag.name }}</a> 
     7    {% if tag.name in used_tags %} 
     8        <strong>{{ tag.name }}</strong> 
     9    {% else %} 
     10        <a href="{% url Blog-tag_view tags=tag.name %}">{{ tag.name }}</a> 
     11    {% endif %} 
     12    {% if add_tag_filter_link %} 
     13        {% include "blog/includes/add_tag_filter.html" %} 
     14    {% endif %} 
    815{% endfor %} 
    916</fieldset> 
  • branches/0.9/pylucid_project/pylucid_plugins/blog/templates/blog/summary.html

    r2523 r2538  
    2222    <div class="content">{{ entry.get_html }}</div> 
    2323 
     24    {% if entry.lastupdateby %} 
    2425    <small><p class="date_info"> 
    25         {% if entry.lastupdateby %}(Last update: {{ entry.lastupdatetime|date:_("DATETIME_FORMAT") }} by {{ entry.lastupdateby }}.){% endif %} 
     26        (Last update: {{ entry.lastupdatetime|date:_("DATETIME_FORMAT") }} by {{ entry.lastupdateby }}.) 
    2627    </p></small> 
     28    {% endif %} 
    2729 
    2830   {% include "blog/includes/taglist.html" %} 
     
    3436{% endfor %} 
    3537</div> 
     38 
     39<fieldset class="feed_selection"><legend>{% trans "Syndication feed format:" %}</legend> 
     40<ul> 
     41{% for feed in feeds %} 
     42    <li> 
     43        {% if tags %} 
     44            <a href="{% url Blog-tag_feed tags feed.filename %}">{% url Blog-tag_feed tags feed.filename %}</a> 
     45        {% else %}       
     46            <a href="{% url Blog-feed feed.filename %}">{% url Blog-feed feed.filename %}</a> 
     47        {% endif %} 
     48        <small>( 
     49        {% if feed.filename == "feed.rss" %} 
     50            <a href="{% trans "http://en.wikipedia.org/wiki/RSS" %}">Really Simple Syndication</a> v2.01rev2 
     51        {% endif %} 
     52        {% if feed.filename == "feed.atom" %}    
     53            <a href="{% trans "http://en.wikipedia.org/wiki/Atom_(standard)" %}">Atom Syndication Format</a> v1.0 
     54        {% endif %} 
     55        ) 
     56        </small> 
     57    </li>     
     58{% endfor %} 
     59</lu> 
     60</fieldset> 
    3661 
    3762<div class="pagination"> 
  • branches/0.9/pylucid_project/pylucid_plugins/blog/urls.py

    r2417 r2538  
    33from django.conf.urls.defaults import patterns, url 
    44 
    5 from blog.views import summary, tag_view, detail_view 
     5from blog.views import summary, tag_view, detail_view, feed, select_feed 
    66 
    77urlpatterns = patterns('', 
    8     url(r'^/tags/(?P<tag>.*?)/$', tag_view, name='Blog-tag_view'), 
     8    url(r'^/tags/(?P<tags>.+?)/$', tag_view, name='Blog-tag_view'), 
    99    url(r'^/(?P<id>\d+?)/(?P<title>.*)/$', detail_view, name='Blog-detail_view'), 
     10 
     11    url(r'^/feed/(?P<tags>.+)/(?P<filename>.+?)$', feed, name='Blog-tag_feed'), 
     12    url(r'^/feed/(?P<filename>.+?)$', feed, name='Blog-feed'), 
     13    url(r'^/feed/', select_feed, name='Blog-select_feed'), 
     14 
    1015    url(r'^', summary, name='Blog-summary'), 
    1116) 
  • branches/0.9/pylucid_project/pylucid_plugins/blog/views.py

    r2527 r2538  
    2727 
    2828from django.conf import settings 
     29from django.contrib.syndication.views import Feed 
    2930from django.utils.translation import ugettext as _ 
    3031from django.views.decorators.csrf import csrf_protect 
    3132from django.contrib.comments.views.comments import post_comment 
     33from django.utils.feedgenerator import Rss201rev2Feed, Atom1Feed 
    3234 
    3335from pylucid_project.apps.pylucid.decorators import render_to 
     36from pylucid_project.utils.safe_obtain import safe_pref_get_integer 
    3437 
    3538from pylucid_project.pylucid_plugins.blog.models import BlogEntry 
     39from pylucid_project.pylucid_plugins.blog.preference_forms import BlogPrefForm 
    3640 
    3741# from django-tagging 
     
    4852 
    4953 
     54def _get_queryset(request, tags=None): 
     55    # Get all blog entries, that the current user can see 
     56    queryset = BlogEntry.objects.all_accessible(request) 
     57 
     58    if tags is not None: 
     59        # filter by tags  
     60        queryset = TaggedItem.objects.get_by_model(queryset, tags) 
     61 
     62    return queryset 
     63 
     64 
     65def _split_tags(raw_tags): 
     66    "simple split tags from url" 
     67    tags = raw_tags.strip("/").split("/") 
     68    return tags 
     69 
     70 
     71class RssFeed(Feed): 
     72    feed_type = Rss201rev2Feed 
     73    filename = "feed.rss" 
     74    title = _("Blog - RSS feed") 
     75    link = "/" 
     76    description_template = "blog/feed_description.html" 
     77 
     78    def __init__(self, request, tags=None): 
     79        self.request = request 
     80 
     81        if tags is not None: 
     82            tags = _split_tags(tags) 
     83        self.tags = tags 
     84 
     85        # Get max number of feed entries from request.GET["count"] 
     86        # Validate/Limit it with information from DBPreferences  
     87        self.count, error = safe_pref_get_integer( 
     88            request, "count", BlogPrefForm, 
     89            default_key="initial_feed_count", default_fallback=5, 
     90            min_key="initial_feed_count", min_fallback=5, 
     91            max_key="max_feed_count", max_fallback=30 
     92        ) 
     93 
     94    def description(self): 
     95        if self.tags is None: 
     96            return _("Last %s blog articles") % self.count 
     97        else: 
     98            return _( 
     99                 "Last %(count)s blog articles tagged with: %(tags)s" 
     100            ) % {"count":self.count, "tags": ",".join(self.tags)} 
     101 
     102    def items(self): 
     103        queryset = _get_queryset(self.request, self.tags) 
     104        return queryset[:self.count] 
     105 
     106    def item_title(self, item): 
     107        return item.headline 
     108 
     109    def item_author_name(self, item): 
     110        return item.createby 
     111 
     112    def item_link(self, item): 
     113        return item.get_absolute_url() 
     114 
     115 
     116class AtomFeed(RssFeed): 
     117    """ 
     118    http://docs.djangoproject.com/en/dev/ref/contrib/syndication/#publishing-atom-and-rss-feeds-in-tandem 
     119    """ 
     120    feed_type = Atom1Feed 
     121    filename = "feed.atom" 
     122    title = _("Blog - Atom feed") 
     123    subtitle = RssFeed.description 
     124 
     125 
     126# The last class is the fallback class, if filename doesn't match 
     127FEEDS = [AtomFeed, RssFeed] 
     128 
     129 
     130 
    50131@render_to("blog/summary.html") 
    51132def summary(request): 
     
    54135    """ 
    55136    # Get all blog entries, that the current user can see 
    56     queryset = BlogEntry.objects.all_accessible(request) 
     137    queryset = _get_queryset(request) 
    57138 
    58139    # Limit the queryset with django Paginator 
     
    65146        "tag_cloud": tag_cloud, 
    66147        "CSS_PLUGIN_CLASS_NAME": settings.PYLUCID.CSS_PLUGIN_CLASS_NAME, 
     148        "feeds": FEEDS, 
    67149    } 
    68150    return context 
     
    70152 
    71153@render_to("blog/summary.html") 
    72 def tag_view(request, tag): 
    73     """ 
    74     Display summary list with blog entries filtered by the giben tag. 
    75     """ 
    76     tags = tag.strip("/").split("/") 
    77  
    78     # Get all blog entries, that the current user can see 
    79     queryset = BlogEntry.objects.all_accessible(request) 
    80  
    81     queryset = TaggedItem.objects.get_by_model(queryset, tags) 
     154def tag_view(request, tags): 
     155    """ 
     156    Display summary list with blog entries filtered by the given tags. 
     157    """ 
     158    tags = _split_tags(tags) 
     159 
     160    # Get all blog entries, that the current user can see 
     161    queryset = _get_queryset(request, tags) 
    82162 
    83163    # Limit the queryset with django Paginator 
     
    85165 
    86166    # Add link to the breadcrumbs ;) 
    87     _add_breadcrumb(request, title=_("All '%s' tagged items" % ",".join(tags)), url=request.path) 
     167    _add_breadcrumb(request, title=_("All items tagged with: %s" % ", ".join(tags)), url=request.path) 
    88168 
    89169    tag_cloud = BlogEntry.objects.get_tag_cloud(request) 
     
    92172        "entries": paginator, 
    93173        "tag_cloud": tag_cloud, 
     174        "add_tag_filter_link": True, # Add + tag filter link 
    94175        "CSS_PLUGIN_CLASS_NAME": settings.PYLUCID.CSS_PLUGIN_CLASS_NAME, 
     176        "used_tags": tags, 
     177        "tags": "/".join(tags), 
     178        "feeds": FEEDS, 
    95179    } 
    96180    return context 
     
    104188    """ 
    105189    # Get all blog entries, that the current user can see 
    106     queryset = BlogEntry.objects.all_accessible(request) 
     190    queryset = _get_queryset(request) 
    107191 
    108192    try: 
     
    133217    return context 
    134218 
     219#------------------------------------------------------------------------------ 
     220 
     221 
     222@render_to("blog/select_feed.html") 
     223def select_feed(request): 
     224    """ Display a list with existing feed filenames. """ 
     225    context = {"feeds": FEEDS} 
     226    return context 
     227 
     228 
     229def feed(request, filename, tags=None): 
     230    """ 
     231    return RSS/Atom feed for all blog entries and filtered by tags.  
     232    Feed format is selected by filename. 
     233    """ 
     234    for feed_class in FEEDS: 
     235        if filename == feed_class.filename: 
     236            break 
     237 
     238    feed = feed_class(request, tags) 
     239    response = feed(request) 
     240    return response 
     241 
  • branches/0.9/pylucid_project/pylucid_plugins/update_journal/views.py

    r2536 r2538  
    2727from django.core.urlresolvers import NoReverseMatch 
    2828 
    29 from pylucid_project.apps.pylucid.models import Language 
    3029from pylucid_project.apps.pylucid.decorators import render_to 
     30from pylucid_project.utils.safe_obtain import safe_pref_get_integer 
     31from pylucid_project.apps.pylucid.models import Language, PluginPage 
    3132 
    3233from pylucid_project.pylucid_plugins.update_journal.models import UpdateJournal 
    33 from pylucid_project.apps.pylucid.models import PluginPage 
     34from pylucid_project.pylucid_plugins.update_journal.preference_forms import UpdateJournalPrefForm 
     35 
    3436 
    3537def _get_queryset(request, count): 
     
    7678    filename = "feed.rss" 
    7779 
    78     title = "Update Journal" 
     80    title = _("Update Journal - RSS feed") 
    7981    link = "/" 
    80     description = "Updates and changes" 
    8182    description_template = "update_journal/feed_description.html" 
    8283 
    8384    def __init__(self, request): 
    84         self.count = 10 # FIXME: use GET parameter? 
    8585        self.request = request 
     86 
     87        # Get max number of feed entries from request.GET["count"] 
     88        # Validate/Limit it with information from DBPreferences  
     89        self.count, error = safe_pref_get_integer( 
     90            request, "count", UpdateJournalPrefForm, 
     91            default_key="initial_feed_count", default_fallback=5, 
     92            min_key="initial_feed_count", min_fallback=5, 
     93            max_key="max_feed_count", max_fallback=30 
     94        ) 
     95 
     96    def description(self): 
     97        return _("Last %s updates and changes") % self.count 
    8698 
    8799    def items(self): 
     
    101113    feed_type = Atom1Feed 
    102114    filename = "feed.atom" 
     115    title = _("Update Journal - Atom feed") 
    103116    subtitle = RssFeed.description 
    104117