Skip to content

The 80% solution to bootstrapping a new Django site: models, views, templates for basic publishing

License

Notifications You must be signed in to change notification settings

veselosky/django-commoncontent

Repository files navigation

Common Content: A reusable content app for Django

Common Content provides models, views, and templates for common web content in a reusable Django app, giving you a blog-like web site out of the box.

Django ships with flatpages, the most simplistic content model possible. Third party tools like Wagtail or DjangoCMS provide flexible and complex content management workflows, but require a lot of custom code. Common Content is designed to fill the gap between these options. If you need pages and feeds for your Django site, but don't need (or want) the power and complexity of a full content management system, Common Content may be the right tool.

Common Content includes a set of templates using the Bootstrap CSS framework based on the examples found on the bootstrap website. The templates work with any objects that implement the common data model. They can easily be coupled with Django's generic class-based views to produce a clean and professional site quickly and easily. If you use the included concrete models with the default templates and the included views, you'll be starting with a basic blog-style site.

Project Status: Alpha

Common Content is still Alpha-level software. It has many completed features that are usable in production. However, test coverage is not yet complete, the feature set is still growing, and there are likely to be breaking changes before the software reaches a stable 1.0 release. Be aware that migrating to newer versions may require some work.

Included Content Models, Views, and Templates

Common Content defines a data model based on Schema.org, extended in some places using fields from the open graph protocol, or other web standards. It provides concrete Django models for common web objects, as well as an abstract CreativeWork and BasePage model for extending the available page types.

Common Content provides the following Content:

  • HomePage - A dedicated model for site home pages. Sites can have multiple HomePages with different publication dates, allowing for scheduled updates.
  • Generic Page - A model for evergreen pages like "About".
  • Article - Like a Post in Wordpress, the Article is the main content type of the site. Articles can also be linked together in a Series.
  • Section - Articles are contained in sections. A section is like a category.
  • RSS Feeds - Common Content provides a site RSS Feed of published articles, and a separate RSS feed for each Section.
  • Sitemaps - Common Content also provides Sitemaps for use with Django's sitemap framework.
  • Image - An Image model is provided to house image uploads and their metadata, including copyright information. Resized renditions of each image are provided by django-imagekit (see the section below on Images).
  • Attachment - A model for storing non-image file uploads and their metadata.
  • Author - A model to encapsulate author information, including default copyright information. Authors are optional. Author pages show a profile and list of authored Articles. Each Author also has an RSS Feed.

Common Content provides views and templates (using Bootstrap 5) for each type, along with a few different options for list display. The templates include Open Graph metadata and Schema.org metadata for social sharing and SEO. The templates load the Bootstrap CSS and JavaScript from a CDN by default, so there's nothing else to install and little or no front-end to deal with (but you can override this in your own templates, see the bootstrap_styles block below).

In addition to the content pages, Common Content also provides:

  • Menu and Link - These models define a list of links that can be used to implement site navigation menus, footer links, etc.
  • Redirects - Includes the Django redirects app, with a custom middleware to support temporary redirects.
  • AbstractCreativeWork and BasePage - These are abstract Django models that you can subclass to create new content types that are compatible with Common Content templates and tools.
  • Admin Support - Common Content provides admin pages for its models, and documentation for use by the admindocs app.
  • django-sitevars - Site variables store bits of information that are reused across the site. Things like the default copyright notice, site tagline, analytics IDs, etc. can be stored in SiteVars. All variables for a site are injected into every template context using the SiteVars Context Processor so they are available on every page, even pages not provided by Common Content.
  • django-tinymce Support - If django-tinymce is installed, Common Content will use its WYSISYG editor in its admin pages. There is an optional JSON view that exposes a list of recently upload images for use by the TinyMCE editor.

Development

This project uses uv from Astral for managing development. Install uv before working with this repo.

After checking out the code, you can bootstrap a development environment by running:

uv sync
uv run ./manage.py migrate

Installation

Add the following to your settings.py:

import commoncontent.apps
INSTALLED_APPS = [
  *commoncontent.apps.CONTENT,
  # Optionally use tinymce in the admin
  "tinymce",
  # Other Django apps here
  "django.contrib.redirects",  # Required
  "django.contrib.sites",  # Required
  # sitevars must come AFTER contrib.sites for admin to work
  "sitevars",
]

# Ensure your middleware includes the following:
MIDDLEWARE += [
  "django.contrib.sites.middleware.CurrentSiteMiddleware",
  "commoncontent.redirects.TemporaryRedirectFallbackMiddleware",
]

# If using tinymce
TINYMCE_DEFAULT_CONFIG = commoncontent.apps.TINYMCE_CONFIG

# Add `commoncontent.apps.context_defaults` to your context processors. You will also
# need to add the request, auth, and messages context processors if not already there.
# The inject_sitevars processor should come after context_defaults so you can override
# the default values using sitevars.
# Probably looks like this:

TEMPLATES = [
  { "BACKEND": "django.template.backends.django.DjangoTemplates",
    "DIRS": [],
    "APP_DIRS": True,
    "OPTIONS": {
      "context_processors": [
        "django.template.context_processors.debug",
        "django.template.context_processors.request",
        "django.contrib.auth.context_processors.auth",
        "django.contrib.messages.context_processors.messages",
        "commoncontent.apps.context_defaults",
        "sitevars.context_processors.inject_sitevars",
      ],
    },
  },
]

In your project's urls.py, insert the Common Content URLs where you want them. To have Common Content manage your home page and top-level pages, make it the LAST url pattern, and list it like this:

from commoncontent import views as generic

urlpatterns = [
  # Common Content provides templates for auth pages
  path("accounts/", include("django.contrib.auth.urls")),
  # You need to add the admin yourself. Remember to add the docs!
  path('admin/doc/', include('django.contrib.admindocs.urls')),
  path("admin/", admin.site.urls),
  # TinyMCE urls if desired
  path("tinymce/", include("tinymce.urls")),
  # All other urls are handed to Common Content
  path("", include("commoncontent.urls")),
]

Usage

The following documentation should help you use Common Content.

The base template

The Common Content base template is divided into major blocks that can be replaced in your child templates. The blocks, in order of appearance, are:

  • title: The content of the HTML page title tag.
  • bootstrap_styles: An HTML block that by default pulls in the bootstrap stylesheet. You can override it to customize your version of bootstrap (e.g. with BootSwatch) or include {{ block.super }} and then add some tweaks.
  • opengraph: Used to expose the page's open graph metadata in the HTML head. This is done in the default template. You won't need to override this unless you define custom open graph types that need special handling.
  • schema: Holds the schema.org metadata.
  • extra_head: Override this if you need to include custom CSS, web fonts, etc. in the page's HTML head.
  • body_class: A block you can override to apply a custom class to the HTML body element, if needed by your custom CSS.
  • header: A block to contain your site's masthead and main navigation, the header elements common to every page. Override in your site's base template.
  • precontent: A block that appears before the main content of the page. Override this on home pages or section pages where you need to insert some feature above the standard content, such as a call to action, introduction to the topic, featured stories, etc.
  • content: The main content body of the page. By default, will include the content sub-template specified in the template context. For an Article this will be the article text, for a Section page this will be the list of Articles in the Section.
  • postcontent: A block that appears after the main content of the page. Often used to include "Read Next" or "Related" recirculation modules or a call to action.
  • footer: A block to contain your site's footer links and blanket copyright statements, elements common to every page. Override in your site's base template.
  • bootstrap_js: Loads the Bootstrap JS bundle. Override if needed.
  • extra_js: A block just before the closing body tag. Use this to include deferred JavaScript or other elements you want loaded after the main page content.

Block Templates

Common Content ships with several partial templates that can be included as the content of the base blocks to construct a page quickly from reusable modules. These can be loaded from the commoncontent/blocks/ template directory.

NOTE: Although the Common Content base template is an excellent starter, these block templates are very basic. This is an area for future expansion. For now, they are usable, but you probably will want to build your own.

The available block templates are:

  • article_list_album.html: Displays Articles' image, title, and description as an array of cards. Useful for Section pages and home pages.
  • article_list_blog.html: Displays Articles' title and excerpt in a news feed style, like an old-school blog home page.
  • article_text.html: Displays the title, featured image, and full text of an Article. Used on the Article detail page.
  • author_list_album.html: Displays a profile image and short bio for each author. Used on the Author list page.
  • author_profile.html: Displays the author profile photo and full bio. Used on the Author detail page.
  • empty.html: An empty template to leave a block empty.
  • footer_simple.html: A very simple footer.
  • header_simple.html: A very simple header.

Site Vars

We depend on django-sitevars for storing site-specific variables or chunks of content. You can also store any variable for use with your own templates. Variable can be injected into template contexts using the context processor in sitevars.context_processors.inject_sitevars, or using the {% sitevar "name" %} template tag. Variables used by the default templates/models are listed below. Defaults for these variables are injected in the template contexts by commoncontent.apps.context_defaults.

  • base_template - The base template to use for generic pages. Defaults to commoncontent/base.html.
  • brand - Site's brand name. Uses site.name if not set.
  • copyright_holder - Custom name for the copyright holder if using the default copyright notice. Falls back to site.name if not provided.
  • copyright_notice - Text to include in the copyright notice section of the footer (replaces the default copyright notice).
  • custom_stylesheet - A site-specific CSS file. This is pulled into the extra_head block after bootstrap and Common Content's CSS, so you can use it to override default styles and customize the look and feel of each site. It is included using {% static custom_stylesheet %} so the value should be relative to the STATIC_ROOT.
  • default_icon - Name of a Bootstrap icon to use by default if the object provides none.
  • detail_precontent_template - Default template to use for the precontent block for detail pages.
  • detail_content_template - Default template to use for the content block for detail pages.
  • detail_postcontent_template - Default template to use for the postcontent block for detail pages.
  • footer_template - Default template to use for the footer block.
  • header_template - Default template to use for the header block.
  • list_postcontent_template - Default template to use for the postcontent block for list pages.
  • list_precontent_template - Default template to use for the precontent block for list pages.
  • list_content_template - Default template to use for the content block for list pages.
  • paginate_by - Items per page on list pages, same as Django's ListView, see pagination in the Django docs.
  • paginate_orphans - Same as Django's ListView, see pagination in the Django docs.

Images and Media

Common Content takes advantage of django-imagekit to manage images. Models are provided for storing file metadata including copyright information.

Common Content uses presets to produce images in specific sizes as recommended by Buffer's Social Media Image Guidelines.

These named image presets are available:

  • small: 160x90
  • medium: 400x225
  • large: 960x540
  • opengraph: 1200x630
  • hd720p: 1280x720
  • hd1080p: 1920x1080
  • portrait_small: 90x160
  • portrait_medium: 225x400
  • portrait_large: 540x960
  • portrait_cover: 1000x1500
  • portrait_social: 1080x1350
  • portrait_hd: 1080x1920

About

The 80% solution to bootstrapping a new Django site: models, views, templates for basic publishing

Topics

Resources

License

Stars

Watchers

Forks