Puput

Puput是一个功能强大且简单的Django博客管理程序。 它使用Wagtail CMS作为内容管理系统。

Puput是Hoopoe的加泰罗尼亚名称,一只美丽的鸟。

特性

  • Built with Wagtail CMS and Django
  • Inspired in Wordpress and Zinnia
  • Simple & responsive HTML template by default
  • SEO friendly urls
  • Support for Disqus comments
  • Entries by author, tags, categories, archives and search term
  • Last & popular entries
  • Configurable sidebar widgets
  • RSS feeds
  • Related entries
  • Extensible entry model
  • Configurable default template color
  • Social share of blog entries (facebook, twitter, linkedin and google plus)
http://i.imgur.com/d13sGI3.png

内容管理:

Setup

If you’re starting from a Django project without Wagtail integration and you want to add a blog site to your project, please follow the steps outlined under Standalone blog app. If you are already using Wagtail, refer to Installation on top of Wagtail.

Standalone blog app

  1. Install Puput and its dependencies via pip install puput.
  2. Append PUPUT_APPS to INSTALLED_APPS in your settings.
from puput import PUPUT_APPS

INSTALLED_APPS += PUPUT_APPS

This includes Puput, Wagtail’s apps and certain third-party dependencies. If you are already referencing one of these apps in your INSTALLED_APPS list, please include the following apps manually in order to avoid app collisions:

INSTALLED_APPS = (
    ...
    'wagtail.core',
    'wagtail.admin',
    'wagtail.documents',
    'wagtail.snippets',
    'wagtail.users',
    'wagtail.images',
    'wagtail.embeds',
    'wagtail.search',
    'wagtail.sites',
    'wagtail.contrib.redirects',
    'wagtail.contrib.forms',
    'wagtail.contrib.sitemaps',
    'wagtail.contrib.routable_page',
    'taggit',
    'modelcluster',
    'django_social_share',
    'puput',
)
  1. Add Wagtail’s required middleware classes to MIDDLEWARE_CLASSES in your Django settings.
MIDDLEWARE_CLASSES = (
    ...
    'wagtail.core.middleware.SiteMiddleware',
    'wagtail.contrib.redirects.middleware.RedirectMiddleware',
)
  1. Add the request context processor to the TEMPLATE_CONTEXT_PROCESSORS structure in your Django settings.
TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    'django.template.context_processors.request',
)
  1. Set the WAGTAIL_SITE_NAME variable to the name of your site in your Django settings.
WAGTAIL_SITE_NAME = 'Puput blog'
  1. Configure the MEDIA_ROOT and MEDIA_URL settings as described in the Wagtail Docs.
MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'media')
MEDIA_URL = '/media/'
  1. Place Puput’s URLs at the bottom of the urlpatterns. It also includes Wagtail’s URLs.
urlpatterns = [
    ...
    path(r'', include('puput.urls')),
]
  1. To make your Django project serve your media files (e.g. things you upload via the admin) during development, don’t forget to add this to your urlpatterns:
from django.conf import settings
from django.conf.urls import url

if settings.DEBUG:
    import os
    from django.conf.urls.static import static
    from django.views.generic.base import RedirectView
    from django.contrib.staticfiles.urls import staticfiles_urlpatterns

    urlpatterns += staticfiles_urlpatterns() # tell gunicorn where static files are in dev mode
    urlpatterns += static(settings.MEDIA_URL + 'images/', document_root=os.path.join(settings.MEDIA_ROOT, 'images'))
    urlpatterns += [
        url(r'^favicon\.ico$', RedirectView.as_view(url=settings.STATIC_URL + 'myapp/images/favicon.ico')),
    ]
  1. Run python manage.py migrate and python manage.py puput_initial_data to load initial data to start a blog site.
  2. Open your browser at http://127.0.0.1:8000/blog/ to view your blog home page. Go to http://127.0.0.1:8000/blog_admin/ to view the admin site and edit your content.

Installation on top of Wagtail

  1. This assumes that you have Wagtail >= 2.0 installed and you can access /admin; if this is not the case or you would like to use a newer version of Wagtail than is in the dependencies of puput, follow the steps below in a python venv:
pip install --upgrade pip
pip install wheel
pip install wagtail django-colorful django-el-pagination django-social-share
pip install --no-deps puput
wagtail start mysite
cd mysite
python manage.py migrate
python manage.py createsuperuser
  1. If you haven’t already, install Puput and its dependencies via pip install puput.
  2. In your Django settings (most commonly settings/base.py inside the wagtail directory), add the following to the INSTALLED_APPS following the wagtail section:
'wagtail.contrib.sitemaps',
'wagtail.contrib.routable_page',
'django_social_share',
'puput',
'colorful',
  1. In the same file, also add the line PUPUT_AS_PLUGIN = True to the very bottom
  2. In the same folder, add to urls.py near the top from puput import urls as puput_urls and just above url(r'', include(wagtail_urls)), add url(r'',include(puput_urls)),
  3. Run python manage.py migrate followed by python manage.py runserver 0:8000 to start the server
  4. To create a Puput blog navigate to the Wagtail admin interface at 127.0.0.1:8000/admin and create a new child page of type Blog. Every blog post is then created as a child of this blog.

Docker

If you want to run Puput in a Docker container please visit docker-puput for detailed instructions.

编辑器的仪表板

Puput uses the default Wagtail CMS admin page in order to manage the content of the blog. It provides a powerful, clean and modern interface. Just open your browser at http://127.0.0.1:8000/blog_admin/.

This is how adding entry page looks:

https://i.imgur.com/QlsVfwT.png

Please visit Wagtail: an Editor’s guide for further details of how to use Wagtail editor’s dashboard.

Note

If you want to edit the owner of an entry you need to install Wagtail >= 1.11.

Comments

Puput allows customize the comment system for your blog entries. Simply go to settings tab while editing blog properties and add the required parameters depending on which system you want to use.

Disqus

Set Disqus api secret and Disqus shortname with your project values and comments will be displayed in each blog entry. Disqus api secret is needed to retrieve the number of comments of each entry. If you don’t need such data in your blog just fill Disqus shortname field.

Note

If you set Disqus api secret you need to install tapioca-disqus to access to the Disqus API

pip install tapioca-disqus

Feeds

Puput allows to customize the feeds for your blog entries. These options can be found in the settings tab while editing blog properties.

Feed description

Set Use short description in feeds to False if you want to use the full blog post content as description for the feed items. When set to True (by default), Puput will try to use the blog post’s excerpt or truncate the body to 70 words when the excerpt is not available.

Extending Entry Page

Puput allows extend the EntryPage model. It provides two approaches to extend entries depending on the project requirements.

Multi-table inheritance

The easiest way to extend EntryPage model is using multi-table inheritance. Imagine if you need an special entry that needs a mandatory video url. You can write an entry model like this on models.py of your project:

from django.db import models
from puput.models import EntryPage


class VideoEntryPage(EntryPage):
    video_url = models.URLField()
    content_panels = EntryPage.content_panels + [
        FieldPanel('video_url')
    ]

You also need to modify subpage_types field of BlogPage model as by default is bounded to have only EntryPage as children. You can rewrite the above example with this:

from django.db import models
from puput.models import EntryPage, BlogPage


class VideoEntryPage(EntryPage):
    video_url = models.URLField()
    content_panels = EntryPage.content_panels + [
        FieldPanel('video_url')
    ]
BlogPage.subpage_types.append(VideoEntryPage)

This will create two independent tables on the database so you can create entries on your blog that are instances of EntryPage or VideoEntryPage.

Abstract base classes

Another approach to have an extension of entries is using abstract base classes inheritance method by inheriting from EntryAbstract instead of EntryPage. In the previous example, it’s shown a blog with regular entries (EntryPage) and tv entries (VideoEntryPage). If you only want to have VideoEntryPage on your blog and create a simple table you need to extend EntryAbstract model on models.py of your project.

from django.db import models
from puput.abstracts import EntryAbstract
from wagtail.wagtailadmin.edit_handlers import FieldPanel


class VideoEntryAbstract(EntryAbstract):
    video_url = models.URLField()

    content_panels = [
        FieldPanel('video_url')
    ]

    class Meta:
        abstract = True

Warning

Do not import the EntryPage model in your models.py where defining the abstract extended model because it will cause a circular importation.

Registering entry extension

You have to register the model extension in settings.py adding PUPUT_ENTRY_MODEL with the path of the abstract model.

Following the previous example you have to add PUPUT_ENTRY_MODEL in your settings.py file:

PUPUT_ENTRY_MODEL = 'youproject.models.VideoEntryAbstract'
Migrations

If you extend EntryPage model you must migrate the database in order to the see the changes that you made on the model. However if you perform a makemigrations operation it will create a migration in puput.migrations of your local Puput module folder.

So you need to define a new path to store the changes made on EntryPage model extension. You have to use MIGRATION_MODULES for this purpose:

MIGRATION_MODULES = {'puput': 'youproject.puput_migrations'}

After run makemigrations puput migrations will appear on puput_migrations folder.

Note

It’s recommended that the new initial migration represents the initial Puput migration in order to avoid conflicts when applying migrate puput command. A recommend way is run makemigrations puput before define Entry model extension on settings.py by setting PUPUT_ENTRY_MODEL.

Import your blog data

If you need to migrate a blog system to Puput we provide you a various tools to import your data.

Prerequisites

All importers need the lxml Python package, which has the prerequisites libxml2 and libxslt.

To install on Ubuntu:

sudo apt-get install libxml2-dev libxslt-dev

To install on CentOS or Red Hat:

sudo yum install libxml2-devel libxml++-devel libxslt-devel

Zinnia

  1. Install zinnia-to-puput package and its dependencies pip install zinnia-to-puput

  2. Add zinnia2puput to your INSTALLED_APPS in settings.py file.

  3. Run the management command:

    python manage.py zinnia2puput
    

You can optionally pass the slug and the title of the blog to the importer:

python manage.py zinnia2puput --slug=blog --title="Puput blog"

Wordpress

  1. Install wordpress-to-puput package and its dependencies pip install wordpress-to-puput

  2. Add wordpress2puput to your INSTALLED_APPS in settings.py file.

  3. Run the management command:

    python manage.py wp2puput path_to_wordpress_export.xml
    

You can optionally pass the slug and the title of the blog to the importer:

python manage.py wp2puput path_to_wordpress_export.xml --slug=blog --title="Puput blog"

Blogger

  1. Install blogger2puput package and its dependencies pip install blogger2puput

  2. Add blogger2puput to your INSTALLED_APPS in settings.py file.

  3. Run the management command:

    python manage.py blogger2puput --blogger_blog_id=Your BlogID --blogger_api_key=Your APIKey
    

You can optionally pass the slug and the title of the blog to the importer:

python manage.py blogger2puput --slug=blog --title="Puput blog" --blogger_blog_id=Your BlogID --blogger_api_key=Your APIKey

Sites structure

Multi blog site

The Wagtail default page architecture it allows to create a tree based CMS where editors could create multiple pages that are children from others. The Puput architecture also follows this philosophy but you can only create Blog pages as parents and Entry pages as children. Furthermore all Blog pages must have Root page as parent.

This has a powerful advantage so you can create separated sites with multiple blog instances. For instance, you could create a simple blog http://www.example.com/blog/ and another one with videos (a videoblog) http://www.example.com/tv/.

Single blog site

A common case of use is having a site as a blog. In this case, Puput is also good for this purpose. If you have a site like http://www.myblog.com and you want that the root of the site will be blog page you can modify our Root page on site configuration (usually here) and select the desired blog page. So with this you will be able to go http://www.myblog.com instead of http://www.myblog.com/blog/.

Settings

Puput provides setting variables in order to customize your installation.

PUPUT_ENTRY_MODEL

Default value: 'puput.abstracts.EntryAbstract' (Empty string)

String setting to define the base model path for Entry model. See Extending Entry Page for more details.

PUPUT_AS_PLUGIN

Default value: False (Empty string)

Boolean setting to define if you set Puput as a plugin of a previously configured Wagtail project.

PUPUT_USERNAME_FIELD

Default value: 'username' (Empty string)

String setting to define the default author username field. Useful for people that are using a custom User model and/or other authentication method where an username is not mandatory.

PUPUT_USERNAME_REGEX

Default value: '\w+' (Empty string)

String setting to define the default author username regex used in routes. Useful for people that are using a custom User model.

Changelog

1.0.2 (2018-05-17)

  • Add missing image.
  • Add missing str methods.

1.0.1 (2018-04-19)

  • Fix header image.

1.0 (2018-04-10)

  • Add support for Django 2.0 and Wagtail 2.0. Drop Python 2.7 support.
  • Add code and block quote options to the entries text editor.
  • Improve default template visualisation.
  • Configurable default template color.
  • Add social sharing links.

0.9.2 (2018-02-13)

  • Remove django-compressor dependency.
  • Add German and Polish translations.

0.9.1 (2017-09-12)

  • Add missing migration.

0.9 (2017-08-03)

  • Fix issue that creates undesired migrations.
  • Add Django 1.11 & Python 3.6 support. Drop Python 3.3 support
  • Improve RSS feeds generation.
  • Fix issue with templatetags.
  • Add Italian, Russian, Brazilian and French translations.
  • Fix url resolution issues.

0.8 (2016-11-17)

  • Add Travis CI integration and functional tests.
  • Add Django 1.10 support.
  • Minor template tweaks.

0.7 (2016-08-18)

  • Add initial travis support.
  • Add canonical url and social share tags in templates for SEO purposes.
  • Allow to place Puput’s blog at any sitemap level.
  • Fix issue in entry comments update method.
  • Add PageChooserPanel for related entries chooser.
  • Improve flexibility on adding other comment systems.
  • Minor bug fixes.

0.6 (2016-05-18)

  • Fix issue when displaying entries without images.
  • Fix css issues.
  • Add django-compressor as project dependency.
  • Improve tags visualization.

0.5.2 (2016-02-18)

  • Removed django-endless-pagination which is no longer maintained and is not compatible with Django 1.9. Replaced by django-el-pagination.
  • Category slug is now editable on snippets section.

0.5.1 (2016-02-16)

  • Fix bug due a missing template tag.

0.5 (2016-02-12)

  • Altered URL structure in order to have blog as Wagtail root page.
  • Added Docker integration.
  • Archive list is now collapsible.

0.4.1 (2016-01-19)

  • Minor css bug fixes.

0.4 (2015-12-09)

  • Added a fancy logo.
  • Improved visualization of entries header images.
  • Minor bug fixes.

0.3 (2015-11-15)

  • Customizable username field in settings file.
  • Improvements in the documentation.
  • CSS cleanup. Added LESS file.
  • Minor bug fixes.
  • Added catalan translations.

0.2 (2015-09-22)

  • Extensible entry model.

0.1 (2015-09-12)

  • Initial release.

Authors

  • Marc Tudurí
  • Cristina Hernandez
  • Felipe Arruda
  • Edu Herraiz
  • David Valera
  • Iker Cortabarría
  • Carlos Salom
  • Basil Shubin
  • Milton Lenis
  • Timothy Allen
  • Pieter De Decker