Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Format blog entry's summary and body with RST. No moar raw HTML!

  • Loading branch information...
commit 48113e03b4587e1853c04ceeb626ebd95fb2c0a4 1 parent 466670b
@jphalip jphalip authored
View
4 django_website/blog/admin.py
@@ -1,9 +1,11 @@
from __future__ import absolute_import
from django.contrib import admin
+
from .models import Entry
admin.site.register(Entry,
list_display = ('headline', 'pub_date', 'is_active', 'is_published', 'author'),
- list_filter = ('is_active',)
+ list_filter = ('is_active',),
+ exclude = ('summary_html', 'body_html'),
)
View
43 ...ite/blog/migrations/0004_auto__add_field_entry_summary_html__add_field_entry_body_html.py
@@ -0,0 +1,43 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding field 'Entry.summary_html'
+ db.add_column('blog_entries', 'summary_html', self.gf('django.db.models.fields.TextField')(default=''), keep_default=False)
+
+ # Adding field 'Entry.body_html'
+ db.add_column('blog_entries', 'body_html', self.gf('django.db.models.fields.TextField')(default=''), keep_default=False)
+
+
+ def backwards(self, orm):
+
+ # Deleting field 'Entry.summary_html'
+ db.delete_column('blog_entries', 'summary_html')
+
+ # Deleting field 'Entry.body_html'
+ db.delete_column('blog_entries', 'body_html')
+
+
+ models = {
+ 'blog.entry': {
+ 'Meta': {'ordering': "('-pub_date',)", 'object_name': 'Entry', 'db_table': "'blog_entries'"},
+ 'author': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'body': ('django.db.models.fields.TextField', [], {}),
+ 'body_html': ('django.db.models.fields.TextField', [], {}),
+ 'headline': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'pub_date': ('django.db.models.fields.DateTimeField', [], {}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
+ 'summary': ('django.db.models.fields.TextField', [], {}),
+ 'summary_html': ('django.db.models.fields.TextField', [], {})
+ }
+ }
+
+ complete_apps = ['blog']
View
35 django_website/blog/migrations/0005_copy_entry_summary_and_body_to_html.py
@@ -0,0 +1,35 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ for entry in orm['blog.Entry'].objects.all():
+ entry.summary_html = entry.summary
+ entry.body_html = entry.body
+ entry.save()
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+
+
+ models = {
+ 'blog.entry': {
+ 'Meta': {'ordering': "('-pub_date',)", 'object_name': 'Entry', 'db_table': "'blog_entries'"},
+ 'author': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'body': ('django.db.models.fields.TextField', [], {}),
+ 'body_html': ('django.db.models.fields.TextField', [], {}),
+ 'headline': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'pub_date': ('django.db.models.fields.DateTimeField', [], {}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
+ 'summary': ('django.db.models.fields.TextField', [], {}),
+ 'summary_html': ('django.db.models.fields.TextField', [], {})
+ }
+ }
+
+ complete_apps = ['blog']
View
38 django_website/blog/migrations/0006_auto__add_field_entry_use_raw_html.py
@@ -0,0 +1,38 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding field 'Entry.use_raw_html'
+ db.add_column('blog_entries', 'use_raw_html', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False)
+
+
+ def backwards(self, orm):
+
+ # Deleting field 'Entry.use_raw_html'
+ db.delete_column('blog_entries', 'use_raw_html')
+
+
+ models = {
+ 'blog.entry': {
+ 'Meta': {'ordering': "('-pub_date',)", 'object_name': 'Entry', 'db_table': "'blog_entries'"},
+ 'author': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'body': ('django.db.models.fields.TextField', [], {}),
+ 'body_html': ('django.db.models.fields.TextField', [], {}),
+ 'headline': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'pub_date': ('django.db.models.fields.DateTimeField', [], {}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
+ 'summary': ('django.db.models.fields.TextField', [], {}),
+ 'summary_html': ('django.db.models.fields.TextField', [], {}),
+ 'use_raw_html': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ }
+ }
+
+ complete_apps = ['blog']
View
35 django_website/blog/migrations/0007_existing_entries_are_raw_html.py
@@ -0,0 +1,35 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ for entry in orm['blog.Entry'].objects.all():
+ entry.use_raw_html = True
+ entry.save()
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+
+
+ models = {
+ 'blog.entry': {
+ 'Meta': {'ordering': "('-pub_date',)", 'object_name': 'Entry', 'db_table': "'blog_entries'"},
+ 'author': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'body': ('django.db.models.fields.TextField', [], {}),
+ 'body_html': ('django.db.models.fields.TextField', [], {}),
+ 'headline': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'pub_date': ('django.db.models.fields.DateTimeField', [], {}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
+ 'summary': ('django.db.models.fields.TextField', [], {}),
+ 'summary_html': ('django.db.models.fields.TextField', [], {}),
+ 'use_raw_html': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ }
+ }
+
+ complete_apps = ['blog']
View
26 django_website/blog/models.py
@@ -5,6 +5,7 @@
from django.contrib.sites.models import Site
from django.contrib.comments.signals import comment_was_posted
from django.utils.encoding import smart_str
+from docutils.core import publish_parts
class EntryManager(models.Manager):
@@ -17,9 +18,12 @@ class Entry(models.Model):
slug = models.SlugField(unique_for_date='pub_date')
is_active = models.BooleanField(help_text="Tick to make the entry live on site (see also the publication date). Note that administrators (like yourself) are allowed to preview inactive content whereas other users and the general public aren't.", default=False)
pub_date = models.DateTimeField(help_text='For an entry to be published, it must be active and its publication date must be in the past.')
- summary = models.TextField(help_text="Use raw HTML.")
- body = models.TextField(help_text="Use raw HTML.")
+ summary = models.TextField()
+ summary_html = models.TextField(help_text="Use reStructuredText unless specified otherwise")
+ body = models.TextField(help_text="Use reStructuredText unless specified otherwise")
+ body_html = models.TextField()
author = models.CharField(max_length=100)
+ use_raw_html = models.BooleanField(help_text="Tick if you prefer to manually enter raw HTML instead of reStructureText formats in the summary and body. This option's main purpose is to cope with old entries that were entirely written in raw HTML.", default=False)
objects = EntryManager()
@@ -47,6 +51,24 @@ def comments_enabled(self):
delta = datetime.datetime.now() - self.pub_date
return delta.days < 60
+ def save(self, *args, **kwargs):
+ if self.use_raw_html:
+ self.summary_html = self.summary
+ self.body_html = self.body
+ else:
+ settings_overrides = {
+ 'doctitle_xform': False,
+ 'initial_header_level': 4,
+ 'id_prefix': 's-',
+ }
+ self.summary_html = publish_parts(source=smart_str(self.summary),
+ writer_name="html",
+ settings_overrides=settings_overrides)['fragment']
+ self.body_html = publish_parts(source=smart_str(self.body),
+ writer_name="html",
+ settings_overrides=settings_overrides)['fragment']
+ super(Entry, self).save(*args, **kwargs)
+
def moderate_comment(sender, comment, request, **kwargs):
ak = akismet.Akismet(
key = settings.AKISMET_API_KEY,
View
2  django_website/templates/blog/entry_archive.html
@@ -6,7 +6,7 @@
{% for object in latest %}
<h2><a href="{{ object.get_absolute_url }}">{{ object.headline|safe }}</a></h2>
- {{ object.body|safe }}
+ {{ object.body_html|safe }}
<p class="date small">Posted by <strong>{{ object.author }}</strong> on {{ object.pub_date|date:"F j, Y" }}</p>
{% endfor %}
View
2  django_website/templates/blog/entry_archive_day.html
@@ -9,7 +9,7 @@
{% for object in object_list %}
<h2><a href="{{ object.get_absolute_url }}">{{ object.headline|safe }}</a></h2>
<p class="small date">{{ object.pub_date|date:"F j, Y" }}</p>
-{{ object.body|safe }}
+{{ object.body_html|safe }}
{% endfor %}
View
2  django_website/templates/blog/entry_archive_month.html
@@ -9,7 +9,7 @@
{% for object in object_list %}
<h2><a href="{{ object.get_absolute_url }}">{{ object.headline|safe }}</a></h2>
<p class="small date">{{ object.pub_date|date:"F j, Y" }}</p>
-{{ object.body|safe }}
+{{ object.body_html|safe }}
{% endfor %}
View
2  django_website/templates/blog/entry_detail.html
@@ -5,6 +5,6 @@
{% block content %}
<h1>{{ object.headline|safe }}</h1>
{% if not object.is_published %}<p><strong>Preview mode</strong></p>{% endif %}
-{{ object.body|safe }}
+{{ object.body_html|safe }}
<p class="date small">Posted by <strong>{{ object.author }}</strong> on {{ object.pub_date|date:"F j, Y" }}</p>
{% endblock %}
View
2  django_website/templates/blog/entry_snippet.html
@@ -1,6 +1,6 @@
{% for e in entries %}
<h3><a href="{{ e.get_absolute_url }}">{{ e.headline }}</a></h3>
<p class="date">by <strong>{{ e.author }}</strong> on {{ e.pub_date|date:"M. j, Y" }}</p>
- {{ e.summary|safe }}
+ {{ e.summary_html|safe }}
<p class="more"><a href="{{ e.get_absolute_url }}">Read more</a></p>
{% endfor %}
Please sign in to comment.
Something went wrong with that request. Please try again.