kopia lustrzana https://github.com/rtts/django-simplecms
Replace CKEditor's RichTextField with MarkdownField
Because you should not store raw HTML in database tables!readwriteweb
rodzic
bd654f5103
commit
f9ea04662b
29
cms/admin.py
29
cms/admin.py
|
@ -1,29 +0,0 @@
|
||||||
from django.contrib import admin
|
|
||||||
from django.utils.text import Truncator
|
|
||||||
from django.utils.safestring import mark_safe
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
from .models import Config
|
|
||||||
|
|
||||||
class BasePageAdmin(admin.ModelAdmin):
|
|
||||||
prepopulated_fields = {'slug': ('title',)}
|
|
||||||
|
|
||||||
class BaseSectionAdmin(admin.ModelAdmin):
|
|
||||||
list_filter = [
|
|
||||||
('page', admin.RelatedOnlyFieldListFilter),
|
|
||||||
]
|
|
||||||
list_display = ['__str__', 'get_type_display']
|
|
||||||
|
|
||||||
@admin.register(Config)
|
|
||||||
class ConfigAdmin(admin.ModelAdmin):
|
|
||||||
list_display = ['__str__', 'get_content']
|
|
||||||
exclude = ['parameter']
|
|
||||||
|
|
||||||
def get_content(self, obj):
|
|
||||||
return mark_safe(Truncator(obj.content).words(50, html=True))
|
|
||||||
get_content.short_description = _('content')
|
|
||||||
|
|
||||||
def has_add_permission(self, request):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def has_delete_permission(self, *args, **kwargs):
|
|
||||||
return False
|
|
|
@ -1,11 +1,11 @@
|
||||||
# Generated by Django 3.0.1 on 2020-01-02 18:31
|
# Generated by Django 3.0.1 on 2020-01-02 20:41
|
||||||
|
|
||||||
import ckeditor.fields
|
|
||||||
import cms.models
|
import cms.models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import embed_video.fields
|
import embed_video.fields
|
||||||
|
import markdownfield.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -34,19 +34,6 @@ class Migration(migrations.Migration):
|
||||||
'swappable': 'CMS_PAGE_MODEL',
|
'swappable': 'CMS_PAGE_MODEL',
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
|
||||||
name='Config',
|
|
||||||
fields=[
|
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('parameter', models.PositiveIntegerField(choices=[(10, 'Footer')], unique=True)),
|
|
||||||
('content', ckeditor.fields.RichTextField(blank=True, verbose_name='content')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'verbose_name': 'configuration parameter',
|
|
||||||
'verbose_name_plural': 'configuration parameters',
|
|
||||||
'ordering': ['parameter'],
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Section',
|
name='Section',
|
||||||
fields=[
|
fields=[
|
||||||
|
@ -55,7 +42,8 @@ class Migration(migrations.Migration):
|
||||||
('position', models.PositiveIntegerField(blank=True, verbose_name='position')),
|
('position', models.PositiveIntegerField(blank=True, verbose_name='position')),
|
||||||
('title', cms.models.VarCharField(blank=True, verbose_name='title')),
|
('title', cms.models.VarCharField(blank=True, verbose_name='title')),
|
||||||
('color', models.PositiveIntegerField(choices=[(1, 'Wit')], default=1, verbose_name='color')),
|
('color', models.PositiveIntegerField(choices=[(1, 'Wit')], default=1, verbose_name='color')),
|
||||||
('content', ckeditor.fields.RichTextField(blank=True, verbose_name='content')),
|
('content', markdownfield.models.MarkdownField(blank=True, verbose_name='content')),
|
||||||
|
('content_rendered', markdownfield.models.RenderedMarkdownField(editable=False)),
|
||||||
('image', models.ImageField(blank=True, upload_to='', verbose_name='image')),
|
('image', models.ImageField(blank=True, upload_to='', verbose_name='image')),
|
||||||
('video', embed_video.fields.EmbedVideoField(blank=True, help_text='Paste a YouTube, Vimeo, or SoundCloud link', verbose_name='video')),
|
('video', embed_video.fields.EmbedVideoField(blank=True, help_text='Paste a YouTube, Vimeo, or SoundCloud link', verbose_name='video')),
|
||||||
('button_text', cms.models.VarCharField(blank=True, verbose_name='button text')),
|
('button_text', cms.models.VarCharField(blank=True, verbose_name='button text')),
|
||||||
|
|
|
@ -7,9 +7,10 @@ from django.urls import reverse
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.forms import TextInput, Select
|
from django.forms import TextInput, Select
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from ckeditor.fields import RichTextField
|
|
||||||
from embed_video.fields import EmbedVideoField
|
from embed_video.fields import EmbedVideoField
|
||||||
from polymorphic.models import PolymorphicModel
|
from polymorphic.models import PolymorphicModel
|
||||||
|
from markdownfield.models import MarkdownField, RenderedMarkdownField
|
||||||
|
from markdownfield.validators import VALIDATOR_NULL
|
||||||
|
|
||||||
from numberedmodel.models import NumberedModel
|
from numberedmodel.models import NumberedModel
|
||||||
|
|
||||||
|
@ -27,9 +28,9 @@ class VarCharChoiceField(models.TextField):
|
||||||
|
|
||||||
class BasePage(NumberedModel):
|
class BasePage(NumberedModel):
|
||||||
'''Abstract base model for pages'''
|
'''Abstract base model for pages'''
|
||||||
position = models.PositiveIntegerField(_('position'), blank=True)
|
|
||||||
title = VarCharField(_('title'))
|
|
||||||
slug = models.SlugField(_('slug'), help_text=_('A short identifier to use in URLs'), blank=True, unique=True)
|
slug = models.SlugField(_('slug'), help_text=_('A short identifier to use in URLs'), blank=True, unique=True)
|
||||||
|
title = VarCharField(_('title'))
|
||||||
|
position = models.PositiveIntegerField(_('position'), blank=True)
|
||||||
menu = models.BooleanField(_('visible in menu'), default=True)
|
menu = models.BooleanField(_('visible in menu'), default=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -52,11 +53,12 @@ class BaseSection(NumberedModel, PolymorphicModel):
|
||||||
'''Abstract base model for sections'''
|
'''Abstract base model for sections'''
|
||||||
TYPES = []
|
TYPES = []
|
||||||
page = models.ForeignKey(swapper.get_model_name('cms', 'Page'), verbose_name=_('page'), related_name='sections', on_delete=models.PROTECT)
|
page = models.ForeignKey(swapper.get_model_name('cms', 'Page'), verbose_name=_('page'), related_name='sections', on_delete=models.PROTECT)
|
||||||
type = VarCharChoiceField(_('section type'), default='', choices=TYPES)
|
type = VarCharChoiceField(_('type'), default='', choices=TYPES)
|
||||||
position = models.PositiveIntegerField(_('position'), blank=True)
|
|
||||||
title = VarCharField(_('title'), blank=True)
|
title = VarCharField(_('title'), blank=True)
|
||||||
|
position = models.PositiveIntegerField(_('position'), blank=True)
|
||||||
color = models.PositiveIntegerField(_('color'), default=1, choices=settings.SECTION_COLORS)
|
color = models.PositiveIntegerField(_('color'), default=1, choices=settings.SECTION_COLORS)
|
||||||
content = RichTextField(_('content'), blank=True)
|
content = MarkdownField(_('content'), rendered_field='content_rendered', validator=VALIDATOR_NULL, use_admin_editor=False, blank=True)
|
||||||
|
content_rendered = RenderedMarkdownField()
|
||||||
image = models.ImageField(_('image'), blank=True)
|
image = models.ImageField(_('image'), blank=True)
|
||||||
video = EmbedVideoField(_('video'), blank=True, help_text=_('Paste a YouTube, Vimeo, or SoundCloud link'))
|
video = EmbedVideoField(_('video'), blank=True, help_text=_('Paste a YouTube, Vimeo, or SoundCloud link'))
|
||||||
button_text = VarCharField(_('button text'), blank=True)
|
button_text = VarCharField(_('button text'), blank=True)
|
||||||
|
@ -88,19 +90,3 @@ class Section(BaseSection):
|
||||||
'''Swappable section model'''
|
'''Swappable section model'''
|
||||||
class Meta(BaseSection.Meta):
|
class Meta(BaseSection.Meta):
|
||||||
swappable = swapper.swappable_setting('cms', 'Section')
|
swappable = swapper.swappable_setting('cms', 'Section')
|
||||||
|
|
||||||
class Config(models.Model):
|
|
||||||
TYPES = [
|
|
||||||
(10, _('Footer')),
|
|
||||||
]
|
|
||||||
|
|
||||||
parameter = models.PositiveIntegerField(choices=TYPES, unique=True)
|
|
||||||
content = RichTextField(_('content'), blank=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "{}. {}".format(self.parameter, self.get_parameter_display())
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = _('configuration parameter')
|
|
||||||
verbose_name_plural = _('configuration parameters')
|
|
||||||
ordering = ['parameter']
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ $blue: #3573a8;
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
font-family: $font;
|
font-family: $font;
|
||||||
|
line-height: 1.33;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +18,16 @@ a {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
th, td {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
border-bottom: 2px solid black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a.button, button.button {
|
a.button, button.button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
@ -248,6 +259,10 @@ section.contactsection {
|
||||||
/* Form elements */
|
/* Form elements */
|
||||||
|
|
||||||
form.cms {
|
form.cms {
|
||||||
|
div.wrapper {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
div.global_error {
|
div.global_error {
|
||||||
border: 2px dotted red;
|
border: 2px dotted red;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
@ -263,7 +278,6 @@ form.cms {
|
||||||
border: 0.5px solid black;
|
border: 0.5px solid black;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
||||||
|
|
||||||
legend {
|
legend {
|
||||||
font-size: 1.15em;
|
font-size: 1.15em;
|
||||||
}
|
}
|
||||||
|
@ -272,10 +286,26 @@ form.cms {
|
||||||
div.formfield {
|
div.formfield {
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
font-size: 0;
|
clear: both;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
&#type, &#position, &#title, &#slug {
|
||||||
|
padding: 0 1em;
|
||||||
|
clear: none;
|
||||||
|
float: left;
|
||||||
|
display: inline-block;
|
||||||
|
width: 33%;
|
||||||
|
}
|
||||||
|
&#type, &#slug {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
&#title {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
&#position {
|
||||||
|
float: right;
|
||||||
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
div.formfield > * {
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
}
|
||||||
div.formfield.error {
|
div.formfield.error {
|
||||||
border: 2px dotted red;
|
border: 2px dotted red;
|
||||||
|
@ -323,13 +353,8 @@ form.cms {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
textarea {
|
||||||
div.django-ckeditor-widget {
|
height: 25em;
|
||||||
display: block !important;
|
|
||||||
}
|
|
||||||
div.cke_chrome {
|
|
||||||
box-sizing: border-box !important;
|
|
||||||
border: 1px solid #aaa !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=checkbox] {
|
input[type=checkbox] {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
html, body {
|
html, body {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
line-height: 1.33;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0; }
|
padding: 0; }
|
||||||
|
|
||||||
|
@ -9,6 +10,13 @@ a {
|
||||||
a:hover {
|
a:hover {
|
||||||
text-decoration: underline; }
|
text-decoration: underline; }
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse; }
|
||||||
|
table th, table td {
|
||||||
|
padding: 1em; }
|
||||||
|
table th {
|
||||||
|
border-bottom: 2px solid black; }
|
||||||
|
|
||||||
a.button, button.button {
|
a.button, button.button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
@ -174,6 +182,9 @@ section.contactsection textarea {
|
||||||
font-family: inherit; }
|
font-family: inherit; }
|
||||||
|
|
||||||
/* Form elements */
|
/* Form elements */
|
||||||
|
form.cms div.wrapper {
|
||||||
|
overflow: hidden; }
|
||||||
|
|
||||||
form.cms div.global_error {
|
form.cms div.global_error {
|
||||||
border: 2px dotted red;
|
border: 2px dotted red;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
@ -193,10 +204,21 @@ form.cms fieldset {
|
||||||
form.cms div.formfield {
|
form.cms div.formfield {
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
font-size: 0; }
|
clear: both;
|
||||||
|
box-sizing: border-box; }
|
||||||
form.cms div.formfield > * {
|
form.cms div.formfield#type, form.cms div.formfield#position, form.cms div.formfield#title, form.cms div.formfield#slug {
|
||||||
font-size: 1rem; }
|
padding: 0 1em;
|
||||||
|
clear: none;
|
||||||
|
float: left;
|
||||||
|
display: inline-block;
|
||||||
|
width: 33%; }
|
||||||
|
form.cms div.formfield#type, form.cms div.formfield#slug {
|
||||||
|
padding-left: 0; }
|
||||||
|
form.cms div.formfield#title {
|
||||||
|
padding: 0; }
|
||||||
|
form.cms div.formfield#position {
|
||||||
|
float: right;
|
||||||
|
padding-right: 0; }
|
||||||
|
|
||||||
form.cms div.formfield.error {
|
form.cms div.formfield.error {
|
||||||
border: 2px dotted red;
|
border: 2px dotted red;
|
||||||
|
@ -237,12 +259,8 @@ form.cms input, form.cms select, form.cms textarea {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 5px; }
|
padding: 5px; }
|
||||||
|
|
||||||
form.cms div.django-ckeditor-widget {
|
form.cms textarea {
|
||||||
display: block !important; }
|
height: 25em; }
|
||||||
|
|
||||||
form.cms div.cke_chrome {
|
|
||||||
box-sizing: border-box !important;
|
|
||||||
border: 1px solid #aaa !important; }
|
|
||||||
|
|
||||||
form.cms input[type=checkbox] {
|
form.cms input[type=checkbox] {
|
||||||
width: auto; }
|
width: auto; }
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -22,7 +22,7 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{% block formset %}
|
{% if formset %}
|
||||||
{{formset.management_form}}
|
{{formset.management_form}}
|
||||||
{% for form in formset %}
|
{% for form in formset %}
|
||||||
{{form.media}}
|
{{form.media}}
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{% endblock %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="edit page">
|
<div class="edit page">
|
||||||
<button>{% trans 'save' %}</button>
|
<button>{% trans 'save' %}</button>
|
||||||
|
@ -74,6 +74,9 @@
|
||||||
slugfield.value = URLify(titlefield.value);
|
slugfield.value = URLify(titlefield.value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
slugfield.addEventListener('input', function(event) {
|
||||||
|
virgin = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if section.content %}
|
{% if section.content_rendered %}
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{{section.content|safe}}
|
{{section.content_rendered|safe}}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
10
cms/utils.py
10
cms/utils.py
|
@ -1,10 +0,0 @@
|
||||||
from .models import Config
|
|
||||||
|
|
||||||
def get_config(parameter):
|
|
||||||
'''Gets or creates the requested parameter.
|
|
||||||
|
|
||||||
'''
|
|
||||||
if parameter not in [t[0] for t in Config.TYPES]:
|
|
||||||
raise ValueError('Invalid configuration parameter requested')
|
|
||||||
(c, created) = Config.objects.get_or_create(parameter=parameter)
|
|
||||||
return c.content
|
|
|
@ -12,7 +12,6 @@ from django.http import HttpResponseRedirect, HttpResponseBadRequest
|
||||||
|
|
||||||
from .decorators import register_view
|
from .decorators import register_view
|
||||||
from .forms import PageForm, SectionForm
|
from .forms import PageForm, SectionForm
|
||||||
from .utils import get_config
|
|
||||||
|
|
||||||
Page = swapper.load_model('cms', 'Page')
|
Page = swapper.load_model('cms', 'Page')
|
||||||
Section = swapper.load_model('cms', 'Section')
|
Section = swapper.load_model('cms', 'Section')
|
||||||
|
@ -59,14 +58,12 @@ class SectionWithFormView(SectionView):
|
||||||
return section
|
return section
|
||||||
|
|
||||||
class MenuMixin:
|
class MenuMixin:
|
||||||
'''Add pages and footer to template context'''
|
'''Add pages to template context'''
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
pages = Page.objects.filter(menu=True)
|
pages = Page.objects.filter(menu=True)
|
||||||
footer = get_config(10)
|
|
||||||
context.update({
|
context.update({
|
||||||
'pages': pages,
|
'pages': pages,
|
||||||
'footer': footer,
|
|
||||||
})
|
})
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# Generated by Django 3.0.1 on 2020-01-02 18:31
|
# Generated by Django 3.0.1 on 2020-01-02 20:42
|
||||||
|
|
||||||
import ckeditor.fields
|
|
||||||
import cms.models
|
import cms.models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import embed_video.fields
|
import embed_video.fields
|
||||||
|
import markdownfield.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -13,8 +13,8 @@ class Migration(migrations.Migration):
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('contenttypes', '0002_remove_content_type_name'),
|
|
||||||
migrations.swappable_dependency(settings.CMS_PAGE_MODEL),
|
migrations.swappable_dependency(settings.CMS_PAGE_MODEL),
|
||||||
|
('contenttypes', '0002_remove_content_type_name'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -42,7 +42,8 @@ class Migration(migrations.Migration):
|
||||||
('position', models.PositiveIntegerField(blank=True, verbose_name='position')),
|
('position', models.PositiveIntegerField(blank=True, verbose_name='position')),
|
||||||
('title', cms.models.VarCharField(blank=True, verbose_name='title')),
|
('title', cms.models.VarCharField(blank=True, verbose_name='title')),
|
||||||
('color', models.PositiveIntegerField(choices=[(1, 'Wit')], default=1, verbose_name='color')),
|
('color', models.PositiveIntegerField(choices=[(1, 'Wit')], default=1, verbose_name='color')),
|
||||||
('content', ckeditor.fields.RichTextField(blank=True, verbose_name='content')),
|
('content', markdownfield.models.MarkdownField(blank=True, verbose_name='content')),
|
||||||
|
('content_rendered', markdownfield.models.RenderedMarkdownField(editable=False)),
|
||||||
('image', models.ImageField(blank=True, upload_to='', verbose_name='image')),
|
('image', models.ImageField(blank=True, upload_to='', verbose_name='image')),
|
||||||
('video', embed_video.fields.EmbedVideoField(blank=True, help_text='Paste a YouTube, Vimeo, or SoundCloud link', verbose_name='video')),
|
('video', embed_video.fields.EmbedVideoField(blank=True, help_text='Paste a YouTube, Vimeo, or SoundCloud link', verbose_name='video')),
|
||||||
('button_text', cms.models.VarCharField(blank=True, verbose_name='button text')),
|
('button_text', cms.models.VarCharField(blank=True, verbose_name='button text')),
|
||||||
|
|
|
@ -7,6 +7,7 @@ except ImportError:
|
||||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||||
|
|
||||||
PROJECT_NAME = 'example'
|
PROJECT_NAME = 'example'
|
||||||
|
SITE_URL = 'https://example.com/'
|
||||||
KEYFILE = f'/tmp/{PROJECT_NAME}.secret'
|
KEYFILE = f'/tmp/{PROJECT_NAME}.secret'
|
||||||
ADMINS = [('JJ Vens', 'jj@rtts.eu')]
|
ADMINS = [('JJ Vens', 'jj@rtts.eu')]
|
||||||
ALLOWED_HOSTS = ['*']
|
ALLOWED_HOSTS = ['*']
|
||||||
|
@ -23,6 +24,8 @@ MEDIA_URL = '/media/'
|
||||||
MEDIA_ROOT = '/srv/' + PROJECT_NAME + '/media'
|
MEDIA_ROOT = '/srv/' + PROJECT_NAME + '/media'
|
||||||
LOGIN_REDIRECT_URL = '/'
|
LOGIN_REDIRECT_URL = '/'
|
||||||
CMS_SECTION_MODEL = 'app.Section'
|
CMS_SECTION_MODEL = 'app.Section'
|
||||||
|
MARKDOWN_EXTENSIONS = ['extra', 'smarty']
|
||||||
|
MARKDOWN_EXTENSION_CONFIGS = {'extra': {}, 'smarty': {}}
|
||||||
|
|
||||||
def read(file):
|
def read(file):
|
||||||
with open(file) as f:
|
with open(file) as f:
|
||||||
|
@ -36,34 +39,10 @@ except IOError:
|
||||||
SECRET_KEY = ''.join(random.choice(string.printable) for x in range(50))
|
SECRET_KEY = ''.join(random.choice(string.printable) for x in range(50))
|
||||||
write(KEYFILE, SECRET_KEY)
|
write(KEYFILE, SECRET_KEY)
|
||||||
|
|
||||||
SECTION_TYPES = [
|
|
||||||
('TextSection', 'Tekst'),
|
|
||||||
('ImageSection', 'Afbeelding'),
|
|
||||||
]
|
|
||||||
|
|
||||||
SECTION_COLORS = [
|
SECTION_COLORS = [
|
||||||
(1, 'Wit'),
|
(1, 'Wit'),
|
||||||
]
|
]
|
||||||
|
|
||||||
CKEDITOR_CONFIGS = {
|
|
||||||
'default': {
|
|
||||||
'removePlugins': 'elementspath',
|
|
||||||
'extraPlugins': 'format',
|
|
||||||
'width': '100%',
|
|
||||||
'toolbar': 'Custom',
|
|
||||||
# 'contentsCss': STATIC_URL + 'ckeditor.css',
|
|
||||||
# 'allowedContent': True, # this allows iframes, embeds, scripts, etc...
|
|
||||||
'toolbar_Custom': [
|
|
||||||
['Format'],
|
|
||||||
['Bold', 'Italic', 'Underline', 'TextColor'],
|
|
||||||
['NumberedList', 'BulletedList', 'Blockquote'],
|
|
||||||
['JustifyLeft', 'JustifyCenter', 'JustifyRight'],
|
|
||||||
['Link', 'Unlink'],
|
|
||||||
['RemoveFormat', 'Source'],
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
'app',
|
'app',
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
|
@ -74,7 +53,6 @@ INSTALLED_APPS = [
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
'cms',
|
'cms',
|
||||||
'simplesass',
|
'simplesass',
|
||||||
'ckeditor',
|
|
||||||
'polymorphic',
|
'polymorphic',
|
||||||
'embed_video',
|
'embed_video',
|
||||||
'easy_thumbnails',
|
'easy_thumbnails',
|
||||||
|
|
5
setup.py
5
setup.py
|
@ -3,7 +3,7 @@ from setuptools import setup, find_packages
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name = 'django-simplecms',
|
name = 'django-simplecms',
|
||||||
version = '2.1.0',
|
version = '2.2.0',
|
||||||
url = 'https://github.com/rtts/django-simplecms',
|
url = 'https://github.com/rtts/django-simplecms',
|
||||||
author = 'Jaap Joris Vens',
|
author = 'Jaap Joris Vens',
|
||||||
author_email = 'jj@rtts.eu',
|
author_email = 'jj@rtts.eu',
|
||||||
|
@ -13,12 +13,13 @@ setup(
|
||||||
include_package_data = True,
|
include_package_data = True,
|
||||||
install_requires = [
|
install_requires = [
|
||||||
'django',
|
'django',
|
||||||
'django-ckeditor',
|
|
||||||
'django-extensions',
|
'django-extensions',
|
||||||
'django-embed-video',
|
'django-embed-video',
|
||||||
'django-polymorphic',
|
'django-polymorphic',
|
||||||
|
'django-markdownfield',
|
||||||
'easy-thumbnails',
|
'easy-thumbnails',
|
||||||
'psycopg2',
|
'psycopg2',
|
||||||
|
'markdown',
|
||||||
'libsass',
|
'libsass',
|
||||||
'swapper',
|
'swapper',
|
||||||
],
|
],
|
||||||
|
|
Ładowanie…
Reference in New Issue