| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | """ |
|---|
| 3 | zine.widgets |
|---|
| 4 | ~~~~~~~~~~~~ |
|---|
| 5 | |
|---|
| 6 | This module provides the core widgets and functionality to build your |
|---|
| 7 | own. Widgets are, in the context of Zine, classes that have a |
|---|
| 8 | unicode conversion function that renders a template into a string but |
|---|
| 9 | have all their attributes attached to themselves. This gives template |
|---|
| 10 | designers the ability to change the general widget template but also |
|---|
| 11 | render one widget differently. |
|---|
| 12 | |
|---|
| 13 | Additionally widgets could be moved around from the admin panel in the |
|---|
| 14 | future. |
|---|
| 15 | |
|---|
| 16 | :copyright: (c) 2010 by the Zine Team, see AUTHORS for more details. |
|---|
| 17 | :license: BSD, see LICENSE for more details. |
|---|
| 18 | """ |
|---|
| 19 | from zine.application import render_template |
|---|
| 20 | from zine.models import Post, SummarizedPost, Category, Tag, Comment |
|---|
| 21 | |
|---|
| 22 | |
|---|
| 23 | class Widget(object): |
|---|
| 24 | """Baseclass for all the widgets out there!""" |
|---|
| 25 | |
|---|
| 26 | #: the name of the widget when called from a template. This is also used |
|---|
| 27 | #: if widgets are configured from the admin panel to have a unique |
|---|
| 28 | #: identifier. |
|---|
| 29 | name = None |
|---|
| 30 | |
|---|
| 31 | #: name of the template for this widget. Please prefix those template |
|---|
| 32 | #: names with an underscore to mark it as partial. The widget is available |
|---|
| 33 | #: in the template as `widget`. |
|---|
| 34 | template = None |
|---|
| 35 | |
|---|
| 36 | def __unicode__(self): |
|---|
| 37 | """Render the template.""" |
|---|
| 38 | return render_template(self.template, widget=self) |
|---|
| 39 | |
|---|
| 40 | def __str__(self): |
|---|
| 41 | return unicode(self).encode('utf-8') |
|---|
| 42 | |
|---|
| 43 | |
|---|
| 44 | class PostArchiveSummary(Widget): |
|---|
| 45 | """Show the last n months/years/days with posts.""" |
|---|
| 46 | |
|---|
| 47 | name = 'post_archive_summary' |
|---|
| 48 | template = 'widgets/post_archive_summary.html' |
|---|
| 49 | |
|---|
| 50 | def __init__(self, detail='months', limit=6, show_title=False): |
|---|
| 51 | self.__dict__.update(SummarizedPost.query |
|---|
| 52 | .get_archive_summary(detail, limit)) |
|---|
| 53 | self.show_title = show_title |
|---|
| 54 | |
|---|
| 55 | |
|---|
| 56 | class LatestPosts(Widget): |
|---|
| 57 | """Show the latest n posts.""" |
|---|
| 58 | |
|---|
| 59 | name = 'latest_posts' |
|---|
| 60 | template = 'widgets/latest_posts.html' |
|---|
| 61 | |
|---|
| 62 | def __init__(self, limit=5, show_title=False, content_types=None): |
|---|
| 63 | if content_types is None: |
|---|
| 64 | query = SummarizedPost.query.for_index() |
|---|
| 65 | else: |
|---|
| 66 | query = SummarizedPost.query.filter(SummarizedPost |
|---|
| 67 | .content_type.in_(content_types)) |
|---|
| 68 | self.posts = query.latest().limit(limit).all() |
|---|
| 69 | self.show_title = show_title |
|---|
| 70 | |
|---|
| 71 | |
|---|
| 72 | class LatestComments(Widget): |
|---|
| 73 | """Show the latest n comments.""" |
|---|
| 74 | |
|---|
| 75 | name = 'latest_comments' |
|---|
| 76 | template = 'widgets/latest_comments.html' |
|---|
| 77 | |
|---|
| 78 | def __init__(self, limit=5, show_title=False, ignore_blocked=False): |
|---|
| 79 | self.comments = Comment.query. \ |
|---|
| 80 | latest(ignore_blocked=ignore_blocked).limit(limit).all() |
|---|
| 81 | self.show_title = show_title |
|---|
| 82 | |
|---|
| 83 | |
|---|
| 84 | class TagCloud(Widget): |
|---|
| 85 | """Show a tagcloud.""" |
|---|
| 86 | |
|---|
| 87 | name = 'tag_cloud' |
|---|
| 88 | template = 'widgets/tag_cloud.html' |
|---|
| 89 | |
|---|
| 90 | def __init__(self, max=None, show_title=False): |
|---|
| 91 | self.tags = Tag.query.get_cloud(max) |
|---|
| 92 | self.show_title = show_title |
|---|
| 93 | |
|---|
| 94 | |
|---|
| 95 | class CategoryList(Widget): |
|---|
| 96 | """Show a list of all categories.""" |
|---|
| 97 | |
|---|
| 98 | name = 'category_list' |
|---|
| 99 | template = 'widgets/category_list.html' |
|---|
| 100 | |
|---|
| 101 | def __init__(self, show_title=False): |
|---|
| 102 | self.categories = Category.query.all() |
|---|
| 103 | self.show_title = show_title |
|---|
| 104 | |
|---|
| 105 | |
|---|
| 106 | class IncludePage(Widget): |
|---|
| 107 | """Includes a page.""" |
|---|
| 108 | |
|---|
| 109 | name = 'include_page' |
|---|
| 110 | template = 'widgets/include_page.html' |
|---|
| 111 | |
|---|
| 112 | def __init__(self, page_name, show_title=False): |
|---|
| 113 | self.page_name = page_name |
|---|
| 114 | self.page = Post.query.type('page').filter_by(slug=page_name).first() |
|---|
| 115 | |
|---|
| 116 | @property |
|---|
| 117 | def exists(self): |
|---|
| 118 | return self.page is not None |
|---|
| 119 | |
|---|
| 120 | |
|---|
| 121 | class PagesNavigation(Widget): |
|---|
| 122 | """Show a list of all pages.""" |
|---|
| 123 | |
|---|
| 124 | name = 'pages_navigation' |
|---|
| 125 | template = 'widgets/pages_navigation.html' |
|---|
| 126 | |
|---|
| 127 | def __init__(self, show_title=False, show_drafts=False): |
|---|
| 128 | self.pages = Post.query.type('page').published().all() |
|---|
| 129 | if show_drafts: |
|---|
| 130 | self.pages += Post.query.type('page').drafts().all() |
|---|
| 131 | self.show_title = show_title |
|---|
| 132 | |
|---|
| 133 | #: list of all core widgets |
|---|
| 134 | all_widgets = [PostArchiveSummary, LatestPosts, LatestComments, TagCloud, |
|---|
| 135 | CategoryList, IncludePage, PagesNavigation] |
|---|