Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
Merge article/publishing changes from branch 'glamkit' into feature/n…
Browse files Browse the repository at this point in the history
…ew_articles

# Conflicts:
#	icekit/articles/admin.py
#	icekit/articles/page_type_plugins.py
  • Loading branch information
Greg Turner committed Sep 27, 2016
2 parents bf28636 + 1228c36 commit 866e5a1
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 13 deletions.
5 changes: 3 additions & 2 deletions docs/howto/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ ICEkit also has a simpler `PublishableArticle` model, which implements a
Publishable Fluent Contents model - ie it's a straightforward Django model
that happens to have rich content and be publishable. This is useful for more
normal Django collections-of-things, like Press Releases, People, Articles.

It's common to have a collecton of items with a paired `AbstractLayoutPage`
Page to list/navigate the collection. See the `icekit-press-releases`
project for a worked example of this.
Page to list/navigate the collection. See the `authors` app for a worked
example of this.

### Adding help text to a Placeholder

Expand Down
6 changes: 6 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,20 @@ Add custom functionality to your site.
* [Placeholders]
* [Publishing]
* [Page trees and mptt]
* [Articles]
* [Writing portable apps]


# Apps for ICEkit
## Included apps, pagetypes and plugins

* Apps:
* `authors` - descriptions of site contributors

* Page type plugins:
* `layout_page` - integrates with our flexible layouts system.
* `search_page` - integrates with [Haystack].
* `authors.page.AuthorListing` - a list of Authors
* Modular content plugins:
* `brightcove`
* `child_pages`
Expand Down Expand Up @@ -88,6 +93,7 @@ team at [the Interaction Consortium]: [labs@interaction.net.au](mailto:labs@inte
[Creating content plugins]: howto/plugins.md
[Deploying ICEkit]: howto/deployment.md
[Layouts]: topics/layouts.md
[Articles]: topics/articles.md
[Placeholders]: topics/placeholders.md
[Publishing]: topics/publishing.md
[Page trees and mptt]: topics/page-trees-and-mptt.md
Expand Down
184 changes: 184 additions & 0 deletions docs/topics/articles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# `Article`s and `ListingPage`s

`Article`s are publishable content types that live in collections. Normally
articles are mounted under a parent's URL.

An example of an article is a Press Release, which would be mounted under a
Press Release Listing Page. The Listing Page has the URL "/press" and thus all
the Press Releases have the URL "/press/<slug>".

## `ArticleBase`

The `icekit.articles.models.ArticleBase` inherits `title`, `slug` and
publishing fields, and each `ArticleBase` subclass implements some key
functionality:

1. **Links to parents.**
In order for an Article to know its URL (which is based on a parent's URL), it
should define a `parent` link, which is normally a link to a `ListingPage`.

1. **A view.**
If an Article is mounted under a `ListingPage` parent, the ListingPagePlugin
will call `get_response(request, parent)` on the article, which should
return the necessary `HttpResponse`. If the Article is a `fluent_contents`
model, the view functions are implemented by `fluent_contents`.

There is also a class `icekit.articles.models.PolymorphicArticleBase` which
extends the Article class with django-polymorphic functionality, allowing
you to define articles of different shapes and mount them under the same
`parent` model.

## `ListingPage`

The `icekit.articles.models.ListingPage` model is a page type that requires
`get_items()` and `get_visible_items()` to be defined in subclasses.
When viewed, ListingPage lists the items returned by `get_items()`.
`get_visible_items()` is necessary because an editor may wish to preview
unpublished items (that aren't returned by `get_items()`)

## Admins

For normal Articles, inherit from `ArticleAdminBase`. For polymorphic articles,
inherit from `PolymorphicArticleParentAdmin` and `PolymorphicArticleChildAdmin`
as shown in the example below.

## Bare-bones example

The following defines a minimal rich content Article, mounted under a
minimal `ArticleCategoryPage`.

In `models.py`:

from django.db import models
from icekit.abstract_models import FluentFieldsMixin
from icekit.articles.abstract_models import ListingPage, ArticleBase


class ArticleCategoryPage(ListingPage):
def get_items(self):
unpublished_pk = self.get_draft().pk
return Article.objects.published().filter(parent_id=unpublished_pk)

def get_visible_items(self):
unpublished_pk = self.get_draft().pk
return Article.objects.visible().filter(parent_id=unpublished_pk)


class Article(ArticleBase, FluentFieldsMixin):
parent = models.ForeignKey(
ArticleCategoryPage,
limit_choices_to={'publishing_is_draft': True}
)

In `admin.py`:

from django.contrib import admin
from icekit.admin import FluentLayoutsMixin
from icekit.articles.admin import ArticleAdminBase
from .models import Article


@admin.register(Article)
class ArticleAdmin(ArticleAdminBase, FluentLayoutsMixin):
pass

In `page_type_plugins.py`:

from fluent_pages.extensions import page_type_pool
from icekit.page_types.layout_page.admin import LayoutPageAdmin
from icekit.articles.page_type_plugins import ListingPagePlugin
from .models import ArticleCategoryPage


@page_type_pool.register
class ArticleCategoryPagePlugin(ListingPagePlugin):
model = ArticleCategoryPage


## Bare-bones polymorphic example

The following defines a polymorphic structure of minimal rich content Article,
and a zero-content (except title) `RedirectArticle`.

In `models.py`:

from django.db import models
from django.http import HttpResponseRedirect
from fluent_pages.pagetypes.redirectnode.models import RedirectNode
from icekit.abstract_models import FluentFieldsMixin
from icekit.fields import ICEkitURLField
from icekit.articles.abstract_models import ListingPage, PolymorphicArticleBase
from django.utils.translation import ugettext_lazy as _


class ArticleCategoryPage(ListingPage):
def get_items(self):
unpublished_pk = self.get_draft().pk
return Article.objects.published().filter(parent_id=unpublished_pk)

def get_visible_items(self):
unpublished_pk = self.get_draft().pk
return Article.objects.visible().filter(parent_id=unpublished_pk)


class Article(PolymorphicArticleBase):
parent = models.ForeignKey(
ArticleCategoryPage,
limit_choices_to={'publishing_is_draft': True}
)

class LayoutArticle(Article, FluentFieldsMixin):
class Meta:
verbose_name = "Article"


class RedirectArticle(Article):
new_url = ICEkitURLField(
help_text=_('The URL to redirect to.')
)
redirect_type = models.IntegerField(
_("Redirect type"),
choices=RedirectNode.REDIRECT_TYPE_CHOICES,
default=302,
help_text=_(
"Use 'normal redirect' unless you want to transfer SEO ranking to the new page."
)
)

def get_response(self, request, *args, **kwargs):
response = HttpResponseRedirect(self.new_url)
response.status_code = self.redirect_type
return response

class Meta:
verbose_name = "Redirect"

In `admin.py`:

from django.contrib import admin
from icekit.admin import FluentLayoutsMixin
from icekit.articles.admin import PolymorphicArticleParentAdmin, \
PolymorphicArticleChildAdmin
from .models import Article, LayoutArticle, RedirectArticle


class ArticleChildAdmin(PolymorphicArticleChildAdmin):
base_model = Article


class LayoutArticleAdmin(ArticleChildAdmin, FluentLayoutsMixin):
base_model=LayoutArticle


class RedirectArticleAdmin(ArticleChildAdmin):
base_model=RedirectArticle


@admin.register(Article)
class ArticleParentAdmin(PolymorphicArticleParentAdmin):
base_model = Article
child_models = ((LayoutArticle, LayoutArticleAdmin),
(RedirectArticle, RedirectArticleAdmin),)


Finally, `page_type_plugins.py` is identical to the non-polymorphic example above.
2 changes: 1 addition & 1 deletion docs/topics/portable-apps.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ In the app whose label is being updated, make the following changes:
with a deprecation warning.

* Add a `db_table: {old app label}` option to all `CreateModel` operations in
existing migrations, if not already defined, giving the current app label
existing migrations, if not already defined, giving the previous app label
as the value.

* Run `manage.py makemigrations {app_label}`. Django will detect that the
Expand Down
5 changes: 2 additions & 3 deletions icekit/articles/admin.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from django.contrib import admin
from polymorphic.admin import PolymorphicChildModelFilter, \
PolymorphicParentModelAdmin
PolymorphicParentModelAdmin, PolymorphicChildModelAdmin

from icekit.admin import FluentLayoutsMixin
from icekit.publishing.admin import PublishingAdmin

class TitleSlugAdmin(admin.ModelAdmin):
Expand All @@ -23,7 +22,7 @@ class PolymorphicArticleParentAdmin(PolymorphicParentModelAdmin, ArticleAdminBas
list_filter = (PolymorphicChildModelFilter,)


class PolymorphicArticleChildAdmin(ArticleAdminBase):
class PolymorphicArticleChildAdmin(PolymorphicChildModelAdmin, ArticleAdminBase):
pass


1 change: 1 addition & 0 deletions icekit/articles/page_type_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

class ListingPagePlugin(ICEkitFluentContentsPagePlugin):
render_template = 'icekit/layouts/listing.html'
model_admin = LayoutPageAdmin

def get_view_response(self, request, page, view_func, view_args, view_kwargs):
"""
Expand Down
5 changes: 5 additions & 0 deletions icekit/dashboard/static/admin/css/icekit_dashboard.less
Original file line number Diff line number Diff line change
Expand Up @@ -619,3 +619,8 @@ input#id_tags {
width: 60em;
max-width: 100%;
}

//if an article is suppressed, colour the publish link red
.field-publishing_column a.suppressed {
color: #9b4444;
}
14 changes: 7 additions & 7 deletions icekit/project/settings/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,18 +414,18 @@
# given model/field, without generating additional unecessary thumbnails. This
# is essential when using a remote storage backend.
THUMBNAIL_ALIASES = {
# 'app[.model][.field]': {
# 'name-WxH': {
# 'size': (W, H),
# ...,
# },
# },
# 'app[.model][.field]': {
# 'name-WxH': { 'size': (W, H), },
# },
'': {
'author_portrait': {
'size': (360, 640),
},
'admin': {
'size': (150, 150),
},
'content_image': {
'size': (1138, 0), # maximum width of a content column
'size': (1138, 0), # maximum width of a bootstrap content column
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions icekit/publishing/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,19 @@ def clone_relations(self, dst_obj):
# re-created on publish thus always have empty M2M rels.
dst_m2m.add(*src_m2m.all())

def is_suppressed_message(self):
"""
Occasionally items may not be visible to the public even if they have
been published and can be previewed. For example, if they belong to a
parent who is not published.
In that case, returning a string here will result in a red `published`
indicator in admin, and the string will be shown in the hyperlink
title.
:return: True always
"""
return True

class PublishableFluentContentsPage(FluentContentsPage,
PublishingModel):
Expand Down

0 comments on commit 866e5a1

Please sign in to comment.