Bambu Blog

A simple set of models for a basic blog, with some tools for custom-designed blog post writing

About Bambu Blog

Bambu Blog was originally intended as a simple blogging tool for web apps, that allowed developers to quickly setup a blog for their app based on a common Bootstrap template, without needing to manage another site and set of user accounts. It used Markdown to render text-only copy, and Bambu Attachments to handle uploading images and other media.

It’s grown a little since then, and now supports either the MarkItUp or TinyMCE editors (just install the Django app you want and Bambu Blog will detect it and apply the appropriate class names to the main body textbox).

Installation

Install the package via Pip:

pip install bambu-blog

Add it to your INSTALLED_APPS list:

INSTALLED_APPS = (
    ...
    'bambu_blog'
)

Add bambu_blog.urls to your URLconf:

urlpatterns = patterns('',
    ...
    url(r'^blog/', include('bambu_blog.urls')),
)

Sync the database

Run manage.py syncdb or manage.py migrate to setup the database tables.

Basic usage

The blog uses a number of templates. All of the important ones extend blog/base.html, so you should start by overriding that template to set it up how you like it. The naming convention used throughout the Bambu collection of apps designates the main content area via the Jinja block form_content. A block is already defined called sidebar, so you can either place HTML in there or override blog/sidebar.inc.html.

Add a blog post via the admin area of your site. As you’re logged in as a staff member you don’t have to publish the blog post to be able to see it on the site once saved. View the blog post index at /blog/.

Override the blog/post.html template to tweak the display of the blog post.

Questions or suggestions?

Find me on Twitter (@iamsteadman) or visit my blog.

Views and templates

Bambu Blog provides a number of views and templates

Blog index (/blog/)

The 10 latest blog posts. When the page querystring argument is set to 2, the 10 published posts before that are shown, and so on (this pagination is used throughout all of the list views).

Template:
  • blog/posts.html

Blog posts by year (/blog/2014/)

The 10 latest blog posts of the given year.

Templates:
  • blog/posts-year.html
  • blog/posts.html

Blog posts by month (/blog/2014/04/)

The 10 latest blog posts of the given year and month.

Templates:
  • blog/posts-month.html
  • blog/posts-year.html
  • blog/posts.html

Blog posts by day (/blog/2014/04/26/)

The 10 latest blog posts of the given year, month and day.

Templates:
  • blog/posts-day.html
  • blog/posts-month.html
  • blog/posts-year.html
  • blog/posts.html

Blog post (/blog/2014/04/26/slug/)

A single blog post, matching a year, month, day and slug.

Template:
  • blog/post.html

Submit blog post comment (/blog/2014/04/26/slug/comment/)

A POST-only view that validates then submits a form that allows comments to be posted to a blog entry. The comment model must have a boolean spam field and a check_for_spam() method that takes the HTTP request as its only argument. This method should return True or False.

If the form is valid and submission is successful, an HttpResponseRedirect is returned that redirects the user back to the blog post page, with a message (via django.contrib.messages).

Template (if submission was unsuccessful):
  • blog/post.html

Blog posts by tag (/blog/tag/tag-slug/)

The 10 latest blog posts tagged tag-slug

Templates:
  • blog/posts-tag.html
  • blog/posts.html

Blog posts by category (/blog/category/category-slug/)

The 10 latest blog posts in the category category-slug

Templates:
  • blog/posts-category.html
  • blog/posts.html

Blog posts by tag (/blog/author/username/)

The 10 latest blog posts by the user with the username username.

Templates:
  • blog/posts-author.html
  • blog/posts.html

Feeds

Of course Bambu Blog exposes RSS feeds. It uses similar URL patterns to those found in well-configured WordPress sites, with lots of URLs suffixed with /feed/ (for example, the blog index, category views, author views, etc).

Blog index (/blog/feed/)

The 10 latest blog posts. When the page querystring argument is set to 2, the 10 published posts before that are shown, and so on (this pagination is used throughout all of the feeds).

Blog posts by year (/blog/2014/feed/)

The 10 latest blog posts of the given year (mainly provided to conform to WordPress’ URL conventions).

Blog posts by month (/blog/2014/04/feed/)

The 10 latest blog posts of the given year and month (mainly provided to conform to WordPress’ URL conventions).

Blog posts by day (/blog/2014/04/26/feed/)

The 10 latest blog posts of the given year, month and day (mainly provided to conform to WordPress’ URL conventions).

Blog posts by tag (/blog/tag/tag-slug/feed/)

The 10 latest blog posts tagged tag-slug

Blog posts by category (/blog/category/category-slug/feed/)

The 10 latest blog posts in the category category-slug

Blog posts by tag (/blog/author/username/feed/)

The 10 latest blog posts by the user with the username username.

Context processor

Bambu Blog has a context processor that will provide a queryset of all the published blog posts. By design it’s supplied as a callable rather than an evaluated query to avoid it being run unnecessarily, and you should limit the number of returned posts via the range template tag.

Installation

Add the following to your list of processors:

bambu_blog.context_processors.latest

Usage

Loop through the latest blog posts in your template like this:

<ul class="latest-blog-posts">
        {% for post in latest_blog_posts|slice:':3' %}
                <li class="post">
                        <a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
                </li>
        {% endfor %}
</ul>

Cron job and webhook

If you use Bambu Cron you can install this cron job (just like any other supported by Bambu Cron) to publish blog posts that are marked with dates in the future. This fires a webhook which you can manage by setting up Bambu Webhooks to do just about anything you want with it.

In the past this was used to auto-tweet the blog posts, but now I use Bambu Buffer which has its own cron job that figures out what to do with published and unpublished blog posts.

Installation

Once you’ve installed Bambu Blog, make sure to run manage.py cron --setup so that Bambu Cron can pick up the Blog cron job.

Settings

BLOG_COMMENTS_FORM
The class of the form used to post comments on a blog entry, expressed as a string (default is ‘bambu_comments.forms.CommentForm’)
BLOG_COMMENTS_MODEL
The model used to store and query comments against blog posts. Use the notation supported by django.db.models.loading.get_model (default is comments.Comment)
BLOG_EXCERPT_LENGTH
The number of words in a blog excerpt before it’ll be truncated (default is 30)
BLOG_POSTS_PER_PAGE
The number of blog posts to display on a page or in a feed (default is 10)
BLOG_THUMBNAIL_WIDTH
The number of pixels wide a featured blog post image should be (default is 640)
BLOG_XMLRPC_STAFF_ONLY
Set to True to only allow staff users to access the XML-RPC endpoint

Haystack

If you use Haystack, you’ll find a search index already setup for blog posts, that includes only posts dated in the past that are marked as published. The index contains the title, author, body, categories and tags for each post.

Models

Managers

XML-RPC

Although not bulletproof, there is some XML-RPC support built in to Bambu Blog. The server is supplied by Bambu XML-RPC.

It exposes endpoints that support the metaWeblog and Blogger XML-RPC interfaces.

Sitemaps

Bambu Blog contains a simple Sitemap class that returns all of the published blog posts. Its frequency setting is set to ‘daily’ and all items are marked with 0.5 priority.

Indices and tables