File List
{% set ajax = TRUE %}
{% set fwutils = TRUE %}
{% set validate = TRUE %}
{% set editable = FALSE %}
{% set usebootbox = FALSE %}
{% set breadcrumbs = [{link: base, text: 'Home'}, {link: base ~ '/admin/', text: 'Admin'}, {text: 'Pages'}] %}
{% extends '@content/page.twig' %}
{% import '@content/iconmacro.twig' as i %}
{% import '@util/formmacro.twig' as f %}
{% import '@util/modalmacro.twig' as m %}
{% set types = ['Object', 'Template', 'In-site 302', 'In-site 301',
'External 302', 'External 301', 'In-site 303', 'External 303',
'In-site 307', 'External 307',
'In-site 308', 'External 308'] %}
{% block css %}
<link rel="stylesheet" href="{{assets}}/css/inline.min.css"/>
{% endblock css %}
{% block scripts %}
<script src="{{assets}}/js/fw-editable.js?v=1"></script>
{% endblock scripts %}
{% block setup %}
function mkinline(type, name, msg, id, value)
{
return '{{f.editable({type: f.wrap('type'), field: f.wrap('name'), title: f.wrap('msg'), key: f.wrap('id'), value: f.wrap('value')})}}';
}
function golink(event)
{
window.location = event.target.parentNode.getAttribute('href');
}
const kname = [
{% for v in types %}
{value: {{loop.index}}, text: '{{v}}'}{{loop.last ? '' : ','}}
{% endfor %}
];
const clicks = [
['delb', framework.dodelbean, ''],
['actb', framework.dotoggle, 'active'],
['logn', framework.dotoggle, 'needlogin'],
['mobo', framework.dotoggle, 'mobileonly'],
['editb', framework.goedit, ''],
['linkb', golink, '']
]
{% endblock setup %}
{% block onload %}
document.querySelectorAll('.editable').forEach(function(edb){
fweditable.editable(edb, {
op: 'bean',
bean: '{{constant('Config\\Framework::PAGE')}}',
source: kname,
update: fweditable.editUpdate
});
});
fwdom.on('#npform', 'submit', fwdom.nosubmit);
fwdom.mkjQ('#npform').parsley();
fwdom.on('#npkind', 'change', function(e) {
fwdom.stop(e);
var pn = document.getElementById('npname').value.toLowerCase();
if (pn !== '')
{
switch (this.value)
{
case '1':
document.getElementById('npsrc').value = '\\Pages\\'+pn.substr(0,1).toUpperCase()+pn.substr(1);
break;
case '2':
document.getElementById('npsrc').value = '@content/'+pn+'.twig';
break;
}
}
})
fwdom.on('#addb', 'click', function(e){
fwdom.stop(e);
this.disabled = true; // disable submit button
const pn = document.getElementById('npname').value.toLowerCase();
if (!pn.match(/^[a-z][a-z0-9.]*$/))
{
framework.alert('"'+pn+'" is not a valid page name. Letters and numbers only');
return;
}
let sp = null;
let error = false;
for (let el of document.getElementsByClassName('pname'))
{
const t = el.innerHTML;
if (t == pn)
{
error = true;
break;
}
if (t > pn)
{
sp = this;
break;
}
}
if (error)
{
framework.alert('That page already exists');
this.disabled = false;
return;
}
const src = document.getElementById('npsrc').value;
if (src == '')
{
framework.alert('Please specify a source');
this.disabled = false;
return;
}
const kind = document.getElementById('npkind').value;
if (kind == '')
{
framework.alert('Please pick a page type');
this.disabled = false;
return;
}
const active = document.getElementById('npactive').checked ? 1 : 0;
const login = document.getElementById('nplogin').checked ? 1 : 0;
const mobile = document.getElementById('npmobile').checked ? 1 : 0;
var fn = function(data){
framework.addElement(document.getElementById('ptab'), 'tr', {'data-id': data}, '<td>'+mkinline('text', 'name', 'Enter name', data, pn)+'</td>'+
'<td>'+mkinline('select', 'kind', 'Enter kind', data, kname[kind-1].text)+'</td>'+
'<td>'+mkinline('text', 'source', 'Enter source', data, document.getElementById('npsrc').value)+'</td>'+
'<td>'+framework.mktoggle('logn', login)+'</td>'+
'<td>'+framework.mktoggle('mobo', mobile)+'</td>'+
'<td>'+framework.mktoggle('actb', active)+'</td>'+
'<td><a href="'+base+'/'+pn+'">{{i.link('linkb')}}</a></td>'+
'<td>{{i.edit('editb')}}</td>'+
'<td>{{i.delete('delb')}}</td>', sp);
bootstrap.Modal.getOrCreateInstance(document.getElementById('npage')).hide();
//fwdom.mkjQ('.ppedit', nx).editable({params: paramset, source: kname});
};
let dt = {
name : pn,
kind : kind,
source : src,
active : active,
needlogin : login,
mobileonly: mobile
};
const f = document.getElementById('npform');
for (let nv of ['start', 'end', 'otherinfo'])
{
f.querySelectorAll('input[name^="'+nv+'"]').forEach(function(el, index){
dt[nv+'['+index+']'] = el.value;
});
}
for (let sv of ['context', 'role'])
{
f.querySelectorAll('select[name^="'+sv+'"]').forEach(function(el, index){
dt[sv+'['+index+']'] = el.options[el.selectedIndex].value;
});
}
framework.beanCreate('{{constant('Config\\Framework::PAGE')}}', dt, fn, 'addb');
});
fwdom.on('#ptab', 'click', function(e){ e.data = {bean: '{{constant('Config\\Framework::PAGE')}}', clicks: clicks}; framework.containerClick(e);});
fwdom.on('#npage', 'show.bs.modal', function(e){
document.getElementById('npform').reset();
});
fwdom.on('#more', 'click', framework.addMore);
{% endblock onload %}
{% if not page is defined %}
{% set page = 1 %}
{% set pagesize = 10 %}
{% endif %}
{% set pages = siteinfo.pagecount('page', pagesize) %}
{% block headerbody %}
<h1>Pages</h1>
{% endblock headerbody %}
{% block main %}
<section class="row">
<article class="offset-md-1 col">
{% include '@util/paginate.twig' with { page : page, pagesize: pagesize, pages: pages} %}
<table class="table table-responsive table-striped table-hover">
<thead class="thead-inverse">
<tr>
<th>Name</th>
<th>Kind</th>
<th>Source</th>
<th>Login Req.</th>
<th>Mobile Only</th>
<th>Active</th>
<th colspan="3"> </th>
</tr>
</thead>
<tbody id="ptab">
{% for p in siteinfo.pages(page, pagesize) %}
<tr data-id="{{p.getID}}">
<td class="pname">{{f.editable({type: 'text', field: 'name', title: 'Enter name', key: p.getID, value: p.name})}}</td>
<td>{{f.editable({type: 'select', field: 'kind', title: 'Enter kind', key: p.getID, value: types[p.kind-1]})}}</td>
<td>{{f.editable({type: 'text', field: 'source', title: 'Enter source', key: p.getID, value: p.source})}}</td>
<td>{{f.tick(p.needlogin, 'logn')}}</td>
<td>{{f.tick(p.mobileonly, 'mobo')}}</td>
<td>{{f.tick(p.active, 'actb')}}</td>
<td><a href="{{base}}/{{p.name}}">{{i.link('linkb')}}</a></td>
<td>{{i.edit('editb')}}</td>
<td>{{i.delete('delb')}}</td>
</tr>
{% else %}
<tr><td colspan="4">No pages defined</td></tr>
{% endfor %}
</tbody>
</table>
{% include '@util/paginate.twig' with { page : page, pagesize: pagesize, pages: pages} %}
<p>{{m.invoke('npage', 'Add Page')}}</p>
</article>
</section>
{{m.open({id: 'npage', title: 'New Page'})}}
<div class="modal-body">
{{f.startform({method: 'post', id: 'npform'})}}
{{f.text({label: 'Name', id: 'npname', ph: 'Page name - alphanumeric characters only', required: TRUE,
valid: { trigger: 'blur', type: 'alphanum', 'remote-reverse': 'false', remote: "#{base}/ajax/unique/#{constant('Config\\Framework::PAGE')}/name/{value}",
'remote-message': 'That page already exists'} })}}
{{f.select({label: 'Kind', id: 'npkind', required: TRUE, options:[
{value: '', text: '— Pick a Type —'},
{value: 1, text: 'Object'},
{value: 2, text: 'Template'},
{value: 4, text: 'In-site 301'},
{value: 6, text: 'External 301'},
{value: 3, text: 'In-site 302'},
{value: 5, text: 'External 302'},
{value: 7, text: 'In-site 303'},
{value: 8, text: 'External 303'},
{value: 9, text: 'In-site 307'},
{value: 10, text: 'External 307'},
{value: 11, text: 'Internal 308'},
{value: 12, text: 'External 308'},
]})}}
{{f.text({label: 'Source', id: 'npsrc', ph: 'page.twig, class name, /local/redirection or URL', required: TRUE})}}
{{f.checkbox({labels: ['Active'], values:[1], ids: ['npactive']})}}
{{f.checkbox({labels: ['Mobile Only'], values:[1], ids: ['npmobile']})}}
{{f.checkbox({labels: ['Login Required'], values:[1], ids: ['nplogin']})}}
<fieldset>
<legend>Roles</legend>
<table class="table table-striped">
<thead>
<tr>
<th>Context</th>
<th>Role</th>
<th>Start</th>
<th>End</th>
<th>Other Info</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr id="example">
<td>
<select name="context[]">
<option value="">— Context —</option>
{% for sr in siteinfo.contexts %}
<option value="{{sr.getID}}">{{sr.name}}</option>
{% endfor %}
</select>
</td>
<td>
<select name="role[]">
<option value="">— Role —</option>
{% for sr in siteinfo.roles %}
<option value="{{sr.getID}}">{{sr.name}}</option>
{% endfor %}
</select>
</td>
<td><input type="text" name="start[]" value="" placeholder="Start Date or Now" class="form-control"/></td>
<td><input type="text" name="end[]" value="" placeholder="End Date or Never" class="form-control"/></td>
<td><input type="text" name="otherinfo[]" value="" placeholder="Other Info" class="form-control"/></td>
</tr>
<tr id="mrow">
<td colspan="4"> </td>
<td><button id="more" class="btn btn-xs btn-info float-end">Add More</button></td>
</tr>
</tbody>
</table>
</fieldset>
{{f.endform()}}
</div>
{{m.close({action: 'Add', id: 'addb'})}}
{% endblock main %}
{% block pagefooter %}
{% endblock pagefooter %}