general: remove legacy theming code (#70128)
This commit is contained in:
parent
36110d8082
commit
2d71198352
|
@ -4,8 +4,6 @@ include wcs.cfg-sample
|
|||
recursive-include wcs/locale *.po *.mo
|
||||
recursive-include extra/ *.py
|
||||
recursive-include data/web/ *.html *.css *.png
|
||||
recursive-include data/themes/default/ *.html *.css *.png *.gif *.jpg *.js *.ezt *.xml
|
||||
recursive-include data/themes/alto/ *.html *.css *.png *.gif *.jpg *.js *.ezt *.xml
|
||||
recursive-include data/vendor/ *.dat
|
||||
recursive-include wcs/qommon/static/ *.css *.scss *.png *.gif *.jpg *.js *.eot *.svg *.ttf *.woff *.map
|
||||
recursive-include wcs/templates *.html *.txt
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<theme name="alto" version="1.0">
|
||||
<label>Alto</label>
|
||||
<desc>Alto theme</desc>
|
||||
<author>Frederic Peters (original Dotclear theme (alto studio) by David Jubert)</author>
|
||||
</theme>
|
Binary file not shown.
Before Width: | Height: | Size: 728 B |
Binary file not shown.
Before Width: | Height: | Size: 9.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 508 B |
Binary file not shown.
Before Width: | Height: | Size: 10 KiB |
|
@ -1,18 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="[site_lang]">
|
||||
<head>
|
||||
<title>[page_title]</title>
|
||||
<link rel="stylesheet" type="text/css" href="[css]"/>
|
||||
[script]
|
||||
</head>
|
||||
<body[if-any onload] onload="[onload]"[end]>
|
||||
<div id="page">
|
||||
<div id="top"> <h1>[if-any title][title][else][site_name][end]</h1> </div>
|
||||
<div id="main-content">
|
||||
[if-any breadcrumb]<p id="breadcrumb">Vous êtes ici : [breadcrumb]</p>[end]
|
||||
[body]
|
||||
</div>
|
||||
<div id="footer"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,270 +0,0 @@
|
|||
/* adapted from alto dotclear theme */
|
||||
|
||||
@import url(/static/xstatic/themes/smoothness/jquery-ui.min.css);
|
||||
@import url(/static/css/qommon.css);
|
||||
|
||||
html, body {
|
||||
background: #CCCCCC;
|
||||
font-family: sans-serif;
|
||||
color: #333333;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
border: none;
|
||||
}
|
||||
|
||||
label {
|
||||
cursor: pointer;
|
||||
cursor: hand;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
input,textarea {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 99%;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
text-decoration : none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #0273B9;
|
||||
text-decoration : underline;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #0273B9;
|
||||
text-decoration : none;
|
||||
}
|
||||
|
||||
#page {
|
||||
background: #fff url(img/page.jpg) repeat-y center top;
|
||||
color: inherit;
|
||||
width: 886px;
|
||||
margin: 0 auto;
|
||||
text-align: left;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#top {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #CCCCCC url(img/top.jpg) no-repeat left top;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
#top h1 {
|
||||
width: 706px;
|
||||
margin: 0 auto;
|
||||
padding-top: 70px;
|
||||
}
|
||||
|
||||
#side {
|
||||
float: right;
|
||||
width: 204px;
|
||||
padding: 0;
|
||||
margin: 0 -20px 0 20px;
|
||||
}
|
||||
|
||||
#side #tracking-code {
|
||||
margin-bottom: 1em;
|
||||
border: 1px solid #bfbfbf;
|
||||
color: #333333;
|
||||
background: #e6e6e6;
|
||||
padding: 1ex;
|
||||
}
|
||||
|
||||
#side #tracking-code h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#side #tracking-code button,
|
||||
#side #tracking-code a {
|
||||
margin: 1ex auto;
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 120%;
|
||||
background: white;
|
||||
border: 1px solid black;
|
||||
padding: 0.5ex 0;
|
||||
width: 10em;
|
||||
}
|
||||
|
||||
#side #tracking-code button {
|
||||
background: #0273B9;
|
||||
color: white;
|
||||
}
|
||||
|
||||
input[name=savedraft] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#steps {
|
||||
background: white;
|
||||
border: 1px solid #bfbfbf;
|
||||
color: #333333;
|
||||
background: #e6e6e6;
|
||||
-moz-border-radius: 6px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
#footer {
|
||||
width: 886px;
|
||||
height: 123px;
|
||||
background: #CCCCCC url(img/bottom.jpg) no-repeat left top;
|
||||
margin: 0;
|
||||
margin-top: 1em;
|
||||
color: #666;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#footer p {
|
||||
width: 706px;
|
||||
margin: 0 auto;
|
||||
padding-top: 24px;
|
||||
text-align: right;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
|
||||
#main-content {
|
||||
width: 735px;
|
||||
padding-left: 65px;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
|
||||
div#steps ol {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
div#steps li {
|
||||
display: block;
|
||||
border: 1px solid #ddd;
|
||||
margin: 0.5em 0;
|
||||
background: #eee;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
#steps span.marker {
|
||||
padding: 0 1ex 0 1ex;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
text-align: center;
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
#steps li.current span.marker {
|
||||
background: #0273b9;
|
||||
}
|
||||
|
||||
|
||||
#steps li.current {
|
||||
font-weight: bold;
|
||||
border: 1px solid #333333;
|
||||
}
|
||||
|
||||
#steps li.current span.label {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
#steps ol ul {
|
||||
margin-right: 1em;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
#steps ol ul li {
|
||||
padding: 0 2px;
|
||||
font-weight: normal;
|
||||
margin-left: -1ex;
|
||||
}
|
||||
|
||||
#steps ol ul li.current {
|
||||
border-color: inherit;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
|
||||
div.widget {
|
||||
clear: none;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
hr {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
textarea {
|
||||
}
|
||||
|
||||
p#breadcrumb {
|
||||
background: #e6e6e6;
|
||||
-moz-border-radius: 6px;
|
||||
width: 750px;
|
||||
padding: 3px;
|
||||
font-size: 90%;
|
||||
border: 1px solid #bfbfbf;
|
||||
}
|
||||
|
||||
div#receipt {
|
||||
}
|
||||
|
||||
div#receipt span.label {
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
}
|
||||
|
||||
div#receipt span.value {
|
||||
display: block;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
form div.page,
|
||||
div#receipt div.page {
|
||||
border: 1px solid #bfbfbf;
|
||||
padding: 1ex;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
form div.page p,
|
||||
div#receipt div.page p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
form div.page h3,
|
||||
div#receipt div.page h3 {
|
||||
margin: 0;
|
||||
margin-bottom: 1ex;
|
||||
}
|
||||
|
||||
|
||||
p#receiver {
|
||||
margin: 0;
|
||||
margin-left: 2em;
|
||||
margin-top: -0.7em;
|
||||
margin-bottom: 1em;
|
||||
padding: 2px 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table#listing {
|
||||
background: white;
|
||||
border: 1px solid #888;
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<theme name="default" version="1.0">
|
||||
<label>Default</label>
|
||||
<desc>Default theme</desc>
|
||||
<author>Frederic Peters & Dotclear Team</author>
|
||||
</theme>
|
Binary file not shown.
Before Width: | Height: | Size: 675 B |
|
@ -12,7 +12,7 @@
|
|||
<div id="page">
|
||||
<div id="top">
|
||||
{% block header %}
|
||||
<h1>WIP/DJANGO - {% if title %}{{ title }}{% else %}{{ site_name }}{% endif %}</h1>
|
||||
<h1>{% if title %}{{ title }}{% else %}{{ site_name }}{% endif %}</h1>
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div id="main-content">
|
||||
|
|
|
@ -28,7 +28,6 @@ from wcs.data_sources import NamedDataSource
|
|||
from wcs.formdef import FormDef
|
||||
from wcs.qommon.form import UploadedFile
|
||||
from wcs.qommon.http_request import HTTPRequest
|
||||
from wcs.qommon.template import get_current_theme
|
||||
from wcs.wf.export_to_model import ExportToModel
|
||||
from wcs.workflows import Workflow
|
||||
from wcs.wscalls import NamedWsCall
|
||||
|
@ -74,16 +73,14 @@ def test_settings_disabled_screens(pub):
|
|||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/settings/')
|
||||
assert 'Identification' in resp.text
|
||||
assert 'Theme' in resp.text
|
||||
|
||||
if not pub.site_options.has_section('options'):
|
||||
pub.site_options.add_section('options')
|
||||
pub.site_options.set('options', 'settings-disabled-screens', 'identification, theme')
|
||||
pub.site_options.set('options', 'settings-disabled-screens', 'identification')
|
||||
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
|
||||
pub.site_options.write(fd)
|
||||
resp = app.get('/backoffice/settings/')
|
||||
assert 'Identification' not in resp.text
|
||||
assert 'Theme' not in resp.text
|
||||
|
||||
|
||||
def test_settings_export_import(pub):
|
||||
|
@ -318,61 +315,6 @@ def test_settings_export_import(pub):
|
|||
assert 'Unknown referenced objects [Unknown fields blocks: unknown]' in resp
|
||||
|
||||
|
||||
def test_settings_themes(pub):
|
||||
create_superuser(pub)
|
||||
app = login(get_app(pub))
|
||||
|
||||
# create mock theme
|
||||
os.mkdir(os.path.join(pub.app_dir, 'themes'))
|
||||
os.mkdir(os.path.join(pub.app_dir, 'themes', 'test'))
|
||||
with open(os.path.join(pub.app_dir, 'themes', 'test', 'desc.xml'), 'w') as fd:
|
||||
fd.write(
|
||||
'<?xml version="1.0"?>'
|
||||
'<theme name="test" version="1.0">'
|
||||
' <label>Test Theme</label>'
|
||||
'</theme>'
|
||||
)
|
||||
|
||||
resp = app.get('/backoffice/settings/themes')
|
||||
assert 'biglist themes' in resp.text
|
||||
assert 'Test Theme (1.0)' in resp.text
|
||||
|
||||
# just for the kick, there's no support for uploading file in webtest 1.3
|
||||
resp = app.get('/backoffice/settings/themes')
|
||||
resp.click('Install New Theme')
|
||||
|
||||
# select the theme
|
||||
resp = app.get('/backoffice/settings/themes')
|
||||
resp.forms[0]['theme'].value = 'test'
|
||||
resp = resp.forms[0].submit()
|
||||
assert resp.location == 'http://example.net/backoffice/settings/'
|
||||
|
||||
resp = app.get('/backoffice/settings/themes')
|
||||
assert 'checked' in resp.text
|
||||
assert get_current_theme()['name'] == 'test'
|
||||
|
||||
|
||||
def test_settings_template(pub):
|
||||
create_superuser(pub)
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/settings/template')
|
||||
|
||||
# change template
|
||||
orig_value = resp.forms[0]['template'].value
|
||||
assert 'foobar' not in orig_value
|
||||
resp.forms[0]['template'] = orig_value + '<!-- foobar -->'
|
||||
resp = resp.forms[0].submit('submit')
|
||||
|
||||
# restore default template
|
||||
resp = app.get('/backoffice/settings/template')
|
||||
assert 'foobar' in resp.forms[0]['template'].value
|
||||
resp = resp.forms[0].submit('restore-default')
|
||||
|
||||
# check
|
||||
resp = app.get('/backoffice/settings/template')
|
||||
assert resp.forms[0]['template'].value == orig_value
|
||||
|
||||
|
||||
def test_settings_user(pub):
|
||||
user = create_superuser(pub)
|
||||
app = login(get_app(pub))
|
||||
|
@ -829,68 +771,6 @@ def test_settings_permissions(pub):
|
|||
assert pub.cfg['admin-permissions']['workflows'] == []
|
||||
|
||||
|
||||
def test_settings_theme_preview(pub):
|
||||
create_superuser(pub)
|
||||
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'form title'
|
||||
formdef.fields = []
|
||||
formdef.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
assert 'alto/wcs.css' not in app.get('/').text
|
||||
resp = app.get('/backoffice/settings/themes')
|
||||
assert resp.form['theme'].value in ('default', 'django')
|
||||
|
||||
# visit theme preview
|
||||
resp = resp.click(href='theme_preview/alto/')
|
||||
assert 'alto/wcs.css' in resp.text
|
||||
|
||||
# get into a form, making sure we are kept in theme preview
|
||||
resp = resp.click('form title')
|
||||
assert 'alto/wcs.css' in resp.text
|
||||
|
||||
# verify submits are not allowed
|
||||
resp = resp.form.submit('submit')
|
||||
assert "The theme preview doesn't support this." in resp.text
|
||||
|
||||
|
||||
def test_settings_theme_download_upload(pub):
|
||||
create_superuser(pub)
|
||||
|
||||
# download existing theme
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/settings/themes')
|
||||
resp = resp.click('download', index=0)
|
||||
assert resp.headers['content-type'] == 'application/zip'
|
||||
|
||||
zip_content = io.BytesIO(resp.body)
|
||||
with zipfile.ZipFile(zip_content, 'a') as zipf:
|
||||
filelist = zipf.namelist()
|
||||
assert 'alto/icon.png' in filelist
|
||||
assert 'alto/desc.xml' in filelist
|
||||
assert 'alto/template.ezt' in filelist
|
||||
assert 'alto/wcs.css' in filelist
|
||||
|
||||
# modify it
|
||||
zipf.writestr('alto/foobar.txt', 'XXX')
|
||||
|
||||
# upload it
|
||||
resp = app.get('/backoffice/settings/themes')
|
||||
resp = resp.click('Install New Theme')
|
||||
resp.form['file'] = Upload('alto-modified.zip', zip_content.getvalue())
|
||||
resp = resp.form.submit()
|
||||
assert os.path.exists(os.path.join(pub.app_dir, 'themes/alto/foobar.txt'))
|
||||
|
||||
assert app.get('/themes/alto/foobar.txt').text == 'XXX'
|
||||
assert 'Directory listing denied' in app.get('/themes/alto/', status=200).text
|
||||
|
||||
assert app.get('/themes/alto/plop', status=404)
|
||||
assert app.get('/themes/alto/../', status=404)
|
||||
assert app.get('/themes/xxx/../', status=404)
|
||||
|
||||
|
||||
def test_postgresql_settings(pub):
|
||||
create_superuser(pub)
|
||||
|
||||
|
|
|
@ -343,28 +343,6 @@ def test_category_page_redirect_var(pub):
|
|||
assert resp.location == 'http://www.example.com/en/foobar/'
|
||||
|
||||
|
||||
def test_legacy_theme_misc():
|
||||
pub = create_temporary_pub(legacy_theme_mode=True)
|
||||
pub.cfg['language'] = {'language': 'en'}
|
||||
pub.write_cfg()
|
||||
|
||||
formdef = create_formdef()
|
||||
formdef.fields = [fields.StringField(id='1', label='string')]
|
||||
formdef.store()
|
||||
|
||||
resp = get_app(pub).get('/')
|
||||
assert '<title>' in resp.text
|
||||
assert '/static/js/qommon.forms.js' not in resp.text
|
||||
assert '<a class="" href="test/">test</a>' in resp.text
|
||||
resp = resp.click('test')
|
||||
assert '/static/js/qommon.forms.js' in resp.text
|
||||
resp.form['f1'] = 'TEST'
|
||||
resp = resp.form.submit('submit')
|
||||
assert 'Check values then click submit.' in resp.text
|
||||
resp = resp.form.submit('submit').follow()
|
||||
assert 'The form has been recorded on' in resp.text
|
||||
|
||||
|
||||
def test_form_access(pub):
|
||||
formdef = create_formdef()
|
||||
get_app(pub).get('/test/', status=200)
|
||||
|
|
|
@ -314,14 +314,14 @@ def test_update_configuration(setuptest):
|
|||
|
||||
def test_update_themes(setuptest):
|
||||
pub, hobo_cmd = setuptest
|
||||
pub.cfg['branding'] = {'theme': 'default'}
|
||||
pub.cfg['branding'] = {'theme': 'django'}
|
||||
service = [x for x in HOBO_JSON.get('services', []) if x.get('service-id') == 'wcs'][0]
|
||||
hobo_cmd.update_configuration(service, pub)
|
||||
assert pub.cfg['branding']['theme'] == 'default'
|
||||
assert pub.cfg['branding']['theme'] == 'django'
|
||||
|
||||
service['variables']['theme'] = 'foobar'
|
||||
hobo_cmd.update_configuration(service, pub)
|
||||
assert pub.cfg['branding']['theme'] == 'default'
|
||||
assert pub.cfg['branding']['theme'] == 'django'
|
||||
|
||||
hobo_cmd.THEMES_DIRECTORY = os.path.join(os.path.dirname(__file__), 'themes')
|
||||
hobo_cmd.update_configuration(service, pub)
|
||||
|
|
|
@ -33,30 +33,25 @@ class KnownElements:
|
|||
pickle_app_dir = None
|
||||
sql_app_dir = None
|
||||
sql_db_name = None
|
||||
legacy_theme_app_dir = None
|
||||
lazy_app_dir = None
|
||||
|
||||
|
||||
known_elements = KnownElements()
|
||||
|
||||
|
||||
def create_temporary_pub(pickle_mode=False, legacy_theme_mode=False, lazy_mode=False):
|
||||
def create_temporary_pub(pickle_mode=False, lazy_mode=False):
|
||||
if get_publisher():
|
||||
get_publisher().cleanup()
|
||||
cleanup()
|
||||
if legacy_theme_mode and known_elements.legacy_theme_app_dir:
|
||||
APP_DIR = known_elements.legacy_theme_app_dir
|
||||
elif lazy_mode and known_elements.lazy_app_dir:
|
||||
if lazy_mode and known_elements.lazy_app_dir:
|
||||
APP_DIR = known_elements.lazy_app_dir
|
||||
elif pickle_mode and known_elements.pickle_app_dir:
|
||||
APP_DIR = known_elements.pickle_app_dir
|
||||
elif not (legacy_theme_mode or lazy_mode or pickle_mode) and known_elements.sql_app_dir:
|
||||
elif not (lazy_mode or pickle_mode) and known_elements.sql_app_dir:
|
||||
APP_DIR = known_elements.sql_app_dir
|
||||
else:
|
||||
APP_DIR = tempfile.mkdtemp()
|
||||
if legacy_theme_mode:
|
||||
known_elements.legacy_theme_app_dir = APP_DIR
|
||||
elif lazy_mode:
|
||||
if lazy_mode:
|
||||
known_elements.lazy_app_dir = APP_DIR
|
||||
elif pickle_mode:
|
||||
known_elements.pickle_app_dir = APP_DIR
|
||||
|
@ -124,12 +119,6 @@ def create_temporary_pub(pickle_mode=False, legacy_theme_mode=False, lazy_mode=F
|
|||
'frontoffice-url': 'http://example.net',
|
||||
}
|
||||
pub.cfg['language'] = {'language': 'en'}
|
||||
|
||||
if legacy_theme_mode:
|
||||
pub.cfg['branding'] = {'theme': 'default'}
|
||||
else:
|
||||
pub.cfg['branding'] = {'theme': 'django'}
|
||||
|
||||
pub.write_cfg()
|
||||
|
||||
if not created:
|
||||
|
@ -183,9 +172,6 @@ def create_temporary_pub(pickle_mode=False, legacy_theme_mode=False, lazy_mode=F
|
|||
def clean_temporary_pub():
|
||||
if get_publisher():
|
||||
get_publisher().cleanup()
|
||||
if known_elements.legacy_theme_app_dir and os.path.exists(known_elements.legacy_theme_app_dir):
|
||||
shutil.rmtree(known_elements.legacy_theme_app_dir)
|
||||
known_elements.legacy_theme_app_dir = None
|
||||
if known_elements.pickle_app_dir and os.path.exists(known_elements.pickle_app_dir):
|
||||
shutil.rmtree(known_elements.pickle_app_dir)
|
||||
known_elements.pickle_app_dir = None
|
||||
|
|
|
@ -24,11 +24,10 @@ try:
|
|||
import lasso
|
||||
except ImportError:
|
||||
lasso = None
|
||||
import shutil
|
||||
import xml.etree.ElementTree as ET
|
||||
import zipfile
|
||||
|
||||
from django.utils.encoding import force_bytes, force_text
|
||||
from django.utils.encoding import force_bytes
|
||||
from quixote import get_publisher, get_request, get_response, get_session, redirect
|
||||
from quixote.directory import Directory
|
||||
from quixote.html import TemplateIO, htmltext
|
||||
|
@ -41,7 +40,6 @@ from wcs.formdef import FormDef, FormdefImportError
|
|||
from wcs.qommon import _, errors, get_cfg, ident, misc, template
|
||||
from wcs.qommon.admin.cfg import cfg_submit
|
||||
from wcs.qommon.admin.emails import EmailsDirectory
|
||||
from wcs.qommon.admin.menu import error_page
|
||||
from wcs.qommon.admin.settings import SettingsDirectory as QommonSettingsDirectory
|
||||
from wcs.qommon.admin.texts import TextsDirectory
|
||||
from wcs.qommon.afterjobs import AfterJob
|
||||
|
@ -59,7 +57,6 @@ from wcs.qommon.form import (
|
|||
SingleSelectWidget,
|
||||
StringWidget,
|
||||
TextWidget,
|
||||
UrlWidget,
|
||||
WidgetList,
|
||||
)
|
||||
from wcs.workflows import Workflow, WorkflowImportError
|
||||
|
@ -449,51 +446,9 @@ class FileTypesDirectory(Directory):
|
|||
return r.getvalue()
|
||||
|
||||
|
||||
class ThemePreviewDirectory(Directory):
|
||||
def _q_traverse(self, path):
|
||||
if len(path) < 2:
|
||||
return error_page('settings', _('Invalid URL'))
|
||||
|
||||
theme_id = path[0]
|
||||
branding = get_publisher().cfg.get('branding', {})
|
||||
original_branding = branding.copy()
|
||||
get_publisher().cfg['branding'] = branding
|
||||
get_publisher().cfg['branding']['theme'] = theme_id
|
||||
if 'template' in get_publisher().cfg['branding']:
|
||||
del get_publisher().cfg['branding']['template']
|
||||
|
||||
root_directory = get_publisher().root_directory_class()
|
||||
|
||||
response = get_response()
|
||||
response.reset_includes()
|
||||
response.filter = {}
|
||||
del response.breadcrumb
|
||||
|
||||
if path[1] in ('backoffice', 'admin') or get_request().get_method() == 'POST':
|
||||
from wcs.qommon.template import error_page as base_error_page
|
||||
|
||||
output = base_error_page(_("The theme preview doesn't support this."))
|
||||
else:
|
||||
output = root_directory._q_traverse(path[1:])
|
||||
|
||||
from wcs.qommon.template import decorate
|
||||
|
||||
if isinstance(output, template.QommonTemplateResponse):
|
||||
output = template.render(output.templates, output.context)
|
||||
theme_preview = decorate(output, response)
|
||||
|
||||
# restore original branding in case it has been changed
|
||||
get_publisher().cfg['branding'] = original_branding
|
||||
get_publisher().write_cfg()
|
||||
response.filter['raw'] = True
|
||||
|
||||
return theme_preview
|
||||
|
||||
|
||||
class SettingsDirectory(QommonSettingsDirectory):
|
||||
_q_exports = [
|
||||
'',
|
||||
'themes',
|
||||
'users',
|
||||
'template',
|
||||
'emails',
|
||||
|
@ -506,12 +461,9 @@ class SettingsDirectory(QommonSettingsDirectory):
|
|||
'sms',
|
||||
'certificates',
|
||||
'texts',
|
||||
'install_theme',
|
||||
'download_theme',
|
||||
'postgresql',
|
||||
('admin-permissions', 'admin_permissions'),
|
||||
'geolocation',
|
||||
'theme_preview',
|
||||
'filetypes',
|
||||
('user-templates', 'user_templates'),
|
||||
('data-sources', 'data_sources'),
|
||||
|
@ -523,7 +475,6 @@ class SettingsDirectory(QommonSettingsDirectory):
|
|||
identification = IdentificationDirectory()
|
||||
users = UsersDirectory()
|
||||
texts = TextsDirectory()
|
||||
theme_preview = ThemePreviewDirectory()
|
||||
filetypes = FileTypesDirectory()
|
||||
data_sources = NamedDataSourcesDirectory()
|
||||
wscalls = NamedWsCallsDirectory()
|
||||
|
@ -636,13 +587,6 @@ class SettingsDirectory(QommonSettingsDirectory):
|
|||
_('Language'),
|
||||
_('Configure site language'),
|
||||
)
|
||||
if enabled('theme'):
|
||||
r += htmltext('<dt><a href="themes">%s</a></dt> <dd>%s</dd>') % (_('Theme'), _('Configure theme'))
|
||||
if enabled('template'):
|
||||
r += htmltext('<dt><a href="template">%s</a></dt> <dd>%s</dd>') % (
|
||||
_('Template'),
|
||||
_('Configure template'),
|
||||
)
|
||||
if enabled('geolocation'):
|
||||
r += htmltext('<dt><a href="geolocation">%s</a></dt> <dd>%s</dd>') % (
|
||||
_('Geolocation'),
|
||||
|
@ -766,217 +710,6 @@ class SettingsDirectory(QommonSettingsDirectory):
|
|||
get_publisher().write_cfg()
|
||||
return redirect('.')
|
||||
|
||||
def themes(self):
|
||||
request = get_request()
|
||||
|
||||
if 'theme' not in request.form:
|
||||
current_theme = get_cfg('branding', {}).get('theme', 'default')
|
||||
|
||||
get_response().breadcrumb.append(('themes', _('Themes')))
|
||||
html_top('settings', title=_('Themes'))
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext("<h2>%s</h2>") % _('Themes')
|
||||
|
||||
r += get_session().display_message()
|
||||
|
||||
r += htmltext('<a rel="popup" href="install_theme">%s</a>') % _('Install New Theme')
|
||||
|
||||
r += htmltext('<form action="themes" enctype="multipart/form-data" method="post">')
|
||||
themes = template.get_themes_dict()
|
||||
r += htmltext('<ul class="biglist themes">')
|
||||
for theme, theme_dict in sorted(themes.items()):
|
||||
label = theme_dict.get('label')
|
||||
if 'version' in theme_dict:
|
||||
label = '%s (%s)' % (label, theme_dict.get('version'))
|
||||
if current_theme == theme:
|
||||
checked = ' checked="checked"'
|
||||
else:
|
||||
checked = ''
|
||||
r += htmltext('<li>')
|
||||
r += htmltext('<strong class="label"><label>')
|
||||
r += htmltext(' <input name="theme" value="%s" type="radio"%s>%s</input>') % (
|
||||
theme,
|
||||
checked,
|
||||
label,
|
||||
)
|
||||
r += htmltext('</label></strong>')
|
||||
if theme_dict.get('icon'):
|
||||
r += htmltext('<img src="/themes/%s/icon.png" alt="" class="theme-icon" />') % theme
|
||||
r += htmltext('<p class="details">%s') % theme_dict.get('desc', '')
|
||||
r += htmltext(' [<a href="download_theme?theme=%s">%s</a>]') % (theme, _('download'))
|
||||
r += htmltext(' [<a class="theme-preview" href="theme_preview/%s/">%s</a>]') % (
|
||||
theme,
|
||||
_('preview'),
|
||||
)
|
||||
if theme_dict.get('author'):
|
||||
r += htmltext('<br/>')
|
||||
r += htmltext(_('by %s')) % theme_dict.get('author')
|
||||
r += htmltext('</p>')
|
||||
r += htmltext('</li>')
|
||||
r += htmltext('</ul>')
|
||||
r += htmltext('<div class="buttons">')
|
||||
r += htmltext('<button>%s</button>') % _('Submit')
|
||||
r += htmltext('</div>')
|
||||
r += htmltext('</form>')
|
||||
return r.getvalue()
|
||||
else:
|
||||
themes = template.get_themes()
|
||||
if str(request.form['theme']) in themes:
|
||||
branding_cfg = get_cfg('branding', {})
|
||||
branding_cfg['theme'] = str(request.form['theme'])
|
||||
get_publisher().cfg['branding'] = branding_cfg
|
||||
get_publisher().write_cfg()
|
||||
return redirect('.')
|
||||
|
||||
def download_theme(self):
|
||||
theme_id = get_request().form.get('theme')
|
||||
if not theme_id:
|
||||
return redirect('themes')
|
||||
|
||||
theme_directory = template.get_theme_directory(theme_id)
|
||||
if not theme_directory:
|
||||
return redirect('themes')
|
||||
|
||||
parent_theme_directory = os.path.dirname(theme_directory)
|
||||
c = io.BytesIO()
|
||||
with zipfile.ZipFile(c, 'w') as z:
|
||||
for base, dummy, filenames in os.walk(theme_directory):
|
||||
basetheme = base[len(parent_theme_directory) + 1 :]
|
||||
for filename in filenames:
|
||||
z.write(os.path.join(base, filename), os.path.join(basetheme, filename))
|
||||
|
||||
response = get_response()
|
||||
response.set_content_type('application/zip')
|
||||
response.set_header('content-disposition', 'attachment; filename=%s.zip' % theme_id)
|
||||
return c.getvalue()
|
||||
|
||||
def install_theme(self):
|
||||
form = Form(enctype='multipart/form-data')
|
||||
form.add(FileWidget, 'file', title=_('Theme File'), required=False)
|
||||
form.add(UrlWidget, 'url', title=_('Theme Address'), required=False, size=50)
|
||||
form.add_submit('submit', _('Install'))
|
||||
form.add_submit('cancel', _('Cancel'))
|
||||
|
||||
if form.get_submit() == 'cancel':
|
||||
return redirect('.')
|
||||
|
||||
if form.is_submitted() and not form.has_errors():
|
||||
try:
|
||||
return self.install_theme_submit(form)
|
||||
except ValueError:
|
||||
form.get_widget('file').set_error(_('Invalid Theme'))
|
||||
|
||||
get_response().breadcrumb.append(('install_theme', _('Install Theme')))
|
||||
html_top('forms', title=_('Install Theme'))
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext('<h2>%s</h2>') % _('Install Theme')
|
||||
r += htmltext('<p>%s</p>') % _(
|
||||
'You can install a new theme by uploading a file or by pointing to the theme URL.'
|
||||
)
|
||||
r += form.render()
|
||||
return r.getvalue()
|
||||
|
||||
def install_theme_submit(self, form):
|
||||
if form.get_widget('url').parse():
|
||||
return self.install_theme_from_url(form.get_widget('url').parse())
|
||||
if form.get_widget('file').parse():
|
||||
return self.install_theme_from_file(form.get_widget('file').parse().fp)
|
||||
get_session().message = ('error', _('You have to enter a file or a URL.'))
|
||||
return redirect('themes')
|
||||
|
||||
def install_theme_from_file(self, fp):
|
||||
try:
|
||||
with zipfile.ZipFile(fp, 'r') as z:
|
||||
theme_dir = os.path.join(get_publisher().app_dir, 'themes')
|
||||
filename_list = [x for x in z.namelist() if x[0] != '/' and x[-1] != '/']
|
||||
if len(filename_list) == 0:
|
||||
get_session().message = ('error', _('Empty theme file.'))
|
||||
return redirect('themes')
|
||||
theme_name = filename_list[0].split('/')[0]
|
||||
if ('%s/desc.xml' % theme_name) not in filename_list:
|
||||
get_session().message = ('error', _('Theme is missing a desc.xml file.'))
|
||||
return redirect('themes')
|
||||
desc_xml = z.read('%s/desc.xml' % theme_name)
|
||||
theme_dict = template.get_theme_dict(io.StringIO(force_text(desc_xml)))
|
||||
if theme_dict.get('name') != theme_name:
|
||||
get_session().message = ('error', _('desc.xml is missing a name attribute.'))
|
||||
return redirect('themes')
|
||||
if os.path.exists(os.path.join(theme_dir, theme_name)):
|
||||
shutil.rmtree(os.path.join(theme_dir, theme_name))
|
||||
for f in z.namelist():
|
||||
if f[-1] == '/':
|
||||
continue
|
||||
path = os.path.join(theme_dir, f)
|
||||
data = z.read(f)
|
||||
if not os.path.exists(os.path.dirname(path)):
|
||||
os.makedirs(os.path.dirname(path))
|
||||
with open(path, 'wb') as _f:
|
||||
_f.write(data)
|
||||
return redirect('themes')
|
||||
except Exception as e:
|
||||
get_session().message = ('error', _('Failed to read theme file. (%s)') % str(e))
|
||||
return redirect('themes')
|
||||
|
||||
def install_theme_from_url(self, url):
|
||||
try:
|
||||
fp = misc.urlopen(url)
|
||||
except misc.ConnectionError as e:
|
||||
get_session().message = ('error', _('Error loading theme (%s).') % str(e))
|
||||
return redirect('themes')
|
||||
|
||||
return self.install_theme_from_file(io.StringIO(fp.read()))
|
||||
|
||||
def template(self):
|
||||
from wcs.qommon.template import get_default_ezt_template
|
||||
|
||||
default_template_ezt = get_default_ezt_template()
|
||||
branding_cfg = get_cfg('branding', {})
|
||||
template = branding_cfg.get('template', default_template_ezt)
|
||||
form = Form(enctype="multipart/form-data")
|
||||
form.add(TextWidget, 'template', title=_('Site Template'), value=template, cols=80, rows=25)
|
||||
form.add_submit('submit', _('Submit'))
|
||||
form.add_submit('restore-default', _('Restore default template'))
|
||||
form.add_submit('cancel', _('Cancel'))
|
||||
if form.get_widget('cancel').parse():
|
||||
return redirect('.')
|
||||
|
||||
if form.get_submit() == 'cancel':
|
||||
return redirect('.')
|
||||
|
||||
if form.get_submit() == 'restore-default':
|
||||
self.template_submit()
|
||||
return redirect('.')
|
||||
|
||||
if form.is_submitted() and not form.has_errors():
|
||||
self.template_submit(form)
|
||||
return redirect('.')
|
||||
|
||||
get_response().breadcrumb.append(('template', _('Template')))
|
||||
html_top('settings', title=_('Template'))
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext('<h2>%s</h2>') % _('Template')
|
||||
r += form.render()
|
||||
return r.getvalue()
|
||||
|
||||
def template_submit(self, form=None):
|
||||
from wcs.qommon.template import DEFAULT_TEMPLATE_EZT, get_default_ezt_template
|
||||
|
||||
theme_default_template_ezt = get_default_ezt_template()
|
||||
|
||||
get_publisher().reload_cfg()
|
||||
branding_cfg = get_cfg('branding', {})
|
||||
if not form:
|
||||
template = None
|
||||
else:
|
||||
template = form.get_widget('template').parse()
|
||||
if template in (DEFAULT_TEMPLATE_EZT, theme_default_template_ezt) or not template:
|
||||
if 'template' in branding_cfg:
|
||||
del branding_cfg['template']
|
||||
else:
|
||||
branding_cfg['template'] = template
|
||||
get_publisher().cfg['branding'] = branding_cfg
|
||||
get_publisher().write_cfg()
|
||||
|
||||
def export(self):
|
||||
if get_request().form.get('download'):
|
||||
return self.export_download()
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
from contextlib import contextmanager
|
||||
from threading import Lock
|
||||
|
||||
|
@ -31,7 +30,7 @@ from quixote.http_request import Upload
|
|||
from .publisher import WcsPublisher
|
||||
from .qommon import force_str, template
|
||||
from .qommon.http_request import HTTPRequest
|
||||
from .qommon.publisher import get_cfg, set_publisher_class
|
||||
from .qommon.publisher import set_publisher_class
|
||||
|
||||
|
||||
class TemplateWithFallbackView(TemplateView):
|
||||
|
@ -65,8 +64,8 @@ class TemplateWithFallbackView(TemplateView):
|
|||
elif request.headers.get('X-Popup') == 'true':
|
||||
response = HttpResponse('<div class="popup-content">%s</div>' % context['body'])
|
||||
elif 'raw' in (getattr(self.quixote_response, 'filter') or {}):
|
||||
# used for theme preview (generated in /backoffice/ but cannot
|
||||
# obviously receive the admin template.
|
||||
# used for raw HTML snippets (for example in the test tool
|
||||
# results in inspect page).
|
||||
response = HttpResponse(context['body'])
|
||||
else:
|
||||
response = self.render_to_response(context)
|
||||
|
@ -145,19 +144,6 @@ class CompatWcsPublisher(WcsPublisher):
|
|||
return output
|
||||
if request.headers.get('X-Popup') == 'true':
|
||||
return '<div class="popup-content">%s</div>' % output
|
||||
if response.filter and response.filter.get('admin_ezt'):
|
||||
return self.render_response(output)
|
||||
|
||||
current_theme = get_cfg('branding', {}).get('theme', 'default')
|
||||
theme_directory = template.get_theme_directory(current_theme)
|
||||
if not theme_directory:
|
||||
return self.render_response(output)
|
||||
|
||||
if not os.path.exists(os.path.join(theme_directory, 'templates')):
|
||||
return self.render_response(output)
|
||||
|
||||
if not os.path.exists(os.path.join(theme_directory, 'templates/wcs/base.html')):
|
||||
return self.render_response(output)
|
||||
|
||||
if isinstance(output, template.QommonTemplateResponse):
|
||||
template_response = output
|
||||
|
|
|
@ -116,7 +116,7 @@ class QommonPublisher(Publisher):
|
|||
after_login_url = ''
|
||||
qommon_static_dir = 'static/'
|
||||
qommon_admin_css = 'css/dc2/admin.css'
|
||||
default_theme = 'default'
|
||||
default_theme = 'django'
|
||||
|
||||
site_options = None
|
||||
site_charset = 'utf-8'
|
||||
|
@ -346,11 +346,6 @@ class QommonPublisher(Publisher):
|
|||
|
||||
return error_page
|
||||
|
||||
def render_response(self, content):
|
||||
if isinstance(content, template.QommonTemplateResponse):
|
||||
content = template.render(content.templates, content.context)
|
||||
return template.decorate(content, self.get_request().response)
|
||||
|
||||
def install_lang(self, request=None):
|
||||
if request:
|
||||
lang = request.language
|
||||
|
|
|
@ -14,11 +14,9 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import glob
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
import django.template
|
||||
from django.template import TemplateSyntaxError as DjangoTemplateSyntaxError
|
||||
|
@ -27,9 +25,7 @@ from django.template import engines
|
|||
from django.template.loader import render_to_string
|
||||
from django.utils.encoding import force_text, smart_text
|
||||
from quixote import get_publisher, get_request, get_response, get_session
|
||||
from quixote.directory import Directory
|
||||
from quixote.html import TemplateIO, htmlescape, htmltext
|
||||
from quixote.util import StaticDirectory, StaticFile
|
||||
|
||||
from . import ezt, force_str
|
||||
|
||||
|
@ -53,123 +49,6 @@ def get_theme_directory(theme_id):
|
|||
return location
|
||||
|
||||
|
||||
class ThemesDirectory(Directory):
|
||||
def _q_lookup(self, component):
|
||||
from . import errors
|
||||
|
||||
if component in ('.', '..'):
|
||||
raise errors.TraversalError()
|
||||
|
||||
location = get_theme_directory(component)
|
||||
if location is None:
|
||||
raise errors.TraversalError()
|
||||
|
||||
if os.path.isdir(location):
|
||||
return StaticDirectory(location)
|
||||
else:
|
||||
return StaticFile(location)
|
||||
|
||||
|
||||
def get_themes_dict():
|
||||
system_location = os.path.join(get_publisher().data_dir, 'themes')
|
||||
local_location = os.path.join(get_publisher().app_dir, 'themes')
|
||||
|
||||
themes = {}
|
||||
for theme_xml in glob.glob(os.path.join(system_location, '*/desc.xml')) + glob.glob(
|
||||
os.path.join(local_location, '*/desc.xml')
|
||||
):
|
||||
theme_dict = get_theme_dict(theme_xml)
|
||||
if not theme_dict:
|
||||
continue
|
||||
themes[theme_dict.get('name')] = theme_dict
|
||||
return themes
|
||||
|
||||
|
||||
def get_theme_dict(theme_xml):
|
||||
try:
|
||||
tree = ET.parse(theme_xml).getroot()
|
||||
except Exception: # parse error
|
||||
return None
|
||||
name = force_str(tree.attrib['name'])
|
||||
version = force_str(tree.attrib.get('version') or '')
|
||||
label = force_str(tree.findtext('label') or '')
|
||||
desc = force_str(tree.findtext('desc') or '')
|
||||
author = force_str(tree.findtext('author') or '')
|
||||
icon = None
|
||||
if isinstance(theme_xml, str):
|
||||
icon = os.path.join(os.path.dirname(theme_xml), 'icon.png')
|
||||
if not os.path.exists(icon):
|
||||
icon = None
|
||||
theme = {'name': name, 'label': label, 'desc': desc, 'author': author, 'icon': icon, 'version': version}
|
||||
theme['keywords'] = []
|
||||
for keyword in tree.findall('keywords/keyword'):
|
||||
theme['keywords'].append(keyword.text)
|
||||
return theme
|
||||
|
||||
|
||||
def get_themes():
|
||||
# backward compatibility function, it returns a tuple with theme info,
|
||||
# newer code should use get_themes_dict()
|
||||
themes = {}
|
||||
for k, v in get_themes_dict().items():
|
||||
themes[k] = (v['label'], v['desc'], v['author'], v['icon'])
|
||||
return themes
|
||||
|
||||
|
||||
def get_current_theme():
|
||||
from .publisher import get_cfg
|
||||
|
||||
current_theme = get_cfg('branding', {}).get('theme', 'default')
|
||||
system_location = os.path.join(get_publisher().data_dir, 'themes', current_theme)
|
||||
local_location = os.path.join(get_publisher().app_dir, 'themes', current_theme)
|
||||
for location in (local_location, system_location):
|
||||
if os.path.exists(location):
|
||||
return get_theme_dict(os.path.join(location, 'desc.xml'))
|
||||
default_theme_location = os.path.join(get_publisher().data_dir, 'themes', 'default')
|
||||
return get_theme_dict(os.path.join(default_theme_location, 'desc.xml'))
|
||||
|
||||
|
||||
DEFAULT_TEMPLATE_EZT = """<!DOCTYPE html>
|
||||
<html lang="[site_lang]">
|
||||
<head>
|
||||
<title>[page_title]</title>
|
||||
<link rel="stylesheet" type="text/css" href="[css]"/>
|
||||
[script]
|
||||
</head>
|
||||
<body[if-any onload] onload="[onload]"[end]>
|
||||
<div id="page">
|
||||
<div id="top"> <h1>[if-any title][title][else][site_name][end]</h1> </div>
|
||||
<div id="main-content">
|
||||
[if-any breadcrumb]<p id="breadcrumb">[breadcrumb]</p>[end]
|
||||
[body]
|
||||
</div>
|
||||
<div id="footer">[if-any footer][footer][end]</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
DEFAULT_IFRAME_EZT = """<!DOCTYPE html>
|
||||
<html lang="[site_lang]">
|
||||
<head>
|
||||
<title>[page_title]</title>
|
||||
<link rel="stylesheet" type="text/css" href="[css]"/>
|
||||
[script]
|
||||
</head>
|
||||
<body[if-any onload] onload="[onload]"[end]>
|
||||
<div id="main-content">
|
||||
[if-any breadcrumb]<p id="breadcrumb">[breadcrumb]</p>[end]
|
||||
[body]
|
||||
</div>
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
default_template = ezt.Template()
|
||||
default_template.parse(DEFAULT_TEMPLATE_EZT)
|
||||
|
||||
default_iframe_template = ezt.Template()
|
||||
default_iframe_template.parse(DEFAULT_IFRAME_EZT)
|
||||
|
||||
|
||||
def html_top(title=None, default_org=None):
|
||||
if not hasattr(get_response(), 'filter'):
|
||||
get_response().filter = {}
|
||||
|
@ -207,38 +86,6 @@ def error_page(error_message, error_title=None, location_hint=None):
|
|||
return htmltext(r.getvalue())
|
||||
|
||||
|
||||
def get_default_ezt_template():
|
||||
from .publisher import get_cfg
|
||||
|
||||
current_theme = get_cfg('branding', {}).get('theme', 'default')
|
||||
|
||||
filename = os.path.join(
|
||||
get_publisher().app_dir, 'themes', current_theme, 'template.%s.ezt' % get_publisher().APP_NAME
|
||||
)
|
||||
if os.path.exists(filename):
|
||||
with open(filename) as fd:
|
||||
return fd.read()
|
||||
|
||||
filename = os.path.join(
|
||||
get_publisher().data_dir, 'themes', current_theme, 'template.%s.ezt' % get_publisher().APP_NAME
|
||||
)
|
||||
if os.path.exists(filename):
|
||||
with open(filename) as fd:
|
||||
return fd.read()
|
||||
|
||||
filename = os.path.join(get_publisher().app_dir, 'themes', current_theme, 'template.ezt')
|
||||
if os.path.exists(filename):
|
||||
with open(filename) as fd:
|
||||
return fd.read()
|
||||
|
||||
filename = os.path.join(get_publisher().data_dir, 'themes', current_theme, 'template.ezt')
|
||||
if os.path.exists(filename):
|
||||
with open(filename) as fd:
|
||||
return fd.read()
|
||||
|
||||
return DEFAULT_TEMPLATE_EZT
|
||||
|
||||
|
||||
def get_decorate_vars(body, response, generate_breadcrumb=True, **kwargs):
|
||||
from .publisher import get_cfg
|
||||
|
||||
|
@ -303,18 +150,8 @@ def get_decorate_vars(body, response, generate_breadcrumb=True, **kwargs):
|
|||
subtitle = kwargs.get('subtitle')
|
||||
sidebar = kwargs.get('sidebar')
|
||||
css = root_url + get_publisher().qommon_static_dir + get_publisher().qommon_admin_css
|
||||
|
||||
app_dir_filename = os.path.join(get_publisher().app_dir, 'themes', current_theme, 'admin.css')
|
||||
data_dir_filename = os.path.join(get_publisher().data_dir, 'themes', current_theme, 'admin.css')
|
||||
for filename in (app_dir_filename, data_dir_filename):
|
||||
if os.path.exists(filename):
|
||||
extra_css = root_url + 'themes/%s/admin.css' % current_theme
|
||||
break
|
||||
extra_head = get_publisher().get_site_option('backoffice_extra_head')
|
||||
app_label = get_publisher().get_site_option('app_label') or 'w.c.s.'
|
||||
else:
|
||||
if current_theme == 'default':
|
||||
css = root_url + 'static/css/%s.css' % get_publisher().APP_NAME
|
||||
else:
|
||||
css = root_url + 'themes/%s/%s.css' % (current_theme, get_publisher().APP_NAME)
|
||||
|
||||
|
@ -354,53 +191,6 @@ def get_decorate_vars(body, response, generate_breadcrumb=True, **kwargs):
|
|||
return vars
|
||||
|
||||
|
||||
def decorate(body, response):
|
||||
if get_request().get_header('x-popup') == 'true':
|
||||
return '''<div class="popup-content"> %s </div>''' % body
|
||||
|
||||
from .publisher import get_cfg
|
||||
|
||||
generate_breadcrumb = True
|
||||
template_ezt = get_cfg('branding', {}).get('template')
|
||||
current_theme = get_cfg('branding', {}).get('theme', 'default')
|
||||
if not template_ezt:
|
||||
# the theme can provide a default template
|
||||
possible_filenames = []
|
||||
possible_filenames.append('template.%s.ezt' % get_publisher().APP_NAME)
|
||||
possible_filenames.append('template.ezt')
|
||||
|
||||
possible_dirnames = [
|
||||
os.path.join(get_publisher().app_dir, 'themes', current_theme),
|
||||
os.path.join(get_publisher().data_dir, 'themes', current_theme),
|
||||
os.path.join(get_publisher().data_dir, 'themes', 'default'),
|
||||
]
|
||||
|
||||
for fname in possible_filenames:
|
||||
for dname in possible_dirnames:
|
||||
filename = os.path.join(dname, fname)
|
||||
if os.path.exists(filename):
|
||||
with open(filename) as fd:
|
||||
template_ezt = fd.read()
|
||||
break
|
||||
else:
|
||||
continue
|
||||
break
|
||||
|
||||
if template_ezt:
|
||||
generate_breadcrumb = '[breadcrumb]' in template_ezt
|
||||
|
||||
template = ezt.Template()
|
||||
template.parse(template_ezt)
|
||||
else:
|
||||
template = default_template
|
||||
|
||||
fd = io.StringIO()
|
||||
vars = get_decorate_vars(body, response, generate_breadcrumb=generate_breadcrumb)
|
||||
|
||||
template.generate(fd, vars)
|
||||
return fd.getvalue()
|
||||
|
||||
|
||||
def render(template_name, context):
|
||||
request = getattr(get_request(), 'django_request', None)
|
||||
result = render_to_string(template_name, context, request=request)
|
||||
|
|
|
@ -265,7 +265,6 @@ class RootDirectory(Directory):
|
|||
]
|
||||
|
||||
api = ApiDirectory()
|
||||
themes = template.ThemesDirectory()
|
||||
myspace = MyspaceDirectory()
|
||||
pages = PagesDirectory()
|
||||
fargo = portfolio.FargoDirectory()
|
||||
|
|
|
@ -38,7 +38,7 @@ class TemplateLoader(django.template.loaders.filesystem.Loader):
|
|||
template_dirs.append(os.path.join(get_publisher().app_dir, 'templates'))
|
||||
template_dirs.append(os.path.join(get_publisher().app_dir, 'theme', 'templates'))
|
||||
|
||||
current_theme = get_cfg('branding', {}).get('theme', 'default')
|
||||
current_theme = get_cfg('branding', {}).get('theme', get_publisher().default_theme)
|
||||
theme_directory = get_theme_directory(current_theme)
|
||||
if theme_directory:
|
||||
# templates from theme directory
|
||||
|
|
Loading…
Reference in New Issue