kopia lustrzana https://github.com/rtts/django-simplecms
Properly sort out pre-commit hook handling
What this means is that the source code of SimpleCMS now passes all the the pre-commit hooks, and that the code generated by `simplecms` _also_ passes all the pre-commit hooks.main
rodzic
924031f3ac
commit
74c896b86e
|
@ -1,7 +1,7 @@
|
||||||
repos:
|
repos:
|
||||||
|
|
||||||
- repo: https://github.com/rtts/djhtml
|
- repo: https://github.com/rtts/djhtml
|
||||||
rev: v1.4.9
|
rev: v1.4.11
|
||||||
hooks:
|
hooks:
|
||||||
- id: djhtml
|
- id: djhtml
|
||||||
|
|
||||||
|
@ -12,16 +12,17 @@ repos:
|
||||||
args: ['--in-place', '--remove-all-unused-imports']
|
args: ['--in-place', '--remove-all-unused-imports']
|
||||||
|
|
||||||
- repo: https://github.com/pycqa/isort
|
- repo: https://github.com/pycqa/isort
|
||||||
rev: 5.9.1
|
rev: 5.10.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
|
args: ['--resolve-all-configs', '--line-length', '88']
|
||||||
- repo: https://github.com/pycqa/flake8
|
|
||||||
rev: 3.9.2
|
|
||||||
hooks:
|
|
||||||
- id: flake8
|
|
||||||
|
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 21.6b0
|
rev: 21.12b0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
|
|
||||||
|
- repo: https://github.com/pycqa/flake8
|
||||||
|
rev: 4.0.1
|
||||||
|
hooks:
|
||||||
|
- id: flake8
|
||||||
|
|
16
README.md
16
README.md
|
@ -45,8 +45,8 @@ Here's an example `views.py` of an app using SimpleCMS:
|
||||||
And here is the contents of `hello.html`:
|
And here is the contents of `hello.html`:
|
||||||
|
|
||||||
<section type="helloworld">
|
<section type="helloworld">
|
||||||
<h1>{{message}}</h1>
|
<h1>{{ message }}</h1>
|
||||||
{{section.content}}
|
{{ section.content }}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
Everytime a section needs to be rendered, SimpleCMS will call the
|
Everytime a section needs to be rendered, SimpleCMS will call the
|
||||||
|
@ -72,17 +72,7 @@ SimpleCMS includes a variety of useful template tags, default *Page*
|
||||||
and *Section* models, and all the other boilerplate code needed for
|
and *Section* models, and all the other boilerplate code needed for
|
||||||
new projects.
|
new projects.
|
||||||
|
|
||||||
One notable inclusion is the `eval` template tag. It will pass its
|
|
||||||
argument first through Django's templating system and then through
|
|
||||||
Markdown, making for instance the following possible. (Disclaimer: use
|
|
||||||
with caution!)
|
|
||||||
|
|
||||||
Welcome to **{% now 'Y' %}!**
|
|
||||||
|
|
||||||
Another useful feature is the automatic compilation of `SCSS` files to
|
|
||||||
`CSS` files using a custom middleware.
|
|
||||||
|
|
||||||
## Feedback and support
|
## Feedback and support
|
||||||
|
|
||||||
We would love to hear from you! Feel free to [open an
|
We would love to hear from you! Feel free to [open an
|
||||||
issue](../../issues) or [send us an email](mailto:jj+cms@rtts.eu).
|
issue](../../issues) or [send us an email](mailto:cms@jj.rtts.eu).
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
__version__ = "1.0.6"
|
__version__ = "1.0.7"
|
||||||
default_app_config = "cms.apps.CmsConfig"
|
default_app_config = "cms.apps.CmsConfig"
|
||||||
|
|
|
@ -36,11 +36,17 @@ def create_project(project_name, project_dir):
|
||||||
line = f"django-simplecms=={cms.__version__}"
|
line = f"django-simplecms=={cms.__version__}"
|
||||||
print(line, file=f)
|
print(line, file=f)
|
||||||
|
|
||||||
shutil.copytree(
|
example_dir = os.path.dirname(example.__file__)
|
||||||
os.path.dirname(example.__file__),
|
app_dir = os.path.join(project_dir, project_name)
|
||||||
os.path.join(project_dir, project_name),
|
shutil.copytree(example_dir, app_dir, dirs_exist_ok=True)
|
||||||
dirs_exist_ok=True,
|
shutil.move(
|
||||||
|
os.path.join(app_dir, "setup.cfg"), os.path.join(project_dir, "setup.cfg")
|
||||||
)
|
)
|
||||||
|
shutil.move(
|
||||||
|
os.path.join(app_dir, ".pre-commit-config.yaml"),
|
||||||
|
os.path.join(project_dir, ".pre-commit-config.yaml"),
|
||||||
|
)
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
os.open(
|
os.open(
|
||||||
os.path.join(project_dir, "manage.py"), os.O_CREAT | os.O_WRONLY, 0o755
|
os.path.join(project_dir, "manage.py"), os.O_CREAT | os.O_WRONLY, 0o755
|
||||||
|
@ -48,36 +54,40 @@ def create_project(project_name, project_dir):
|
||||||
"w",
|
"w",
|
||||||
) as f:
|
) as f:
|
||||||
print(
|
print(
|
||||||
"#!/usr/bin/env python",
|
f"""#!/usr/bin/env python
|
||||||
"import os, sys",
|
import os
|
||||||
f"os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{project_name}.settings')",
|
import sys
|
||||||
"from django.core.management import execute_from_command_line",
|
|
||||||
"execute_from_command_line(sys.argv)",
|
from django.core.management import execute_from_command_line
|
||||||
sep="\n",
|
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{project_name}.settings")
|
||||||
|
execute_from_command_line(sys.argv)""",
|
||||||
file=f,
|
file=f,
|
||||||
)
|
)
|
||||||
with open(os.path.join(project_dir, project_name, "wsgi.py"), "w") as f:
|
with open(os.path.join(project_dir, project_name, "wsgi.py"), "w") as f:
|
||||||
print(
|
print(
|
||||||
"import os",
|
f"""import os
|
||||||
"from django.core.wsgi import get_wsgi_application",
|
|
||||||
f"os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{project_name}.settings')",
|
from django.core.wsgi import get_wsgi_application
|
||||||
"application = get_wsgi_application()",
|
|
||||||
sep="\n",
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{project_name}.settings")
|
||||||
|
application = get_wsgi_application()""",
|
||||||
file=f,
|
file=f,
|
||||||
)
|
)
|
||||||
with open(os.path.join(project_dir, ".gitignore"), "w") as f:
|
with open(os.path.join(project_dir, ".gitignore"), "w") as f:
|
||||||
print("*.pyc\n__pycache__/", file=f)
|
print("*.pyc\n__pycache__/", file=f)
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f'Successfully created project "{project_name}"',
|
f"""
|
||||||
"",
|
Successfully created project "{project_name}"
|
||||||
"Things to do next:",
|
|
||||||
"- create a database",
|
Things to do next:
|
||||||
"- ./manage.py makemigrations",
|
- create a database
|
||||||
"- ./manage.py migrate",
|
- ./manage.py makemigrations
|
||||||
"- ./manage.py createsuperuser",
|
- ./manage.py migrate
|
||||||
"- ./manage.py runserver",
|
- ./manage.py createsuperuser
|
||||||
sep="\n",
|
- ./manage.py runserver
|
||||||
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,17 @@
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="{% get_current_language as lang%}{{lang}}">
|
<html lang="{% get_current_language as lang%}{{lang}}">
|
||||||
<head>
|
<head>
|
||||||
<title>{% block title %}{% endblock %}</title>
|
<title>{% block title %}{% endblock %}</title>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="{% static 'cms/admin.scss.css' %}">
|
<link rel="stylesheet" href="{% static 'cms/admin.scss.css' %}">
|
||||||
{% block extrahead %}{% endblock %}
|
{% block extrahead %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extrabody %}{% endblock %}
|
{% block extrabody %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -4,113 +4,113 @@
|
||||||
{% block title %}{% trans 'Edit' %} {{form.instance}}{% endblock %}
|
{% block title %}{% trans 'Edit' %} {{form.instance}}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form method="POST" enctype="multipart/form-data" class="cms" novalidate>
|
<form method="POST" enctype="multipart/form-data" class="cms" novalidate>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
{% if form.errors %}
|
{% if form.errors %}
|
||||||
<div class="global_error">
|
<div class="global_error">
|
||||||
{% trans 'Please correct the error(s) below and save again' %}
|
{% trans 'Please correct the error(s) below and save again' %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% include 'cms/form.html' %}
|
||||||
|
|
||||||
|
<div class="edit page">
|
||||||
|
<button><img src="{% static 'cms/save.png' %}" width="75"></button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
</form>
|
||||||
|
|
||||||
{% include 'cms/form.html' %}
|
|
||||||
|
|
||||||
<div class="edit page">
|
|
||||||
<button><img src="{% static 'cms/save.png' %}" width="75"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extrabody %}
|
{% block extrabody %}
|
||||||
<script type="text/javascript" src="/static/admin/js/urlify.js"></script>
|
<script type="text/javascript" src="/static/admin/js/urlify.js"></script>
|
||||||
<script>
|
<script>
|
||||||
function addForm(node) {
|
function addForm(node) {
|
||||||
let base = node.previousElementSibling;
|
let base = node.previousElementSibling;
|
||||||
let parent = node.parentNode;
|
let parent = node.parentNode;
|
||||||
let counter = parent.firstElementChild;
|
let counter = parent.firstElementChild;
|
||||||
let extra_form = base.cloneNode(true);
|
let extra_form = base.cloneNode(true);
|
||||||
let prefix = extra_form.id
|
let prefix = extra_form.id
|
||||||
|
|
||||||
increment(extra_form, prefix, 'id');
|
increment(extra_form, prefix, 'id');
|
||||||
for (let el of extra_form.querySelectorAll(`*[id^=${prefix}]`)) {
|
for (let el of extra_form.querySelectorAll(`*[id^=${prefix}]`)) {
|
||||||
increment(el, prefix, 'id');
|
increment(el, prefix, 'id');
|
||||||
}
|
}
|
||||||
for (let el of extra_form.querySelectorAll(`*[name^=${prefix}]`)) {
|
for (let el of extra_form.querySelectorAll(`*[name^=${prefix}]`)) {
|
||||||
increment(el, prefix, 'name');
|
increment(el, prefix, 'name');
|
||||||
}
|
}
|
||||||
for (let el of extra_form.querySelectorAll(`*[id^=id_${prefix}]`)) {
|
for (let el of extra_form.querySelectorAll(`*[id^=id_${prefix}]`)) {
|
||||||
increment(el, 'id_' + prefix, 'id');
|
increment(el, 'id_' + prefix, 'id');
|
||||||
}
|
}
|
||||||
for (let el of extra_form.querySelectorAll(`*[for^=id_${prefix}]`)) {
|
for (let el of extra_form.querySelectorAll(`*[for^=id_${prefix}]`)) {
|
||||||
increment(el, 'id_' + prefix, 'for');
|
increment(el, 'id_' + prefix, 'for');
|
||||||
}
|
}
|
||||||
for (let el of extra_form.querySelectorAll(`*[id^=formfield_${prefix}]`)) {
|
for (let el of extra_form.querySelectorAll(`*[id^=formfield_${prefix}]`)) {
|
||||||
increment(el, 'formfield_' + prefix, 'id');
|
increment(el, 'formfield_' + prefix, 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
node.remove();
|
||||||
|
parent.appendChild(extra_form);
|
||||||
|
parent.appendChild(node);
|
||||||
|
base.hidden = false;
|
||||||
|
counter.value = parseInt(counter.value) + 1;
|
||||||
|
setEventHandlers();
|
||||||
|
resizeTextareas();
|
||||||
}
|
}
|
||||||
|
|
||||||
node.remove();
|
function increment(node, prefix, attr) {
|
||||||
parent.appendChild(extra_form);
|
let re = RegExp(`${prefix}(.*)`);
|
||||||
parent.appendChild(node);
|
let matches = node.getAttribute(attr).match(re);
|
||||||
base.hidden = false;
|
if (matches) {
|
||||||
counter.value = parseInt(counter.value) + 1;
|
let suffix = matches[1];
|
||||||
setEventHandlers();
|
let name = prefix.replace(/-\d+$/, '');
|
||||||
resizeTextareas();
|
let index = parseInt(prefix.replace(/.*-/, ''));
|
||||||
}
|
index++;
|
||||||
|
let new_prefix = `${name}-${index}`;
|
||||||
function increment(node, prefix, attr) {
|
node.setAttribute(attr, new_prefix + suffix);
|
||||||
let re = RegExp(`${prefix}(.*)`);
|
|
||||||
let matches = node.getAttribute(attr).match(re);
|
|
||||||
if (matches) {
|
|
||||||
let suffix = matches[1];
|
|
||||||
let name = prefix.replace(/-\d+$/, '');
|
|
||||||
let index = parseInt(prefix.replace(/.*-/, ''));
|
|
||||||
index++;
|
|
||||||
let new_prefix = `${name}-${index}`;
|
|
||||||
node.setAttribute(attr, new_prefix + suffix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resizeTextareas() {
|
|
||||||
let tx = document.getElementsByTagName('textarea');
|
|
||||||
for (let i = 0; i < tx.length; i++) {
|
|
||||||
tx[i].style.height = (tx[i].scrollHeight) + 1 + 'px';
|
|
||||||
tx[i].addEventListener('input', function() {
|
|
||||||
this.style.height = (this.scrollHeight) + 1 + 'px'; // why the 1???
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function showRelevantFields(form, type) {
|
|
||||||
let fields_per_type = {{fields_per_type|safe}};
|
|
||||||
for (let field of form.querySelectorAll(`fieldset#${form.id} > div.formfield`)) {
|
|
||||||
if (!field.id.endsWith('DELETE')) {
|
|
||||||
field.hidden = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let name of fields_per_type[type]) {
|
|
||||||
document.getElementById(`formfield_${form.id}-${name}`).hidden = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setEventHandlers() {
|
function resizeTextareas() {
|
||||||
for (let typefield of document.querySelectorAll('select[name$=-type]')) {
|
let tx = document.getElementsByTagName('textarea');
|
||||||
let formId = typefield.name.replace(/-type$/, '');
|
for (let i = 0; i < tx.length; i++) {
|
||||||
let form = document.getElementById(formId);
|
tx[i].style.height = (tx[i].scrollHeight) + 1 + 'px';
|
||||||
let type = typefield.value.toLowerCase();
|
tx[i].addEventListener('input', function() {
|
||||||
showRelevantFields(form, type);
|
this.style.height = (this.scrollHeight) + 1 + 'px'; // why the 1???
|
||||||
typefield.addEventListener('input', function() {
|
});
|
||||||
type = typefield.value.toLowerCase();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showRelevantFields(form, type) {
|
||||||
|
let fields_per_type = {{fields_per_type|safe}};
|
||||||
|
for (let field of form.querySelectorAll(`fieldset#${form.id} > div.formfield`)) {
|
||||||
|
if (!field.id.endsWith('DELETE')) {
|
||||||
|
field.hidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let name of fields_per_type[type]) {
|
||||||
|
document.getElementById(`formfield_${form.id}-${name}`).hidden = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setEventHandlers() {
|
||||||
|
for (let typefield of document.querySelectorAll('select[name$=-type]')) {
|
||||||
|
let formId = typefield.name.replace(/-type$/, '');
|
||||||
|
let form = document.getElementById(formId);
|
||||||
|
let type = typefield.value.toLowerCase();
|
||||||
showRelevantFields(form, type);
|
showRelevantFields(form, type);
|
||||||
resizeTextareas();
|
typefield.addEventListener('input', function() {
|
||||||
});
|
type = typefield.value.toLowerCase();
|
||||||
|
showRelevantFields(form, type);
|
||||||
|
resizeTextareas();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function(event) {
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
setEventHandlers();
|
setEventHandlers();
|
||||||
resizeTextareas();
|
resizeTextareas();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
|
||||||
<fieldset id="{{form.prefix}}" class="form" {% if forloop.last %}hidden{% endif %}>
|
<fieldset id="{{form.prefix}}" class="form" {% if forloop.last %}hidden{% endif %}>
|
||||||
{{form.media}}
|
{{form.media}}
|
||||||
{% for field in form.hidden_fields %}
|
{% for field in form.hidden_fields %}
|
||||||
{{field}}
|
{{field}}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% for field in form.visible_fields %}
|
{% for field in form.visible_fields %}
|
||||||
{% include 'cms/formfield.html' with field=field %}
|
{% include 'cms/formfield.html' with field=field %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% for formset in form.formsets %}
|
{% for formset in form.formsets %}
|
||||||
<div class="formfield {{formset.name}}" id="formfield_{{formset.prefix}}">
|
<div class="formfield {{formset.name}}" id="formfield_{{formset.prefix}}">
|
||||||
{{formset.management_form}}
|
{{formset.management_form}}
|
||||||
{% for form in formset %}
|
{% for form in formset %}
|
||||||
{% include 'cms/form.html' %}
|
{% include 'cms/form.html' %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<img onclick="addForm(this, '{{formset.prefix}}')" src="{% static 'cms/add.png' %}" width="75">
|
<img onclick="addForm(this, '{{formset.prefix}}')" src="{% static 'cms/add.png' %}" width="75">
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
{% if field.name == 'DELETE' and not form.instance.pk %}
|
{% if field.name == 'DELETE' and not form.instance.pk %}
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="formfield {{field.name}}{% if field.errors %} error{% endif %}" id="formfield_{{field.html_name}}">
|
<div class="formfield {{field.name}}{% if field.errors %} error{% endif %}" id="formfield_{{field.html_name}}">
|
||||||
|
|
||||||
{% if field.errors %}
|
{% if field.errors %}
|
||||||
<div class="errors">
|
<div class="errors">
|
||||||
{{field.errors}}
|
{{field.errors}}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if field.field.widget.input_type == 'checkbox' %}
|
{% if field.field.widget.input_type == 'checkbox' %}
|
||||||
<div class="input">
|
<div class="input">
|
||||||
{{field}} {{field.label_tag}}
|
{{field}} {{field.label_tag}}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="label">
|
<div class="label">
|
||||||
{{field.label_tag}}
|
{{field.label_tag}}
|
||||||
</div>
|
</div>
|
||||||
<div class="input">
|
<div class="input">
|
||||||
{{field}}
|
{{field}}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if field.help_text %}
|
{% if field.help_text %}
|
||||||
<div class="helptext">
|
<div class="helptext">
|
||||||
{{field.help_text}}
|
{{field.help_text}}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
{% block title %}{{block.super}} - {{page.title}}{% endblock %}
|
{% block title %}{{block.super}} - {{page.title}}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% for section in sections %}
|
{% for section in sections %}
|
||||||
{% include_section section %}
|
{% include_section section %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% editpage '<img src="/static/cms/edit.png">' %}
|
{% editpage '<img src="/static/cms/edit.png">' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -3,19 +3,19 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form method="post" class="cms" novalidate>
|
<form method="post" class="cms" novalidate>
|
||||||
<div class="wrapper" style="max-width: 300px">
|
<div class="wrapper" style="max-width: 300px">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<fieldset>
|
<fieldset>
|
||||||
{{form.non_field_errors}}
|
{{form.non_field_errors}}
|
||||||
{% for field in form %}
|
{% for field in form %}
|
||||||
{% include 'cms/formfield.html' with field=field %}
|
{% include 'cms/formfield.html' with field=field %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="edit page">
|
<div class="edit page">
|
||||||
<button><img src="{% static 'cms/save.png' %}"></button>
|
<button><img src="{% static 'cms/save.png' %}"></button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,3 +1 @@
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
# Create your tests here.
|
# Create your tests here.
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[settings]
|
||||||
|
known_third_party=cms
|
|
@ -15,13 +15,14 @@ repos:
|
||||||
rev: main
|
rev: main
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
|
args: ['--line-length', '88']
|
||||||
- repo: https://github.com/pycqa/flake8
|
|
||||||
rev: master
|
|
||||||
hooks:
|
|
||||||
- id: flake8
|
|
||||||
|
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: main
|
rev: main
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
|
|
||||||
|
- repo: https://github.com/pycqa/flake8
|
||||||
|
rev: main
|
||||||
|
hooks:
|
||||||
|
- id: flake8
|
||||||
|
|
|
@ -1,25 +1,16 @@
|
||||||
from django.db import models
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
|
|
||||||
from cms.decorators import page_model, section_model
|
from cms.decorators import page_model, section_model
|
||||||
from cms.models import BasePage, BaseSection
|
from cms.models import BasePage, BaseSection
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
@page_model
|
@page_model
|
||||||
class Page(BasePage):
|
class Page(BasePage):
|
||||||
"""Add custom fields here. Already existing fields: title, slug,
|
pass
|
||||||
number, menu
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
@section_model
|
@section_model
|
||||||
class Section(BaseSection):
|
class Section(BaseSection):
|
||||||
"""Add custom fields here. Already existing fields: title, type,
|
|
||||||
number, content, image, video, href
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
page = models.ForeignKey(Page, related_name="sections", on_delete=models.PROTECT)
|
page = models.ForeignKey(Page, related_name="sections", on_delete=models.PROTECT)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,77 +3,77 @@
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="{{lang}}">
|
<html lang="{{lang}}">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" href="{% static 'favicon.png' %}">
|
<link rel="icon" href="{% static 'favicon.png' %}">
|
||||||
<link rel="stylesheet" href="{% static 'main.scss.css' %}">
|
<link rel="stylesheet" href="{% static 'main.scss.css' %}">
|
||||||
<link rel="stylesheet" href="{% static 'hamburgers.css' %}">
|
<link rel="stylesheet" href="{% static 'hamburgers.css' %}">
|
||||||
<title>{% block title %}Awesome Website{% endblock %}</title>
|
<title>{% block title %}Awesome Website{% endblock %}</title>
|
||||||
{% block extrahead %}{% endblock %}
|
{% block extrahead %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
|
||||||
|
<header>
|
||||||
|
{% block header %}
|
||||||
|
<h1><a href="/">Awesome Website</a></h1>
|
||||||
|
{% endblock %}
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<nav>
|
||||||
|
{% block nav %}
|
||||||
|
{% if pages %}
|
||||||
|
<ul id="menu">
|
||||||
|
{% for p in pages %}
|
||||||
|
<li><a href="{% if p.slug %}{% url 'cms:page' p.slug %}{% else %}{% url 'cms:page' %}{% endif %}" {% if p.pk == page.pk %}class="current"{% endif %}>{{p.title}}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
{% if perms.cms_page_create %}
|
||||||
|
<li><a class="edit" href="{% url 'cms:createpage' %}">+ {% trans 'new page' %}</a></li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
<button class="hamburger hamburger--collapse" id='hamburger'>
|
||||||
|
<span class="hamburger-box">
|
||||||
|
<span class="hamburger-inner"></span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
{% endblock %}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<article>
|
||||||
|
{% block content %}
|
||||||
|
{% endblock %}
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
{% block footer %}
|
||||||
|
{% endblock %}
|
||||||
|
</footer>
|
||||||
|
|
||||||
<header>
|
|
||||||
{% block header %}
|
|
||||||
<h1><a href="/">Awesome Website</a></h1>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</header>
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
|
var hamburger = document.getElementById('hamburger');
|
||||||
|
var menu = document.getElementById('menu');
|
||||||
|
hamburger.addEventListener('click', function(e) {
|
||||||
|
hamburger.classList.toggle('is-active');
|
||||||
|
menu.classList.toggle('visible');
|
||||||
|
});
|
||||||
|
|
||||||
<nav>
|
var links = document.querySelectorAll('a');
|
||||||
{% block nav %}
|
for (var link of links) {
|
||||||
{% if pages %}
|
var a = new RegExp('/' + window.location.host + '/');
|
||||||
<ul id="menu">
|
if (!a.test(link.href)) {
|
||||||
{% for p in pages %}
|
link.addEventListener('click', function(event) {
|
||||||
<li><a href="{% if p.slug %}{% url 'cms:page' p.slug %}{% else %}{% url 'cms:page' %}{% endif %}" {% if p.pk == page.pk %}class="current"{% endif %}>{{p.title}}</a></li>
|
event.preventDefault();
|
||||||
{% endfor %}
|
event.stopPropagation();
|
||||||
{% if perms.cms_page_create %}
|
window.open(this.href, '_blank');
|
||||||
<li><a class="edit" href="{% url 'cms:createpage' %}">+ {% trans 'new page' %}</a></li>
|
});
|
||||||
{% endif %}
|
}
|
||||||
</ul>
|
}
|
||||||
{% endif %}
|
});
|
||||||
<button class="hamburger hamburger--collapse" id='hamburger'>
|
</script>
|
||||||
<span class="hamburger-box">
|
{% block extrabody %}{% endblock %}
|
||||||
<span class="hamburger-inner"></span>
|
</body>
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
{% endblock %}
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<article>
|
|
||||||
{% block content %}
|
|
||||||
{% endblock %}
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
{% block footer %}
|
|
||||||
{% endblock %}
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
<script>
|
|
||||||
document.addEventListener("DOMContentLoaded", function(event) {
|
|
||||||
var hamburger = document.getElementById('hamburger');
|
|
||||||
var menu = document.getElementById('menu');
|
|
||||||
hamburger.addEventListener('click', function(e) {
|
|
||||||
hamburger.classList.toggle('is-active');
|
|
||||||
menu.classList.toggle('visible');
|
|
||||||
});
|
|
||||||
|
|
||||||
var links = document.querySelectorAll('a');
|
|
||||||
for (var link of links) {
|
|
||||||
var a = new RegExp('/' + window.location.host + '/');
|
|
||||||
if (!a.test(link.href)) {
|
|
||||||
link.addEventListener('click', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
window.open(this.href, '_blank');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% block extrabody %}{% endblock %}
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
{% load i18n cms %}
|
{% load i18n cms %}
|
||||||
<section class="contact">
|
<section class="contact">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<h1>{{section.title}}</h1>
|
<h1>{{section.title}}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form">
|
||||||
|
<form method="post" class="cms">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% for field in form %}
|
||||||
|
{% include 'cms/formfield.html' with field=field %}
|
||||||
|
{% endfor %}
|
||||||
|
<button class="button" name="section" value="{{section.pk}}">{% trans 'Send' %}</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form">
|
{% editsection '<img src="/static/cms/edit.png">' %}
|
||||||
<form method="post" class="cms">
|
|
||||||
{% csrf_token %}
|
|
||||||
{% for field in form %}
|
|
||||||
{% include 'cms/formfield.html' with field=field %}
|
|
||||||
{% endfor %}
|
|
||||||
<button class="button" name="section" value="{{section.pk}}">{% trans 'Send' %}</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% editsection '<img src="/static/cms/edit.png">' %}
|
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
{% load thumbnail i18n cms %}
|
{% load thumbnail i18n cms %}
|
||||||
|
|
||||||
<section class="images">
|
<section class="images">
|
||||||
<div class="images">
|
<div class="images">
|
||||||
{% for image in section.images.all %}
|
{% for image in section.images.all %}
|
||||||
<div class="image">
|
<div class="image">
|
||||||
<div>
|
<div>
|
||||||
<img src="{% thumbnail image.image 700x700 %}">
|
<img src="{% thumbnail image.image 700x700 %}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% editsection '<img src="/static/cms/edit.png">' %}
|
{% editsection '<img src="/static/cms/edit.png">' %}
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
{% load i18n cms %}
|
{% load i18n cms %}
|
||||||
|
|
||||||
<section class="text">
|
<section class="text">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<h1>
|
<h1>
|
||||||
{{section.title}}
|
{{section.title}}
|
||||||
</h1>
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
{% eval section.content %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content">
|
{% editsection '<img src="/static/cms/edit.png">' %}
|
||||||
{% eval section.content %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% editsection '<img src="/static/cms/edit.png">' %}
|
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
{% load embed_video_tags i18n cms %}
|
{% load embed_video_tags i18n cms %}
|
||||||
|
|
||||||
<section class="video">
|
<section class="video">
|
||||||
{% if section.video %}
|
{% if section.video %}
|
||||||
<div class="video">
|
<div class="video">
|
||||||
<div class="iframe">
|
<div class="iframe">
|
||||||
{% video section.video '800x600' %}
|
{% video section.video '800x600' %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% editsection '<img src="/static/cms/edit.png">' %}
|
{% editsection '<img src="/static/cms/edit.png">' %}
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
|
|
||||||
from cms.decorators import section_view
|
from cms.decorators import section_view
|
||||||
from cms.forms import ContactForm
|
from cms.forms import ContactForm
|
||||||
from cms.views import SectionFormView, SectionView
|
from cms.views import SectionFormView, SectionView
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
@section_view
|
@section_view
|
||||||
|
|
1
setup.py
1
setup.py
|
@ -34,6 +34,7 @@ setup(
|
||||||
"easy-thumbnails",
|
"easy-thumbnails",
|
||||||
"libsass",
|
"libsass",
|
||||||
"markdown",
|
"markdown",
|
||||||
|
"pre-commit",
|
||||||
"psycopg2",
|
"psycopg2",
|
||||||
"pylibmc",
|
"pylibmc",
|
||||||
],
|
],
|
||||||
|
|
Ładowanie…
Reference in New Issue