remove old cms, switch to wagtail; move website to cms

This commit is contained in:
bkfox
2016-07-22 05:50:00 +02:00
parent 4bbffa9a50
commit ba3bf68e33
50 changed files with 950 additions and 4836 deletions

View File

@ -1,301 +0,0 @@
/// Actions manager
/// This class is used to register actions and to execute them when it is
/// triggered by the user.
var Actions = {
registry: {},
/// Add an handler for a given action
register: function(id, symbol, title, handler) {
this.registry[id] = {
symbol: symbol,
title: title,
handler: handler,
}
},
/// Init an existing action HTML element
init_action: function(item, action_id, data, url) {
var action = this.registry[action_id];
if(!action)
return;
item.title = action.title;
item.innerHTML = (action.symbol || '') + '<label>' +
action.title + '</label>';
item.data = data;
item.className = 'action';
if(url)
item.href = url;
item.setAttribute('action', action_id);
item.addEventListener('click', Actions.run, true);
},
/// Add an action to the given item
add_action: function(item, action_id, data, url) {
var actions = item.querySelector('.actions');
if(actions && actions.querySelector('[action="' + action_id + '"]'))
return;
var item = document.createElement('a');
this.init_action(item, action_id, data, url);
actions.appendChild(item);
},
/// Run an action from the given event -- ! this can be undefined
run: function(event) {
var item = event.target;
var action = item.hasAttribute('action') &&
item.getAttribute('action');
if(!action)
return;
event.preventDefault();
event.stopImmediatePropagation();
action = Actions.registry[action];
if(!action)
return;
action.handler(item.data || item.dataset, item);
return true;
},
};
/*
document.addEventListener('DOMContentLoaded', function(event) {
var items = document.querySelectorAll('.action[action]');
for(var i = 0; i < items.length; i++) {
var item = items[i];
var action_id = item.getAttribute('action');
var data = item.dataset;
Actions.init_action(item, action_id, data);
}
}, false);
*/
/// Small utility used to make XMLHttpRequests, and map results on objects.
/// This is intended to dynamically retrieve Section and exposed data.
///
/// Request.Selector is a utility class that can be used to map data using
/// selectors.
///
/// Since there is no a common method to render items in JS and Django, we
/// retrieve items yet rendered, and select data over it.
function Request_(url = '', params = '') {
this.url = url;
this.params = params;
this.selectors = [];
this.actions = [];
}
Request_.prototype = {
/// XMLHttpRequest object used to retrieve data
xhr: null,
/// delayed actions that have been registered
actions: null,
/// registered selectors
selectors: null,
/// parse request result and save in this.stanza
__parse_dom: function() {
if(self.stanza)
return;
var doc = document.implementation.createHTMLDocument('xhr').documentElement;
doc.innerHTML = this.xhr.responseText;
this.stanza = doc;
},
/// make an xhr request, and call callback(err, xhr) if given
get: function() {
var self = this;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState != 4)
return
// TODO: error handling
var err = self.xhr.status != 200 && self.xhr.status;
if(err)
return;
for(var i = 0; i < self.actions.length; i++)
self.actions[i].apply(self);
}
if(this.params)
xhr.open('GET', this.url + '?' + this.params, true);
else
xhr.open('GET', this.url, true);
this.xhr = xhr;
return this;
},
/// send request
send: function() {
this.xhr.send();
return this;
},
/// set selectors.
/// * callback: if set, call it once data are downloaded with an object
/// of elements matched with the given selectors only. The object is
/// made of `selector_name: select_result` items.
select: function(selectors, callback = undefined) {
for(var i in selectors) {
selector = selectors[i];
if(!selector.sort)
selector = [selector]
selector = new Request_.Selector(i, selector[0], selector[1], selector[2])
selectors[i] = selector;
this.selectors.push(selector)
}
if(callback) {
var self = this;
this.actions.push(function() {
self.__parse_dom();
var r = {}
for(var i in selectors) {
r[i] = selectors[i].select(self.stanza);
}
callback(r);
});
}
return this;
},
/// map data using this.selectors on xhr result *and* dest
map: function(dest) {
var self = this;
this.actions.push(function() {
self.__parse_dom();
for(var i = 0; i < self.selectors.length; i++) {
selector = self.selectors[i]
selector.map(self.stanza, dest);
}
});
return this;
},
/// add an action to the list of actions
on: function(callback) {
this.actions.push(callback)
return this;
},
};
Request_.Selector = function(name, selector, attribute = null, all = false) {
this.name = name;
this.selector = selector;
this.attribute = attribute;
this.all = all;
}
Request_.Selector.prototype = {
select: function(obj, use_attr = true) {
if(!this.all) {
obj = obj.querySelector(this.selector)
return (this.attribute && use_attr && obj) ? obj[this.attribute] : obj;
}
obj = obj.querySelectorAll(this.selector);
if(!obj)
return;
r = []
for(var i = 0; i < obj.length; i++) {
r.push(this.attribute && use_attr ? obj[i][this.attribute] : obj[i])
}
return r;
},
map: function(src, dst) {
src_qs = this.select(src, false);
dst_qs = this.select(dst, false);
if(!src_qs || !dst_qs)
return
if(!this.all) {
src_qs = [ src_qs ];
dst_qs = [ dst_qs ];
}
var size = Math.min(src_qs.length, dst_qs.length);
for(var i = 0; i < size; i++) {
var src = src_qs[i];
var dst = dst_qs[i];
if(this.attribute)
dst[this.attribute] = src[this.attribute] || '';
else
dst.parentNode.replaceChild(src, dst);
}
},
}
/// Just to by keep same convention between utilities
/// Create an instance of Request_
function Request(url = '', params = '') {
return new Request_(url, params);
}
var Section = {
/// Return the parent section of a DOM element. Compare it using its
/// className. If not class_name is given, use "section"
get_section: function(item, class_name) {
class_name = class_name || 'section';
while(item) {
if(item.className && item.className.indexOf(class_name) != -1)
break
item = item.parentNode;
}
return item;
},
/// Load a section using the given url and parameters, update the header,
/// the content and the footer automatically. No need to add "embed" in
/// url params.
///
/// If find_section is true, item is a child of the wanted section.
///
/// Return a Request.Selector
load: function(item, url, params, find_section) {
if(find_section)
item = this.get_section(item);
var rq = Request(url, 'embed&' + (params || ''))
return rq.get().select({
'header': ['header', 'innerHTML', true],
'content': ['.content', 'innerHTML', true],
'footer': ['footer', 'innerHTML', true]
}).map(item).send();
},
/// Load a Section on event, and handle it.
load_event: function(event, params) {
var item = event.currentTarget;
var url = item.getAttribute('href');
event.preventDefault();
this.load(item, url, params, true);
return true;
},
}

View File

@ -1,155 +0,0 @@
/** main layout **/
body {
padding: 0;
margin: 0;
}
.page {
display: flex;
}
.page .menu {
width: 20em;
}
.page .menu_left { margin-right: 0.5em; }
.page .menu_right { margin-left: 0.5em; }
.page main {
flex-grow: 1;
}
.section {
vertical-align: top;
}
/** detail and list content **/
main .section {
/* width: calc(50% - 2em);
display: inline-block; */
padding: 0.5em;
}
main .section .section_content {
font-size: 0.95em;
}
main .section h1 {
font-size: 1.2em;
}
main .section * {
max-width: 100%;
}
.post_item {
display: block;
}
/** comments **/
.comments form input:not([type=checkbox]),
.comments form textarea {
display: inline-block;
width: 100%;
max-height: 6em;
margin: 0.2em 0em;
padding: 0.2em;
}
.comments form input[type=checkbox],
.comments form button[type=submit] {
vertical-align:bottom;
margin: 0.2em 0em;
text-align: center;
}
.comments form button[type=submit] {
float: right;
}
.comments form #show_more:not(:checked) ~ .extra {
display: none;
}
.comments label[for="show_more"] {
font-size: 0.8em;
}
/** calendar **/
.section_calendar header {
border-bottom: 1px black solid;
width: 100%;
}
.section_calendar header h3,
.section_calendar header a {
display: inline-block;
width: 2em;
padding: 0;
margin: 0;
font-size: 1em;
}
.section_calendar header h3 {
width: calc(100% - 4em);
text-align: center;
}
.section_calendar header a:last-child {
text-align: right;
}
.section_calendar .content {
padding: 0.2em;
margin: 0;
font-size: 0.9em;
}
.section_calendar .content > * {
padding: 0;
margin: 0;
text-align: right;
display: inline-block;
}
.section_calendar .content a {
width: calc(100% / 7);
}
.section_calendar .content a.today {
font-style: italic;
}
.section_calendar div[first_weekday] {
width: 0;
}
.section_calendar div[first_weekday="1"] {
width: calc(100% / 7);
}
.section_calendar div[first_weekday="2"] {
width: calc(100% / 7 * 2);
}
.section_calendar div[first_weekday="3"] {
width: calc(100% / 7 * 3);
}
.section_calendar div[first_weekday="4"] {
width: calc(100% / 7 * 4);
}
.section_calendar div[first_weekday="5"] {
width: calc(100% / 7 * 5);
}
.section_calendar div[first_weekday="6"] {
width: calc(100% / 7 * 6);
}