Commit dba6f826 by benjaoming

Adding template tags, bootstrap front end, creation of first root article,…

Adding template tags, bootstrap front end, creation of first root article, template tags for rendering
parent 458bbd21
...@@ -42,6 +42,7 @@ setup( ...@@ -42,6 +42,7 @@ setup(
install_requires=[ install_requires=[
'Django>=1.4', 'Django>=1.4',
'markdown', 'markdown',
'django-sekizai',
'south', 'south',
], ],
classifiers=[ classifiers=[
......
...@@ -74,6 +74,19 @@ TEMPLATE_DIRS = ( ...@@ -74,6 +74,19 @@ TEMPLATE_DIRS = (
'templates', 'templates',
) )
TEMPLATE_CONTEXT_PROCESSORS =(
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.core.context_processors.tz',
'django.contrib.messages.context_processors.messages',
'sekizai.context_processors.sekizai',
)
INSTALLED_APPS = ( INSTALLED_APPS = (
'django.contrib.auth', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',
...@@ -84,6 +97,7 @@ INSTALLED_APPS = ( ...@@ -84,6 +97,7 @@ INSTALLED_APPS = (
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.admindocs', 'django.contrib.admindocs',
'south', 'south',
'sekizai',
'wiki', 'wiki',
'wiki.plugins.images', 'wiki.plugins.images',
'wiki.plugins.attachments', 'wiki.plugins.attachments',
......
#!virtualenv/bin/python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testproject.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
...@@ -23,8 +23,8 @@ class ArticleRevisionForm(forms.ModelForm): ...@@ -23,8 +23,8 @@ class ArticleRevisionForm(forms.ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(ArticleRevisionForm, self).__init__(*args, **kwargs) super(ArticleRevisionForm, self).__init__(*args, **kwargs)
EditorClass = get_callable(settings.EDITOR) EditorClass = get_callable(settings.EDITOR)
Editor = EditorClass(instance=self.instance) editor = EditorClass(instance=self.instance)
self.fields['content'].widget = Editor.get_admin_widget() self.fields['content'].widget = editor.get_admin_widget()
class ArticleRevisionAdmin(admin.ModelAdmin): class ArticleRevisionAdmin(admin.ModelAdmin):
form = ArticleRevisionForm form = ArticleRevisionForm
......
...@@ -21,6 +21,26 @@ class BaseEditor(): ...@@ -21,6 +21,26 @@ class BaseEditor():
css = {} css = {}
js = () js = ()
class Media:
css = {}
js = ()
class MarkItUpAdminWidget(forms.Widget):
"""A simplified more fail-safe widget for the backend"""
def __init__(self, attrs=None):
# The 'rows' and 'cols' attributes are required for HTML correctness.
default_attrs = {'class': 'markItUp',
'rows': '10', 'cols': '40',}
if attrs:
default_attrs.update(attrs)
super(MarkItUpAdminWidget, self).__init__(default_attrs)
def render(self, name, value, attrs=None):
if value is None: value = ''
final_attrs = self.build_attrs(attrs, name=name)
return mark_safe(u'<textarea%s>%s</textarea>' % (flatatt(final_attrs),
conditional_escape(force_unicode(value))))
class MarkItUpWidget(forms.Widget): class MarkItUpWidget(forms.Widget):
def __init__(self, attrs=None): def __init__(self, attrs=None):
# The 'rows' and 'cols' attributes are required for HTML correctness. # The 'rows' and 'cols' attributes are required for HTML correctness.
...@@ -40,8 +60,11 @@ class MarkItUp(BaseEditor): ...@@ -40,8 +60,11 @@ class MarkItUp(BaseEditor):
editor_id = 'markitup' editor_id = 'markitup'
def get_admin_widget(self, instance=None): def get_admin_widget(self, instance=None):
return MarkItUpWidget() return MarkItUpAdminWidget()
def get_widget(self, instance=None):
return MarkItUpWidget()
class AdminMedia: class AdminMedia:
css = { css = {
'all': ("wiki/markitup/skins/simple/style.css", 'all': ("wiki/markitup/skins/simple/style.css",
...@@ -51,3 +74,13 @@ class MarkItUp(BaseEditor): ...@@ -51,3 +74,13 @@ class MarkItUp(BaseEditor):
"wiki/markitup/jquery.markitup.js", "wiki/markitup/jquery.markitup.js",
"wiki/markitup/sets/admin/set.js", "wiki/markitup/sets/admin/set.js",
) )
class Media:
css = {
'all': ("wiki/markitup/skins/simple/style.css",
"wiki/markitup/sets/frontend/style.css",)
}
js = ("wiki/markitup/frontend.init.js",
"wiki/markitup/jquery.markitup.js",
"wiki/markitup/sets/frontend/set.js",
)
from django import forms
from django.utils.translation import ugettext as _
class CreateRoot(forms.Form):
title = forms.CharField(label=_(u'Title'), help_text=_(u'Initial title of the article. May be overridden with revision titles.'))
content = forms.CharField(label=_(u'Type in some contents'),
help_text=_(u'This is just the initial contents of your article. After creating it, you can use more complex features like adding plugins, meta data, related articles etc...'),
required=False)
...@@ -15,6 +15,9 @@ from urlpath import * ...@@ -15,6 +15,9 @@ from urlpath import *
if not 'mptt' in django_settings.INSTALLED_APPS: if not 'mptt' in django_settings.INSTALLED_APPS:
raise ImproperlyConfigured('django-wiki: needs mptt in INSTALLED_APPS') raise ImproperlyConfigured('django-wiki: needs mptt in INSTALLED_APPS')
if not 'sekizai' in django_settings.INSTALLED_APPS:
raise ImproperlyConfigured('django-wiki: needs sekizai in INSTALLED_APPS')
if not 'django.contrib.contenttypes' in django_settings.INSTALLED_APPS: if not 'django.contrib.contenttypes' in django_settings.INSTALLED_APPS:
raise ImproperlyConfigured('django-wiki: needs django.contrib.contenttypes in INSTALLED_APPS') raise ImproperlyConfigured('django-wiki: needs django.contrib.contenttypes in INSTALLED_APPS')
......
...@@ -6,7 +6,6 @@ from django.contrib.contenttypes import generic ...@@ -6,7 +6,6 @@ from django.contrib.contenttypes import generic
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from wiki.conf import settings from wiki.conf import settings
from wiki.core import exceptions
class Article(models.Model): class Article(models.Model):
...@@ -109,7 +108,7 @@ class Article(models.Model): ...@@ -109,7 +108,7 @@ class Article(models.Model):
has_parent_field = hasattr(obj, 'parent') has_parent_field = hasattr(obj, 'parent')
rel = ArticleForObject.objects.get_or_create(article=self, rel = ArticleForObject.objects.get_or_create(article=self,
content_type=content_type, content_type=content_type,
object_pk=obj.pk, object_id=obj.id,
has_parent_method=has_parent_field) has_parent_method=has_parent_field)
return rel return rel
......
...@@ -31,6 +31,7 @@ class URLPath(MPTTModel): ...@@ -31,6 +31,7 @@ class URLPath(MPTTModel):
@property @property
def path(self): def path(self):
if not self.parent: return ""
return "/".join([obj.slug for obj in self.get_ancestors(include_self=True)]) return "/".join([obj.slug for obj in self.get_ancestors(include_self=True)])
@classmethod @classmethod
...@@ -39,9 +40,9 @@ class URLPath(MPTTModel): ...@@ -39,9 +40,9 @@ class URLPath(MPTTModel):
root_nodes = cls.objects.root_nodes().filter(site=site) root_nodes = cls.objects.root_nodes().filter(site=site)
no_paths = root_nodes.count() no_paths = root_nodes.count()
if no_paths == 0: if no_paths == 0:
raise NoRootURL raise NoRootURL("You need to create a root article on site '%s'" % site)
if no_paths > 1: if no_paths > 1:
raise MultipleRootURLs raise MultipleRootURLs("Somehow you have multiple roots on %s" % site)
return root_nodes[0] return root_nodes[0]
class MPTTMeta: class MPTTMeta:
...@@ -101,13 +102,17 @@ class URLPath(MPTTModel): ...@@ -101,13 +102,17 @@ class URLPath(MPTTModel):
@classmethod @classmethod
def create_root(cls, site=None): def create_root(cls, site=None):
if not site: site = Site.objects.get_current() if not site: site = Site.objects.get_current()
if not cls.objects.root_nodes().filter(site=site): root_nodes = cls.objects.root_nodes().filter(site=site)
if not root_nodes:
# (get_or_create does not work for MPTT models??) # (get_or_create does not work for MPTT models??)
root = cls.objects.create(site=site) root = cls.objects.create(site=site)
article = Article() article = Article()
article.add_revision(ArticleRevision(), save=True) article.add_revision(ArticleRevision(), save=True)
article.add_object_relation(root) article.add_object_relation(root)
else:
root = root_nodes[0]
return root
@property @property
def article(self): def article(self):
try: try:
......
class Registry():
def __init__(self):
self._registry = []
def register(self, plugin_instance):
if not isinstance(plugin_instance, WikiPlugin):
raise TypeError("That's not a WikiPlugin")
self._registry.append(plugin_instance)
class WikiPlugin():
pass
\ No newline at end of file
from django.contrib import admin
import models
class AttachmentRevisionAdmin(admin.TabularInline):
model = models.AttachmentRevision
extra = 1
fields = ('file', 'user', 'user_message')
class AttachmentAdmin(admin.ModelAdmin):
inlines = [AttachmentRevisionAdmin]
# Do not let images be added in the admin. An image can only be added
# from the article admin due to the automatic revision system.
#def has_add_permission(self, request):
# return False
admin.site.register(models.Attachment, AttachmentAdmin)
\ No newline at end of file
...@@ -18,7 +18,11 @@ class Attachment(ReusablePlugin): ...@@ -18,7 +18,11 @@ class Attachment(ReusablePlugin):
blank=True, null=True, related_name='current_set', blank=True, null=True, related_name='current_set',
help_text=_(u'The revision of this attachment currently in use (on all articles using the attachment)'), help_text=_(u'The revision of this attachment currently in use (on all articles using the attachment)'),
) )
original_filename = models.CharField(max_length=256, verbose_name=_(u'original filename'), blank=True, null=True)
description = models.TextField(blank=True)
class Meta: class Meta:
verbose_name = _(u'attachment') verbose_name = _(u'attachment')
verbose_name_plural = _(u'attachments') verbose_name_plural = _(u'attachments')
...@@ -26,12 +30,26 @@ class Attachment(ReusablePlugin): ...@@ -26,12 +30,26 @@ class Attachment(ReusablePlugin):
def upload_path(instance, filename): def upload_path(instance, filename):
from os import path from os import path
try: try:
extension = filename.split(".")[-1] extension = filename.split(".")[-1]
except IndexError: except IndexError:
# No extension
raise IllegalFileExtension() raise IllegalFileExtension()
if not extension.lower() in map(lambda x: x.lower(), settings.FILE_EXTENTIONS):
# Must be an allowed extension
if not extension.lower() in map(lambda x: x.lower(), settings.FILE_EXTENSIONS):
raise IllegalFileExtension() raise IllegalFileExtension()
# Has to match original extension filename
if instance.attachment and instance.attachment.original_filename:
original_extension = ".".split(instance.attachment.original_filename)[-1]
if not extension.lower() == original_extension:
raise IllegalFileExtension("File extension has to be %s" % original_extension)
elif instance.attachment:
instance.attachment.original_filename = filename
upload_path = settings.UPLOAD_PATH upload_path = settings.UPLOAD_PATH
upload_path = upload_path.replace('%aid', str(instance.original_article.id)) upload_path = upload_path.replace('%aid', str(instance.original_article.id))
if settings.UPLOAD_PATH_OBSCURIFY: if settings.UPLOAD_PATH_OBSCURIFY:
...@@ -39,7 +57,7 @@ def upload_path(instance, filename): ...@@ -39,7 +57,7 @@ def upload_path(instance, filename):
m=hashlib.md5(str(random.randint(0,100000000000000))) m=hashlib.md5(str(random.randint(0,100000000000000)))
upload_path = path.join(upload_path, m.hexdigest()) upload_path = path.join(upload_path, m.hexdigest())
return path.join(upload_path, filename + '.upload') return path.join(upload_path, filename + '.upload')
class AttachmentRevision(BaseRevision): class AttachmentRevision(BaseRevision):
attachment = models.ForeignKey('Attachment') attachment = models.ForeignKey('Attachment')
...@@ -47,10 +65,6 @@ class AttachmentRevision(BaseRevision): ...@@ -47,10 +65,6 @@ class AttachmentRevision(BaseRevision):
file = models.FileField(upload_to=upload_path, #@ReservedAssignment file = models.FileField(upload_to=upload_path, #@ReservedAssignment
verbose_name=_(u'file')) verbose_name=_(u'file'))
original_filename = models.CharField(max_length=256, verbose_name=_(u'original filename'))
overwritten = models.BooleanField(default=False)
class Meta: class Meta:
verbose_name = _(u'attachment revision') verbose_name = _(u'attachment revision')
verbose_name_plural = _(u'attachment revisions') verbose_name_plural = _(u'attachment revisions')
......
...@@ -12,4 +12,4 @@ UPLOAD_PATH_OBSCURIFY = getattr(django_settings, 'WIKI_UPLOAD_PATH_OBSCURIFY', T ...@@ -12,4 +12,4 @@ UPLOAD_PATH_OBSCURIFY = getattr(django_settings, 'WIKI_UPLOAD_PATH_OBSCURIFY', T
# No files are saved without appending ".upload" to the file to ensure that # No files are saved without appending ".upload" to the file to ensure that
# your web server never actually executes some script. # your web server never actually executes some script.
# Case insensitive. # Case insensitive.
FILE_EXTENTIONS = getattr(django_settings, 'WIKI_FILE_EXTENTIONS', ['pdf', 'doc', 'odt', 'docx', 'txt']) FILE_EXTENSIONS = getattr(django_settings, 'WIKI_FILE_EXTENSIONS', ['pdf', 'doc', 'odt', 'docx', 'txt'])
$(document).ready(function() {
$(".markItUp").markItUp(mySettings);
});
Markup language:
Markdown
Description:
A basic Markdown markup set with Headings, Bold, Italic, Picture, Link, List, Quotes, Code, Preview button.
Install:
- Download the zip file
- Unzip it in your markItUp! sets folder
- Modify your JS link to point at this set.js
- Modify your CSS link to point at this style.css
\ No newline at end of file
// -------------------------------------------------------------------
// markItUp!
// -------------------------------------------------------------------
// Copyright (C) 2008 Jay Salvat
// http://markitup.jaysalvat.com/
// -------------------------------------------------------------------
// MarkDown tags example
// http://en.wikipedia.org/wiki/Markdown
// http://daringfireball.net/projects/markdown/
// -------------------------------------------------------------------
// Feel free to add more tags
// -------------------------------------------------------------------
mySettings = {
previewParserPath: '',
onShiftEnter: {keepDefault:false, openWith:'\n\n'},
markupSet: [
{name:'First Level Heading', key:'1', placeHolder:'Your title here...', closeWith:function(markItUp) { return miu.markdownTitle(markItUp, '=') } },
{name:'Second Level Heading', key:'2', placeHolder:'Your title here...', closeWith:function(markItUp) { return miu.markdownTitle(markItUp, '-') } },
{name:'Heading 3', key:'3', openWith:'### ', placeHolder:'Your title here...' },
{name:'Heading 4', key:'4', openWith:'#### ', placeHolder:'Your title here...' },
{name:'Heading 5', key:'5', openWith:'##### ', placeHolder:'Your title here...' },
{name:'Heading 6', key:'6', openWith:'###### ', placeHolder:'Your title here...' },
{separator:'---------------' },
{name:'Bold', key:'B', openWith:'**', closeWith:'**'},
{name:'Italic', key:'I', openWith:'_', closeWith:'_'},
{separator:'---------------' },
{name:'Bulleted List', openWith:'- ' },
{name:'Numeric List', openWith:function(markItUp) {
return markItUp.line+'. ';
}},
{separator:'---------------' },
{name:'Picture', key:'P', replaceWith:'![[![Alternative text]!]]([![Url:!:http://]!] "[![Title]!]")'},
{name:'Link', key:'L', openWith:'[', closeWith:']([![Url:!:http://]!] "[![Title]!]")', placeHolder:'Your text to link here...' },
{separator:'---------------'},
{name:'Quotes', openWith:'> '},
{name:'Code Block / Code', openWith:'(!(\t|!|`)!)', closeWith:'(!(`)!)'},
{separator:'---------------'},
{name:'Preview', call:'preview', className:"preview"}
]
}
// mIu nameSpace to avoid conflict.
miu = {
markdownTitle: function(markItUp, char) {
heading = '';
n = $.trim(markItUp.selection||markItUp.placeHolder).length;
for(i = 0; i < n; i++) {
heading += char;
}
return '\n'+heading;
}
}
/* -------------------------------------------------------------------
// markItUp!
// By Jay Salvat - http://markitup.jaysalvat.com/
// ------------------------------------------------------------------*/
/*label[for=id_content] {float: none; clear: both; width: 100%; display: block;}*/
.markItUp {max-width: 600px; padding: 0; width: 100%;}
.markItUpContainer {}
.markItUp .markItUpButton1 a {
background-image:url(images/h1.png);
}
.markItUp .markItUpButton2 a {
background-image:url(images/h2.png);
}
.markItUp .markItUpButton3 a {
background-image:url(images/h3.png);
}
.markItUp .markItUpButton4 a {
background-image:url(images/h4.png);
}
.markItUp .markItUpButton5 a {
background-image:url(images/h5.png);
}
.markItUp .markItUpButton6 a {
background-image:url(images/h6.png);
}
.markItUp .markItUpButton7 a {
background-image:url(images/bold.png);
}
.markItUp .markItUpButton8 a {
background-image:url(images/italic.png);
}
.markItUp .markItUpButton9 a {
background-image:url(images/list-bullet.png);
}
.markItUp .markItUpButton10 a {
background-image:url(images/list-numeric.png);
}
.markItUp .markItUpButton11 a {
background-image:url(images/picture.png);
}
.markItUp .markItUpButton12 a {
background-image:url(images/link.png);
}
.markItUp .markItUpButton13 a {
background-image:url(images/quotes.png);
}
.markItUp .markItUpButton14 a {
background-image:url(images/code.png);
}
.markItUp .preview a {
background-image:url(images/preview.png);
}
{% extends "wiki/base.html" %}
{% load wiki_tags %}
{% block wiki_contents %}
{% block page-title %}{{ article.current_revision.title }}{% endblock %}
{% wiki_article urlpath %}
{% endblock %}
{% extends "wiki/base.html" %}
{% load wiki_tags i18n sekizai_tags %}
{% block page-title %}{% trans "Create root article" %}{% endblock %}
{% block wiki_contents %}
{% addtoblock "js" %}
{% for js in editor.Media.js %}
<script type="text/javascript" src="{{ STATIC_URL }}{{ js }}"></script>
{% endfor %}
{% endaddtoblock %}
{% addtoblock "css" %}
{% for media, srcs in editor.Media.css.items %}
{% for src in srcs %}
<link rel="stylesheet" media="{{ media }}" href="{{ STATIC_URL }}{{ src }}" />
{% endfor %}
{% endfor %}
{% endaddtoblock %}
<h1>{% trans "Congratulations!" %}</h1>
<p class="lead">
{% trans "You have django-wiki installed... but there are no articles. So it's time to create the first one, the root article. In the beginning, it will only be editable by administrators, but you can define permissions after." %}
</p>
<h2 class="page-header">{% trans "Root article" %}</h2>
<style type="text/css">
#id_title {font-size: 20px; padding: 10px; width: 400px;}
</style>
<form method="POST" class="form-horizontal">
{% wiki_form create_form %}
<div class="form-actions">
<input type="submit" name="save_changes" value="{% trans "Create root" %} &raquo;" class="btn btn-primary btn-large" />
</div>
</form>
{% endblock %}
{% load wiki_tags i18n cache %}
{% block wiki_contents %}
{% cache 500 article.current_revision %}
{{ article.render }}
{% endcache %}
{% endblock %}
{% load sekizai_tags %}<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{% block page-title %}{% endblock %} ~~ django-wiki ^_^</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="www.django-wiki.org">
<!-- Le styles -->
<link href="{{ STATIC_URL }}wiki/bootstrap/css/bootstrap.css" rel="stylesheet">
<style>
body {
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
}
</style>
<link href="{{ STATIC_URL }}wiki/bootstrap/css/bootstrap-responsive.css" rel="stylesheet">
<script src="{{ STATIC_URL }}wiki/js/jquery.min.js"></script>
{% render_block "css" %}
{% render_block "js" %}
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="{% url wiki:root %}">django-wiki</a>
<div class="nav-collapse">
<ul class="nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<div class="container">
{% block wiki_contents %}
<h1>Bootstrap starter template</h1>
<p>Use this document as a way to quick start any new project.<br> All you get is this message and a barebones HTML document.</p>
{% endblock %}
<footer style="margin: 50px 0">
<p>Powered by django-wiki: <a href="http://www.django-wiki.org">www.django-wiki.org</a></p>
<p>This is open source, <a href="http://www.gnu.org/licenses/quick-guide-gplv3.html">GPLv3</a>. <a href="https://github.com/benjaoming/django-wiki">Fork me on Github.</a></p>
</footer>
</div> <!-- /container -->
<!-- Le javascript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!--
<script src="{{ STATIC_URL }}wiki/bootstrap/js/bootstrap-transition.js"></script>
<script src="{{ STATIC_URL }}wiki/bootstrap/js/bootstrap-alert.js"></script>
<script src="{{ STATIC_URL }}wiki/bootstrap/js/bootstrap-modal.js"></script>
<script src="{{ STATIC_URL }}wiki/bootstrap/js/bootstrap-dropdown.js"></script>
<script src="{{ STATIC_URL }}wiki/bootstrap/js/bootstrap-scrollspy.js"></script>
<script src="{{ STATIC_URL }}wiki/bootstrap/js/bootstrap-tab.js"></script>
<script src="{{ STATIC_URL }}wiki/bootstrap/js/bootstrap-tooltip.js"></script>
<script src="{{ STATIC_URL }}wiki/bootstrap/js/bootstrap-popover.js"></script>
<script src="{{ STATIC_URL }}wiki/bootstrap/js/bootstrap-button.js"></script>
<script src="{{ STATIC_URL }}wiki/bootstrap/js/bootstrap-collapse.js"></script>
<script src="{{ STATIC_URL }}wiki/bootstrap/js/bootstrap-carousel.js"></script>
<script src="{{ STATIC_URL }}wiki/bootstrap/js/bootstrap-typeahead.js"></script>
-->
</body>
</html>
{% csrf_token %}
{% if form.non_field_errors %}
<div class="alert alert-block alert-error">
{% if form_error_title %}<h4 class="alert-heading">{{ form_error_title }}</h4>{% endif %}
<ul>
{{ form.non_field_errors|unordered_list }}
</ul>
</div>
{% endif %}
{% for field in form %}
{% if field.is_hidden %}
{{ field }}
{% else %}
<div id="div_{{ field.auto_id }}" class="clearfix control-group{% if field.errors %} error{% endif %}">
{% if field.label %}
<label for="{{ field.id_for_label }}" class="control-label {% if field.field.required %}requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
<div class="controls">
{{ field }}
{% if field.errors %}
{% for error in field.errors %}
<div id="error_{{ forloop.counter }}_{{ field.auto_id }}" class="help-block"><strong>{{ error }}</strong></div>
{% endfor %}
{% endif %}
{% if field.help_text %}
<p id="hint_{{ field.auto_id }}" class="help-block">{{ field.help_text|safe }}</p>
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
from django import template
from django.contrib.contenttypes.models import ContentType
from django.db.models import Model
from django.forms import BaseForm
register = template.Library()
from wiki import models
@register.inclusion_tag('wiki/article/render.html')
def wiki_article(obj):
if not isinstance(obj, Model):
raise TypeError("A Wiki article can only be associated to a Django Model instance, not %s" % type(obj))
content_type = ContentType.objects.get_for_model(obj)
try:
article = models.ArticleForObject.objects.get(content_type=content_type, object_id=obj.pk).article
except models.ArticleForObject.DoesNotExist:
article = None
return {
'obj': obj,
'article': article,
}
@register.inclusion_tag('wiki/includes/form.html', takes_context=True)
def wiki_form(context, form_obj):
if not isinstance(form_obj, BaseForm):
raise TypeError("Error including form, it's not a form, it's a %s" % type(form_obj))
return {
'form': form_obj,
}
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
from django.conf.urls.defaults import patterns, url from django.conf.urls.defaults import patterns, url
urlpatterns = patterns('', urlpatterns = patterns('',
url('^$', 'wiki.views.index', name='index'), url('^$', 'wiki.views.root', name='root'),
url('^create-root/$', 'wiki.views.root_create', name='root_create'),
url('(.*)', 'wiki.views.get_url', name='get_url'),
) )
def get_pattern(app_name="wiki", namespace="wiki"): def get_pattern(app_name="wiki", namespace="wiki"):
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.shortcuts import render_to_response from django.shortcuts import render_to_response, redirect
from django.template.context import RequestContext from django.template.context import RequestContext
from django.contrib.auth.decorators import permission_required
def index(request): import models
c = RequestContext(request) import forms
return render_to_response("wiki/index.html", c) from conf import settings
\ No newline at end of file from wiki.core.exceptions import NoRootURL
from django.core.urlresolvers import get_callable
def root(request):
try:
urlpath = models.URLPath.root()
except NoRootURL:
return redirect('wiki:root_create')
c = RequestContext(request, {'urlpath': urlpath})
return render_to_response("wiki/article.html", c)
@permission_required('wiki.add_article')
def root_create(request):
if request.method == 'POST':
create_form = forms.CreateRoot(request.POST)
if create_form.is_valid():
root = models.URLPath.create_root()
return redirect("wiki:root")
else:
create_form = forms.CreateRoot()
# Insert current editor
EditorClass = get_callable(settings.EDITOR)
editor = EditorClass()
create_form.fields['content'].widget = editor.get_widget()
c = RequestContext(request, {'create_form': create_form,
'editor': editor,})
return render_to_response("wiki/article/create_root.html", c)
def get_url(request, path):
path = models.URLPath.get_by_path(path)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment