Introduction

django-inline-media allows insertion of inline media content in your text fields. Based on django-basic-apps/inlines, it provives the following features:

  1. Inserts pictures and collection of pictures into your texts using the TextAreaWithInlines widget.
  2. Positions media content at different places and sizes (mini/small/medium/large at left/right or full at the left/center/right).
  3. Facilitates administration with thumbnails and search by tags, author and license.
  4. Shows a customised control to insert media content in text fields.
  5. Uses jquery prettyPhoto to show pictures and galleries when clicking on them.
  6. Tested under:
    • Python 2.7 and Python 3 (3.2, 3.4, 3.5, 3.6)
    • Django 1.8, Django 1.9 and Django 1.10

The following sample shows a centered inline picture set inserted in a text, on mouseover event the first 3 photos unfold:

_images/cover.png

Run the demo project to see django-inline-media in action.

Demo projects

There is a demo project showing stories (custom model Article) with a TextFieldWithInlines, so that the user may insert inline media content in the text.

Find the code of the example sites here.

Demo sites setup

Run the demo sites in a virtualenv for this app. Create the virtualenv, clone the code and cd into any of the demo sites. Then do as follow.

$ cd django-inline-media/example/demo $ python manage.py syncdb –noinput $ python manage.py collectstatic $ python manage.py runserver

Admin user/pwd: admin/admin.

Demo project structure

The home page shows a link to an article list. The article list contains six example articles. Each of which contains pictures or picture sets located at different positions in the text. Take a look at the articles and click on the media. Pictures and picture sets are clickable by default. When clicking on a picture, the prettyPhoto jquery plugin overlays the picture on the current page. When clicking on a picture set, the plugin overlays a gallery view of all the pictures in the picture set.

The demo site uses django-inline-media with a custom articles app. The articles app defines the Article model. django-inlines-media provides 4 models: InlineType, License, Picture and PictureSet:

_images/demo_admin.png

The Article model has a body field of type TextFieldWithInlines. The field uses its own widget TextareaWithInlines that renders an extra control to insert inline media in the textarea. The inline media content can be placed at different positions and with different size.

Positions can be left, right, or center. The size can be mini (80px width), small (150px width), medium (200px width), large (250px width) and full. Pictures at the center are in full size, and picturesets in the center render at a default size of 380x280 pixels. All sizes are customizables using the setting INLINE_MEDIA_CUSTOM_SIZES.

Example articles

Let’s see how articles in the demo site look like. Following you can see example articles one, two and five. Article views are combined with their body fields in the admin UI so that you can get an idea of how inline elements look like in the textarea and what’s the effect in the final rendered article.

Example article one

Article one is made of four text paragraphs with a picture. The picture and its description float at the right hand side of the first paragraph.

_images/demo_article_1.png

The code highlighted in blue inserts the Ubuntu logo at the top right side of the article’s text. It’s been added using the control Inlines below the body’s textarea.

The attribute type in the <inline> corresponds with the InlineType instance of the content_type Picture. The attribute id is the object id of the picture, and class represents the CSS class applied when rendering the inline with the template templates/inline_media/inline_media_picture.html.

Example article two

Yet another four paragraphs example article with two pictures, both floating at the right hand side, the first one on the first paragraph and the second on the second paragraph.

_images/demo_article_2.png

The Python logo uses the CSS class inline_large_right while the Django logo uses inline_medium_right. Both are clickable and both contain a description with an anchor element.

The change picture view for the first image, the Python one, looks like this:

_images/demo_pic_change_view_python.png

Removing the tick of the box Show as link avoids making the image clickable. As an alternative you can also rewrite the template inline_media/inline_media_picture.html using the attributes at will. Take a look at the Article 4 to see an example with an inline non-clickable picture.

Example article five

Three paragraphs with an inline picture set. The picture set float at the right side using the inline_medium_right CSS class.

_images/demo_article_5.png

An inline picture set has different looks:

  • As an inline: the picture set shows only the croped version of the cover picture.
  • On mouseover: A croped version of the 2/3 first pictures of the set are fanned out.
  • On click: The picture set is overlaid in a gallery view showing complete pictures.

The overlaid gallery view of the picture set of article five:

_images/demo_article_5_gallery.png

Tutorial

Django-inline-media is a simple reusable app that allows insertion of inline media content, so far pictures and picture sets, into texts.

Motivation

Django-inline-media help your users place images or collections of images as inlines in texts.

Any application used to write text that needs to insert inline pictures is a good candidate to adopt Django-inline-media. The app will render the text with inline pictures or picture sets, and when defined as clickable pictures will be overlayed in a bigger size on top of the page.

Django-inline-media comes with two media models: Picture and PictureSet, but you can create your own inline types to support other media formats or providers (oembed based content coming soon).

This tutorial explains how to install and configure django-inline-media, how to integrate it in your web project and how to use the widget. It additionally supports the Wysihtml5 rich text editor by providing a replacement for the Wysihtml5’s insertImage command. See the demo_wysihtml5 for details on this feature.

Installation

Check out the sources and add the app to your project or PYTHONPATH.

Use git, pip or easy_install to check out django-inline-media from Github or get a release from PyPI:

  1. Use git to clone the repository, and then install the package (read more about git):
  • git clone git://github.com/danirus/django-inline-media.git and
  • python setup.py install
  1. Or use pip (read more about pip):
  • Do pip install django-inline-media, or
  • Edit your project’s requirements file and append either the Github URL or the package name django-inline-media, and then do pip install -r requirements.
  1. Or use easy_install (read more about easy_install):
  • Do easy_install django-inline-media

Configuration

Follow the steps:

  1. Install required apps:
  1. Add the following entries to your settings.py:
  • Add inline_media, sorl.thumbnail and tagging to INSTALLED_APPS.
  • Add THUMBNAIL_BACKEND = "inline_media.sorl_backends.AutoFormatBackend"
  • Add THUMBNAIL_FORMAT = "JPEG"
  • Optionally add an extra setting to control where django-inline-media stores images (see Settings). It has a sane default, so don’t bother to much.
  1. Run management commands:
    • python manage.py syncdb to create inline_media DB entities (License, Picture, PictureSet)
    • python manage.py collectstatic to copy CSS and JavaScript content from inline_media to your project’s static directory

There are extra steps when planning to use the Wysihtml5 editor. Read on the specific ref-wysihtml5-demo.

Using inline-media

Using inline-media is pretty easy:

  1. Decide which fields of your models will hold inline media content (the typical candidate: a body field of a blog Post model)
  2. Change their type from TextField to TextFieldWithInlines. This change does not affect your models’ table definition, but just the way fields are rendered.
  3. Change the admin class of those models and make them inherit from AdminTextFieldWithInlinesMixin. Fields of type TextfieldWithInlines will be rendered as TextareWithInlines

Let’s see it with an example: the Article model.

Example code

The Article model, in the demo project, has a couple of fields of type TextField, abstract and body. Only the field body will hold inline media content. Article definition will look as follow:

from inline_media.fields import TextFieldWithInlines

class Article(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(unique_for_date='publish')
    abstract = models.TextField()
    body = TextFieldWithInlines()
    publish = models.DateTimeField(default=datetime.now)

The ArticleAdmin class will inherit from both, AdminTextFieldWithInlinesMixin and Django’s ModelAdmin:

from django.contrib import admin
from inline_media.admin import AdminTextFieldWithInlinesMixin
from demo.articles.models import Article

class ArticleAdmin(AdminTextFieldWithInlinesMixin, admin.ModelAdmin):
    list_display  = ('title', 'publish')
    list_filter   = ('publish',)
    search_fields = ('title', 'abstract', 'body')
    prepopulated_fields = {'slug': ('title',)}
    fieldsets = ((None,
                  {'fields': ('title', 'slug', 'abstract', 'body',
                              'publish',)}),)

admin.site.register(Article, ArticleAdmin)

In action

Look at the admin site of the demo project. Click on any of the articles and see that the inlines field below the body allows you to choose between Picture and PictureSet:

_images/tutorial_article_change_view.png

Your articles detail template (example/demo/templates/articles/article_detail.html) loads the inlines templatetag and apply the render_inlines filter to the body field:

{% load i18n inlines %}
...

<div class="inline_media_clearfix">
  {{ object.body|render_inlines }}
</div>

You can also customize inline-media templates for pictures and picture sets.

Filters

Django-inline-media comes with two filters and one tag:

  • filter render_inlines
  • filter extract_inlines

Load the templatetag module to use them in your templates:

{% load inlines %}

Filter: render_inlines

Renders inlines in a text by passing them through inline templates.

Syntax:

{{ <field>|render_inlines }}

Inline Syntax (singular):

<inline type="<app_name>.<model_name>" id="<id>" class="<cssclass>" />

Inline Syntax (plural):

<inline type="<app_name>.<model_name>" ids="<id>, <id>, <id>" />
An inline template will be used to render the inline. Templates will be located in the following maner:
inline_media/<app_name>_<model_name>.html
The template will be passed the following context:
  • object: an object for the corresponding passed id, or
  • object_list: a list of objects for the corresponding ids.

It would be wise to anticipate both object_list and object unless you know for sure one or the other will only be present.

Example usage:

{{ object.body|render_inlines }}

Filter: extract_inlines

Extract inlines from a text.

Syntax:

{{ <field>|extract_inlines }}

Example usage:

{% for inline in object.body|extract_inlines %}
  {% ifequal inline.content_type "inline_media.picture" %}
    {% include "inline_media/inline_media_picture.html" with object=inline.object class=inline.class %}
  {% endifequal %}
{% endfor %}

Settings

Django-inline-media recognizes four setting:

INLINE_MEDIA_TYPES

Optional

Defines the inline media types available project wide.

It defaults to:

INLINE_MEDIA_TYPES = ['inline_media.picture',
                      'inline_media.pictureset']

INLINE_MEDIA_CUSTOM_SIZES

Optional

This setting defines custom size values for the available INLINE_MEDIA_TYPES. By default every inline type declared in INLINE_MEDIA_TYPES can be rendered in mini, small, medium, large and full size.

INLINE_MEDIA_CUSTOM_SIZES is a 2-level depth dictionary to define custom size values for each of the 5 size classes. Size classes can also be disabled.

The first level contains inline types with app_label.model pairs as keys. The second level contains class sizes as keys and values as geometries. When the value is just an int, it represents the width of the thumbnail. When the value is a tuple it represents the (width, height) of the thumbnail. The value can be None, what means the size won’t be available for that inline type.

It defaults to:

INLINE_MEDIA_CUSTOM_SIZES = {
    'inline_media.picture': {
        'mini': 80,
        'small': 150,
        'medium': 200,
        'large': 250,
    },
    'inline_media.pictureset': {
        'mini': None,
        'small': (150, 150),
        'medium': (200, 200),
        'large': (250, 250),
        'full': (380, 280)
    }
}

See that the ‘full’ class size is not defined for the type inline_media.picture. That doesn’t disable it. By default the 5 class sizes are active for every inline type defined in INLINE_MEDIA_TYPES. The purpose of this setting is either to pass a custom size in the context to the template, or to disable a class size.

To disable the ‘small’ size for type inline_media.pictureset just set it to None in your settings module:

INLINE_MEDIA_CUSTOM_SIZES = {
    'inline_media.pictureset': {
        'small': None,
    }
}

INLINE_MEDIA_TEXTAREA_ATTRS

Optional

This setting define attributes to apply to TextareaWithInlines widgets.

To apply common attributes to all TextareaWithInline widgets use the default key, and define attributes and values in its dictionary (see the example below).

You can also apply rendering attributes on a per app_label.model and field basis.

In this example, every TextFieldWithInlines field will get the style attribute applied by default. Then, abstract and body fields of the articles.article model will get the attribute rows applied too. The style attribute defined in the default key can be overriden by simply defining it again for an app_label.model/field combination:

INLINE_MEDIA_TEXTAREA_ATTRS = {
    'default': {
        'style': 'font: 13px monospace',
    },
    'articles.article': {
        'abstract': {
            'rows':  5
        },
        'body': {
            'rows': 20
        }
    }
}

Defaults to {} so that no extra attributes are applied.

INLINE_MEDIA_REMOVE_TAGS

Optional

This setting list all the tags that could be added by the parser ‘html.parser’ used with BeautifulSoup4 to render the content of TextFieldWithInlines. ‘html.parser’ is the only parser available under Python 3 at the moment.

An example:

INLINE_MEDIA_REMOVE_TAGS = ['</br>', </whatever>']

Defaults to ['</br>']

ADMIN_IMAGES_PATH

Optional

This setting establishes the path under which Django admin images may be found.

An example:

ADMIN_IMAGES_PATH = "%s/admin/img/admin" % STATIC_URL # Django 1.3

Defaults to "%s/admin/img" % settings.STATIC_URL, the Django 1.4 admin images path.

Templates

List of template files coming with Django-inline-media.

inline_media/inline_media.picture.mini.html
Renders an <inline> picture with any of the followin CSS classes:
  • inline_mini_left or inlin_mini_right.
inline_media/inline_media.picture.default.html
Renders an <inline> picture with any of the following CSS classes:
  • inline_small_left or inlin_small_right
  • inline_medium_left or inlin_medium_right
  • inline_large_left or inlin_large_right
inline_media/inline_media.picture.full.html
Renders an <inline> picture with any of the following CSS classes: * inline_full_left, inline_full_center, inlin_full_right.
inline_media/inline_media.pictureset.mini.html
Renders an <inline> pictureset with any of the followin CSS classes:
  • inline_mini_left or inline_mini_right.
inline_media/inline_media.pictureset.default.html
Renders an <inline> pictureset with any of the following CSS classes:
  • inline_small_left or inline_small_right
  • inline_medium_left or inline_medium_right
  • inline_large_left or inline_large_right
inline_media/inline_media.pictureset.full.html
Renders an <inline> pictureset with any of the followin CSS classes:
  • inline_full_left, inline_full_center, inline_full_right.

Template customization

Django-inline-media will try to use a template matching the following pattern:

  • inline_media/<app-label>.<model>.<size>.html Being <size> one of the following:

    • mini
    • small
    • medium
    • large
    • full

    Note: Actual size values can be customize through the setting INLINE_MEDIA_CUSTOM_SIZES. See it the Settings.

When django-inline-media has to render an element with a CSS class like inline_medium_left, it will first look for the template:

  • inline_media/<app_label>.<model>.medium.html

And if it doesn’t exist it will use the default template:

  • inline_media/<app_label>.<model>.default.html

Your own InlineTypes

If the django-inline-media models, Picture and PictureSet, are not suitable for your project or need another ones, just create your own and bind them to the app.

Once you have your model (say MyPicture), declare it the setting INLINE_MEDIA_TYPES. Your model will then show up in the dropdown list of inline types at the bottom of your TextFieldWithInlines fields (like the body field in the Article model of the demo).

Then create templates to render your own media content. Name your templates after the correspoding app_label for your model:

  • inline_media/<my_app_label>.mypicture.<size>.html
  • inline_media/<my_app_label>.mypicture.default.html

Quick start

  1. Get the dependencies:

    $ pip install -r requirements.pip
    
  2. In your settings.py:

  • Add inline_media, sorl.thumbnail and tagging to INSTALLED_APPS.
  • Add THUMBNAIL_BACKEND = "inline_media.sorl_backends.AutoFormatBackend"
  • Add THUMBNAIL_FORMAT = "JPEG"
  1. Create a model with a field of type TextFieldWithInlines.
  2. Create an admin class for that model by inheriting from both inline_media.admin.AdminTextFieldWithInlinesMixin and Django’s admin.ModelAdmin.
  3. Optionally, customise inline_media templates by copying them from inline_media/templates/inline_media/ to your inline_media/ folder in your templates directory.
  1. Run manage.py commands: syncdb, collectstatic, runserver.
  2. Create two InlineType objects, one for the Picture model and one for the PictureSet model.
  3. Upload some pictures and create some picture sets.
  4. Add content to the model using the field TextFieldWithInlines and see that you can insert inline content in the textarea. It will be rendered in the position indicated by the CSS class selected in the dropdown box.
  5. Hit your app’s URL!

Run the demo in django-inline-media/examples/demo to see an example.

Indices and tables