";
$button = $this->modules->get('InputfieldButton');
$button->href = "./add";
$button->value = $this->labels['Add New'];
$button->icon = 'plus-circle';
$button->addClass('add_template_button head_button_clone');
$out .= $button->render();
$button = $this->modules->get('InputfieldButton');
$button->id = 'import_button';
$button->href = "./import/";
$button->value = $this->labels['Import'];
$button->icon = 'paste';
$button->addClass('ui-priority-secondary');
$out .= $button->render();
$button = $this->modules->get('InputfieldButton');
$button->id = 'export_button';
$button->href = "./export/";
$button->value = $this->labels['Export'];
$button->icon = 'copy';
$button->addClass('ui-priority-secondary');
$out .= $button->render();
if($this->input->nosave) {
$this->session->remove('ProcessTemplateFilterSystem');
$this->session->remove('ProcessTemplateFilterField');
}
return $out;
}
public function ___getListFilterForm() {
$form = $this->modules->get("InputfieldForm");
$form->id = 'filters';
$form->method = 'get';
$form->action = './';
$fieldset = $this->modules->get("InputfieldFieldset");
$fieldset->entityEncodeLabel = false;
$fieldset->label = $this->_("Filters"); // Template list filters headline
$fieldset->icon = 'filter';
$fieldset->collapsed = Inputfield::collapsedYes;
$form->add($fieldset);
// --------------------------------------
$field = $this->modules->get("InputfieldSelect");
$field->attr('id+name', 'filter_field');
$field->label = $this->_("Filter by Field");
$field->description = $this->_("Select a field and only templates using that field will be shown."); // Filter by Field, description
$field->addOption('', $this->_x('Show All', 'filter-select'));
foreach($this->fields as $f) {
$name = $f->name;
if(($f->flags & Field::flagSystem) || ($f->flags & Field::flagPermanent)) $name .= "*";
$field->addOption($f->name, $name);
}
if($this->input->get->filter_field !== null) {
$filterField = $this->sanitizer->name($this->input->get->filter_field);
$this->session->ProcessTemplateFilterField = $filterField;
} else {
$filterField = $this->session->ProcessTemplateFilterField;
}
$field->attr('value', $filterField);
$field->collapsed = $filterField ? Inputfield::collapsedNo : Inputfield::collapsedYes;
$fieldset->add($field);
if($filterField) $filterField = $this->fields->get($filterField);
if($filterField) $form->description = sprintf($this->_('Templates with field: %s'), $filterField->name);
// --------------------------------------
if(!$filterField) {
$field = $this->modules->get("InputfieldRadios");
$field->label = $this->_("Show system templates?");
$field->description = $this->_("By default, system/internal templates are not shown. Click 'Yes' to have them included in the templates list below."); // Show system templates, description
$field->attr('id', 'filter_system');
$field->attr('name', 'system');
$field->addOption(1, $this->labels['Yes']);
$field->addOption(0, $this->labels['No']);
if($this->input->get->system !== null) {
$filterSystem = (int) $this->input->get->system;
$this->session->ProcessTemplateFilterSystem = $filterSystem;
} else {
$filterSystem = (int) $this->session->ProcessTemplateFilterSystem;
}
$field->attr('value', $filterSystem);
$field->collapsed = $filterSystem ? Inputfield::collapsedNo : Inputfield::collapsedYes;
$fieldset->add($field);
} else $filterSystem = 0;
if($filterSystem || $filterField) $fieldset->collapsed = Inputfield::collapsedNo;
return $form;
}
public function ___getListTable($templates) {
$table = $this->modules->get("MarkupAdminDataTable");
$table->setEncodeEntities(false);
$useLabels = false;
foreach($templates as $template) {
$label = $template->getLabel();
if($label && $label != $template->name) {
$useLabels = true;
break;
}
}
$rows = array();
foreach($templates as $template) {
$row = $this->getListTableRow($template, $useLabels);
if(!empty($row)) $rows[] = $row;
}
$header = array();
$header[] = $this->_x('Name', 'list-thead');
if($useLabels) $header[] = $this->_x('Label', 'list-thead');
$header[] = $this->_x('Fields', 'list-thead');
$header[] = $this->_x('Pages', 'list-thead');
$header[] = $this->_x('Modified', 'list-thead');
$header[] = ' ';
$table->headerRow($header);
foreach($rows as $row) $table->row($row);
return $table;
}
public function ___getListTableRow(Template $template, $useLabel = true) {
$flags = array();
$flagDefs = array(
'system' => array(
'label' => $this->_x('system', 'list-note'),
'icon' => 'puzzle-piece'
),
'access' => array(
'label' => $this->_x('access', 'list-note'),
'icon' => 'key'
),
'no-file' => array(
'label' => $this->_x('no-file', 'list-note'),
'icon' => 'ban'
),
'cache' => array(
'label' => $this->_x('cache', 'list-note'),
'icon' => 'clock-o'
),
'url-segments' => array(
'label' => $this->_x('URL segments', 'list-note'),
'icon' => 'sitemap'
),
'page-numbers' => array(
'label' => $this->_x('Page numbers', 'list-note'),
'icon' => 'list-ol'
)
);
$notes = '';
$filterField = $this->session->ProcessTemplateFilterField;
$filterSystem = $this->session->ProcessTemplateFilterSystem;
if($template->flags & Template::flagSystem) {
if(!$filterSystem && !$filterField) return array();
$flags[] = 'system';
}
if($filterField && !$template->fieldgroup->has($filterField)) return array();
if($template->useRoles) $flags[] = 'access';
if(!$template->filenameExists()) $flags[] = 'no-file';
if($template->cache_time > 0) $flags[] = 'cache';
if($template->urlSegments) $flags[] = 'url-segments';
if($template->allowPageNum) $flags[] = 'page-numbers';
$notes = '';
foreach($flags as $flag) {
$class = 'templateFlag' . ucfirst($flag);
$flag = $flagDefs[$flag];
$label = str_replace('-', ' ', ucfirst($flag['label']));
$notes .= " ";
}
$numPages = $template->getNumPages();
$numPagesLink = $this->config->urls->admin . "page/search/?show_options=1&template={$template->name}&sort=title";
$numFields = count($template->fieldgroup);
if($template->fieldgroup && $template->fieldgroup->name != $template->name) $numFields .= " " . $template->fieldgroup->name;
$numFieldsLink = "../field/?templates_id={$template->id}&nosave=1";
$row = array();
$row["{$template->name} "] = "edit?id={$template->id}";
if($useLabel) $row[] = $this->sanitizer->entities($template->getLabel());
$row[] = "$numFields ";
$row["{$numPages} "] = "$numPagesLink"; // space is required to make it work
$row[] = $template->modified > 0 ? "$template->modified" . wireRelativeTimeStr($template->modified) : '';
$row[] = $notes;
return $row;
}
/**
* Execute the template add process
*
*/
public function ___executeAdd() {
$this->fuel('breadcrumbs')->add(new Breadcrumb('./', $this->moduleInfo['title']));
$this->setFuel('processHeadline', $this->_('Add New Templates')); // Headline when adding templates
$dir = new DirectoryIterator($this->fuel('config')->paths->templates);
$templateFiles = array();
$ext = "." . $this->config->templateExtension;
$prependTemplateFile = $this->config->prependTemplateFile;
$appendTemplateFile = $this->config->appendTemplateFile;
$ignoreRegex = $this->wire('config')->ignoreTemplateFileRegex;
foreach($dir as $file) {
if($file->isDir() || $file->isDot()) continue;
$filename = $file->getFilename();
if($filename == $prependTemplateFile || $filename == $appendTemplateFile) continue; // skip over prepend/append files
if(substr($filename, -1 * strlen($ext)) != $ext) continue;
if($ignoreRegex && preg_match($ignoreRegex, $filename)) continue;
$basename = basename($file->getFilename(), $ext);
if(count($this->fuel('templates')->find("name=$basename"))) continue;
$templateFiles[] = $basename;
}
if(count($this->input->post)) {
$this->session->CSRF->validate();
$importFieldgroup = null;
$importFields = array();
if($this->input->post->import_fieldgroup) {
$importFieldgroup = $this->fieldgroups->get($this->sanitizer->name($this->input->post->import_fieldgroup));
} else {
// find global fields
foreach($this->fields as $field) {
if($field->flags & Field::flagGlobal) {
$importFields[] = $field;
}
}
}
$postTemplates = $this->input->post->templates;
// add any templates without files to the postTemplates
if($this->input->post->template_name) {
$templateName = trim($this->input->post->template_name);
if(strpos($templateName, ' ')) $templateNames = explode(' ', $templateName);
else $templateNames = array($templateName);
foreach($templateNames as $name)
$postTemplates[] = basename($name);
}
foreach($postTemplates as $basename) {
// if(!in_array($basename, $templateFiles)) continue;
$template = new Template();
$template->name = $this->fuel('sanitizer')->name($basename);
$fieldgroup = new Fieldgroup();
$fieldgroup->name = $template->name;
$fieldgroup->save();
$template->fieldgroup = $fieldgroup;
$template->roles = array($this->roles->getGuestRole()->id);
$template->save();
$this->message(sprintf($this->_('Added template and fieldgroup: %s'), $basename));
if($importFieldgroup) {
$this->importFieldgroup($importFieldgroup, $template);
$template->fieldgroup->save();
} else if(count($importFields)) { // global fields
foreach($importFields as $field) {
$template->fieldgroup->add($field);
$this->fieldAdded($field, $template);
}
$template->fieldgroup->save();
}
}
$this->session->redirect('./');
}
$form = $this->buildAddForm($templateFiles);
if(count($this->input->post)) $form->processInput($this->input->post);
return $form->render();
}
/**
* Build the form used for adding templates
*
*/
protected function buildAddForm($templateFiles) {
$templateUrl = $this->fuel('config')->urls->templates;
$form = $this->modules->get('InputfieldForm');
$form->attr('id', 'ProcessTemplateAdd');
$form->attr('action', 'add');
$form->attr('method', 'post');
//$form->description = "This action looks for new template files (ending with .{$this->config->templateExtension}) in $templateUrl";
if(count($templateFiles)) {
$field = $this->modules->get('InputfieldCheckboxes');
$field->label = sprintf($this->_('Templates found in: %s'), "$templateUrl*.{$this->config->templateExtension}");
$field->description = $this->_('The following new templates were found. Check the box next to each template you want to add.'); // Templates found, description
$field->attr('id+name', 'templates');
foreach($templateFiles as $file) $field->addOption($file);
$form->append($field);
} else {
$this->error(sprintf($this->_('No new template files were found in: %s'), "$templateUrl*.{$this->config->templateExtension}")); // Error message when no new templates found
}
$field = $this->modules->get("InputfieldText");
$field->label = $this->_('Create a new template without a file');
$field->description = $this->_('If you want to create a new template even though there is currently no file associated with it, enter the name of the template here.'); // Create template with no file, description
$field->description .= ' ' . $this->_('You may enter multiple template names by separating each with a space.');
$field->notes = $this->_('Do not include a file extension');
$field->attr('id+name', 'template_name');
$field->collapsed = count($templateFiles) ? Inputfield::collapsedYes : Inputfield::collapsedNo;
$form->append($field);
$form->append($this->buildEditFormImport());
$field = $this->modules->get('InputfieldSubmit');
$field->attr('value', $this->_n('Add Template', 'Add Templates', count($templateFiles)));
$form->append($field);
return $form;
}
/**
* Execute the template edit process
*
*/
public function ___executeEdit() {
$this->fuel('breadcrumbs')->add(new Breadcrumb('./', $this->moduleInfo['title']));
$this->setFuel('processHeadline', sprintf($this->_('Edit Template: %s'), $this->template->name)); // Headline when editing a template
if(!$this->template) throw new WireException("No Template specified");
$this->form = $this->buildEditForm($this->template);
$out = $this->form->render();
return $out;
}
/**
* Build the main form used for template edits
*
*/
protected function ___buildEditForm(Template $template) {
$languages = wire('languages');
$form = $this->modules->get('InputfieldForm');
$form->attr('id', 'ProcessTemplateEdit');
$form->attr('action', "save");
$form->attr('method', 'post');
if(!is_file($template->filename) && !count($this->input->post)) {
$this->message(sprintf($this->_('Pages using this template are not viewable because the template file (%s) does not exist [no-file].'), $template->name . '.' . $this->config->templateExtension));
}
$t = new InputfieldWrapper();
$t->attr('title', $this->_x('Basics', 'tab'));
$t->attr('class', 'WireTab');
// $head = sprintf($this->_n('This template is used by 1 page', 'This template is used by %d pages', $this->numPages), $this->numPages);
// if($this->numPages) $head = str_replace(" {$this->numPages} ", " [{$this->numPages}]({$this->config->urls->admin}page/search/?show_options=0&template={$template->name}) ", $head);
// $t->head = $head;
$f = $this->modules->get('InputfieldText');
$f->attr('name', 'templateLabel');
$f->attr('value', $template->label);
$f->label = $this->_x('Label', 'field-label');
$f->description = $this->_('An optional label to describe this template.');
$f->collapsed = Inputfield::collapsedBlank;
if($languages) {
$f->useLanguages = true;
foreach($languages as $language) $f->set('value' . $language->id, $template->get('label' . $language->id));
}
$t->add($f);
$t->add($this->buildEditFormFields($template));
if($template->name != $template->fieldgroup->name || $this->config->advanced) $t->add($this->buildEditFormFieldgroup($template));
$form->add($t);
$t = new InputfieldWrapper();
$t->attr('title', $this->_x('Access', 'tab'));
// $t->head = $this->_('Manage template access');
$t->attr('class', 'WireTab');
$t->add($this->buildEditFormAccess($template));
$form->add($t);
$t = new InputfieldWrapper();
$t->attr('title', $this->_x('Family', 'tab'));
// $t->head = $this->_('Optional usage and placement in the page tree');
$t->attr('class', 'WireTab');
$t->add($this->buildEditFormFamily($template));
$form->add($t);
$t = new InputfieldWrapper();
$t->attr('title', $this->_x('URLs', 'tab'));
// $t->head = $this->_('Optional settings for URLs of pages using this template');
$t->attr('class', 'WireTab');
$t->add($this->buildEditFormURLs($template));
$form->add($t);
$t = new InputfieldWrapper();
$t->attr('title', $this->_x('Files', 'tab'));
$t->attr('class', 'WireTab');
$t->add($this->buildEditFormFile($template));
$form->add($t);
$t = new InputfieldWrapper();
$t->attr('title', $this->_x('Cache', 'tab'));
// $t->head = $this->_("Output caching");
$t->attr('class', 'WireTab');
$t->add($this->buildEditFormCache($template));
$form->add($t);
$t = new InputfieldWrapper();
$t->attr('title', $this->_x('Advanced', 'tab'));
// $t->head = $this->_('Optional advanced template settings');
$t->attr('class', 'WireTab');
$t->add($this->buildEditFormAdvanced($template));
$form->add($t);
if($this->config->advanced) {
$t = new InputfieldWrapper();
$t->attr('title', $this->_x('System', 'tab'));
// $t->head = $this->_('System-specific template settings');
$t->attr('class', 'WireTab');
$t->add($this->buildEditFormSystem($template));
$form->add($t);
}
$t = new InputfieldWrapper();
$t->attr('class', 'WireTab');
$t->attr('title', $this->_x('Import', 'tab'));
// $t->head = $this->_('Import fields from another template');
$t->add($this->buildEditFormImport());
$form->add($t);
$t = new InputfieldWrapper();
$t->attr('title', $this->_x('Delete', 'tab'));
$t->attr('id', 'WireTabDelete');
// $t->head = $this->_('Delete template');
$t->attr('class', 'WireTab');
$t->add($this->buildEditFormDelete($template));
$form->add($t);
// --------------------
$field = $this->modules->get('InputfieldHidden');
$field->attr('name', 'id');
$field->attr('value', $template->id);
$form->append($field);
$field = $this->modules->get('InputfieldSubmit');
$field->attr('value', $this->_x('Save', 'button'));
$field->class .= ' head_button_clone';
$form->append($field);
return $form;
}
protected function buildEditFormDelete(Template $template) {
$field = $this->modules->get('InputfieldCheckbox');
$field->label = $this->_('Confirm deletion');
$field->attr('id+name', "delete");
$field->attr('value', $template->id);
$field->icon = 'times-circle';
$fieldgroup = $this->fuel('fieldgroups')->get($template->name);
$numFieldgroupTemplates = 0;
if($fieldgroup) {
foreach($this->fuel('templates') as $tpl) {
if($tpl->id == $template->id) continue;
if($tpl->fieldgroup && $tpl->fieldgroup->id == $fieldgroup->id) $numFieldgroupTemplates++;
}
}
$description = $this->_('This template may not be deleted');
if($template->flags & Template::flagSystem) {
$field->description = $description;
$field->notes = $this->_('System templates cannot be deleted');
$field->attr('disabled', 'disabled');
} else if($this->numPages > 0) {
$field->description = $description;
$field->notes = sprintf($this->_n('Template is used by 1 page', 'Template is used by %d pages', $this->numPages), $this->numPages); // Template can't be deleted because it's in use
$field->attr('disabled', 'disabled');
} else if($numFieldgroupTemplates > 0) {
$field->description = $description;
$field->notes = sprintf($this->_n("This template's fieldgroup is used by 1 other template", "This template's fieldgroup is used by %d other templates", $numFieldgroupTemplates), $numFieldgroupTemplates); // Template can't be deleted because it's fieldgroup is in use
$field->attr('disabled', 'disabled');
} else {
$field->description = $this->_('Note that deleting the template only removes it from the database, it does not delete the template file on disk.'); // Note about template files not being deleted
}
return $field;
}
protected function buildEditFormFieldgroup(Template $template) {
$field = $this->modules->get('InputfieldSelect');
$field->label = $this->_x("Fieldgroup", 'field-label');
$field->attr('id+name', 'fieldgroup');
$field->attr('value', $template->fieldgroup->id);
$field->required = true;
$field->description = $this->_("By default, each template manages it's own group of fields. If you want to have this template use the fields from another template, select it here."); // Fieldgroup description
foreach($this->fieldgroups->getAll()->sort('name') as $fieldgroup) {
$name = $fieldgroup->name;
if($name == $template->name) {
$name .= ' ' . $this->_('(default)'); // Label appended to default fieldgroup name in select box
} else {
$tpl = $this->templates->get($name);
// if the template is not using it's own fieldgroup, don't include it in the list
if($tpl && $tpl->name && $tpl->fieldgroup && $tpl->fieldgroup->name != $tpl->name) continue;
}
$field->addOption($fieldgroup->id, $name);
}
if($template->fieldgroup->name == $template->name) {
$field->collapsed = Inputfield::collapsedYes;
}
return $field;
}
/**
* Just show the fields that this template's fieldgroup uses (informational)
*
*/
protected function buildEditFormShowFields(Template $template) {
$table = $this->modules->get("MarkupAdminDataTable");
foreach($template->fieldgroup as $field) {
$table->row(array($field->name));
}
$field = $this->modules->get("InputfieldMarkup");
$field->value = $table->render();
$field->label = $this->_x('Fields', 'field-label (non-default fieldgroup)');
$field->description = sprintf($this->_("For your reference, this is a list of fields used by this template. This template gets it's fields from the '%s' template."), $template->fieldgroup->name); // Description of where the template's fields come from
return $field;
}
/**
* Edit the fields that are part of this template
*
*/
protected function buildEditFormFields(Template $template) {
// if this template isn't defining it's fields, then just show what it's using
if($template->fieldgroup->name != $template->name) return $this->buildEditFormShowFields($template);
$select = $this->modules->get('InputfieldAsmSelect');
$select->label = $this->_x('Fields', 'field-label');
$select->description = $this->_('Define the fields that are used by this template. You may also drag and drop fields to the desired order.'); // Fields definition, description
$select->attr('name', 'fieldgroup_fields');
$select->attr('id', 'fieldgroup_fields');
$select->attr('title', $this->_('Add Field'));
$select->setAsmSelectOption('sortable', true);
$select->setAsmSelectOption('editLink', wire('config')->urls->admin . "setup/field/edit?id={value}&fieldgroup_id={$template->fieldgroup->id}&modal=1&process_template=1");
$select->setAsmSelectOption('hideDeleted', false);
foreach($template->fieldgroup as $field) {
$field = $template->fieldgroup->getField($field->id, true); // get in context
$attrs = $this->getAsmListAttrs($field);
$attrs['selected'] = 'selected';
$select->addOption($field->id, $field->name, $attrs);
}
foreach($this->fields as $field) {
if($template->fieldgroup->has($field)) continue;
if(($field->flags & Field::flagPermanent) && !$this->config->advanced) continue;
$name = $field->name;
if($field->flags & Field::flagSystem) $name .= "*";
$attrs = $this->getAsmListAttrs($field);
$select->addOption($field->id, $name, $attrs);
}
return $select;
}
protected function getAsmListAttrs(Field $field) {
$status = '';
$desc = '';
if(!$field->type instanceof FieldtypeFieldsetClose) {
$desc = $field->label;
$maxDesc = 30;
if(strlen($desc) > $maxDesc) {
$desc = $this->wire('sanitizer')->entities(substr($desc, 0, $maxDesc));
$pos = strrpos($desc, ' ');
if($pos) $desc = substr($desc, 0, strrpos($desc, ' '));
$desc .= '…';
}
$status = str_replace('Fieldtype', '', $field->type);
}
$icons = '';
if($field->required) $icons .= "";
if($field->showIf) $icons .= "";
$status .= $field->columnWidth > 0 ? ' ' . $field->columnWidth . '%' : ' ';
$attrs = array(
'data-status' => $icons . $status,
'data-desc' => $desc
);
return $attrs;
}
protected function buildEditFormImport() {
$form = new InputfieldWrapper();
$field = $this->modules->get("InputfieldSelect");
$field->label = $this->_('Duplicate fields used by another template');
$field->description = $this->_('If you want to duplicate fields used by another template, select it here. Fields already present in this template will be left alone.'); // Duplicate fields, description
$field->attr('id+name', 'import_fieldgroup');
$field->addOption('');
$field->attr('value', '');
foreach($this->fieldgroups->find("sort=name") as $fieldgroup) {
$template = $this->templates->get($fieldgroup->name);
if($template && ($template->flags & Template::flagSystem) && !$this->config->advanced) continue;
if($this->template && $fieldgroup->name == $this->template->name) continue;
$field->addOption($fieldgroup->name);
}
$form->add($field);
return $form;
}
protected function buildEditFormCache(Template $template) {
$form = new InputfieldWrapper();
// --------------------
$field = $this->modules->get('InputfieldInteger');
$field->attr('id+name', 'cache_time');
$field->label = $this->_x('Cache Time', 'field-label');
$field->icon = 'clock-o';
$field->description = $this->_('To cache the output of this template, enter the time (in seconds) that the output should be cached. Caching can help significantly with page render time on resource-heavy pages. But caching should not be used on templates that need to process constantly changing data, like from forms or sessions. Also note that URL segments are cachable, but GET and POST vars are not.'); // Cach time description
$field->notes = $this->_('For example: 60 = 1 minute, 600 = 10 minutes, 3600 = 1 hour, 86400 = 1 day, 604800 = 1 week, 2419200 = 1 month.'); // Cache time notes/examples
$field->attr('value', $template->cache_time);
$form->append($field);
// --------------------
$field = $this->modules->get('InputfieldRadios');
$field->attr('id+name', 'cacheExpire');
$field->label = $this->_('Page Save / Cache Expiration');
$field->description = $this->_('When a page using this template is saved, what should happen to the cache?');
$field->addOption(Template::cacheExpirePage, $this->_('Clear cache for the saved page only (default)'));
$field->addOption(Template::cacheExpireSite, $this->_('Clear cache for entire site*')); // Clear cache for entire site // Note you should include the '*' to relate this item to the Cache expiration notes
$field->addOption(Template::cacheExpireParents, $this->_('Clear cache for the saved page and parents (including homepage)'));
$field->addOption(Template::cacheExpireSpecific, $this->_('Clear cache for the saved page and other pages that I specify...'));
$field->addOption(Template::cacheExpireNone, $this->_('Do nothing'));
$field->attr('value', (int) $template->cacheExpire);
$field->notes = $this->_('*To maximize performance, cache files are all expired as a group rather than cleared individually.'); // Cache expiration notes // This explains the 'Clear cache for entire site*' option
$form->append($field);
// --------------------
$field = $this->modules->get('InputfieldPageListSelectMultiple');
$field->attr('id+name', 'cacheExpirePages');
$field->label = $this->_('Specify the other pages that should have their cache cleared');
$field->description = $this->_('When pages using this template are saved, their cache files will be cleared. Select the other pages that should also have their cache files cleared below.'); // Specified cache clear pages, description
$value = is_array($template->cacheExpirePages) ? $template->cacheExpirePages : array();
$field->attr('value', $value);
$form->append($field);
// --------------------
$field = $this->modules->get('InputfieldRadios');
$field->attr('id+name', 'useCacheForUsers');
$field->label = $this->_('Cache when rendering pages for these users');
$field->addOption(0, $this->_('Guests only'));
$field->addOption(1, $this->_('Guests and logged-in users'));
$field->attr('value', (int) $template->useCacheForUsers);
$field->notes = $this->_('Note that the cache is always disabled for pages where the user has edit access, regardless of what you select here.'); // Cache for guest/loggin-in user notes
$form->append($field);
// --------------------
$labelGET = $this->_('Cache disabling GET variables');
$labelPOST = $this->_('Cache disabling POST variables');
$description = $this->_('When your template output is cached, variables of this type are ignored by default. You can optionally specify one or more variable names that will disable the cache for that request, causing the page to be rendered sans cache.'); // Disable cache, GET/POST vars, description
$notes = $this->_('Optionally enter one or more variable names. If entering more than one, separate each by a space.'); // Disable cache, GET/POST vars, notes
$field = $this->modules->get('InputfieldText');
$field->attr('id+name', 'noCacheGetVars');
$field->label = $labelGET;
$field->description = $description;
$field->notes = $notes;
$field->attr('value', (string) $template->noCacheGetVars);
$field->collapsed = Inputfield::collapsedBlank;
$form->append($field);
// --------------------
$field = $this->modules->get('InputfieldText');
$field->attr('id+name', 'noCachePostVars');
$field->label = $labelPOST;
$field->description = $description;
$field->notes = $notes;
$field->attr('value', (string) $template->noCachePostVars);
$field->collapsed = Inputfield::collapsedBlank;
$form->append($field);
return $form;
}
protected function buildEditFormAdvanced(Template $template) {
$form = new InputfieldWrapper();
// --------------------
$field = $this->modules->get("InputfieldText");
$field->attr('name', 'tags');
$field->attr('value', $template->tags);
$field->label = $this->_('Tags');
$field->icon = 'tags';
$field->description = $this->_('If you want to visually group this template with others in the templates list, enter a one-word tag. Enter the same tag on other templates you want to group with. To specify multiple tags, separate each with a space. Use of tags may be worthwhile if your site has a large number of templates.'); // Description for field tags
$field->notes =
$this->_('Each tag must be one word (hyphenation is okay).') . " " .
$this->_('To make a tag collapsed in the templates list, prepend a hyphen to it, like this: -hello');
$form->add($field);
// --------------------
if(!($template->flags & Template::flagSystem)) {
$field = $this->modules->get("InputfieldName");
$field->label = $this->_('Rename Template');
$field->description = $this->_('The name used to refer to this template. This is also the default filename of the template file (with .php extension) in /site/templates/.'); // Rename template, description
if(basename($template->filename, '.php') == $template->name) {
if(is_writable($template->filename)) $field->description .= $this->_('The template filename is writable and will be renamed as well.'); // Rename template, filename writable, description
else $field->description .= $this->_('The template file is not writable so you will have to rename it manually (instructions will be provided after you save).'); // Rename template, filename not writable, description
}
$field->notes = $this->_('Enter any combination of letters (a-z), numbers (0-9), hyphens or underscores (no spaces). Do not include the .php file extension.'); // Rename template, notes
$field->attr('id+name', 'rename');
$field->attr('value', $template->name);
$field->collapsed = Inputfield::collapsedYes;
$form->append($field);
}
// --------------------
$field = $this->modules->get("InputfieldCheckbox");
$field->attr('id+name', 'clone_template');
$field->attr('value', 1);
$field->label = $this->_('Duplicate/clone this template?');
$field->description = $this->_('Check the box below if you want to create a duplicate/clone copy of this template. The clone will be created when you save. If your templates directory is writable and the template has a file, it will also be cloned.'); // Clone template, description
$field->collapsed = Inputfield::collapsedYes;
$form->append($field);
// --------------------
$field = $this->modules->get('InputfieldText');
$field->attr('name', 'pageLabelField');
$field->label = $this->_('List of fields to display in the admin Page List');
$field->description = $this->_("Enter one or more field names assigned to this template to display in the admin Page List when listing pages using this template. If left blank, the fields specified on the ProcessPageList module configuration will be used instead. Field names should be separated by a space and/or comma. Blank fields will be ignored."); // Page list fields, description
$notes = 'name, ';
foreach($template->fields as $f) if(!$f->type instanceof FieldtypeFieldsetOpen) $notes .= $f->name . ", ";
$field->notes = $this->_('You may enter one or more of these fields:') . ' ' . rtrim($notes, ", ");
$field->notes .= "\n" . $this->_('You may also enter an [icon name](http://fontawesome.io/cheatsheet/), for example: icon-file or fa-file (either format works).');
$field->attr('value', $template->pageLabelField);
$field->collapsed = Inputfield::collapsedBlank;
$form->append($field);
// --------------------
$fieldset = $this->wire('modules')->get('InputfieldFieldset');
$fieldset->label = $this->_('Template Toggles');
$fieldset->description = $this->_('You should generally leave these toggles unchecked unless you have a specific need covered here.');
$form->add($fieldset);
$field = $this->modules->get('InputfieldCheckbox');
$field->attr('name', 'noChangeTemplate');
$field->label = $this->_("Don't allow pages to change their template?");
$field->description = $this->_("When checked, pages using this template will be unable to change to another template."); // noChangeTemplate option, description
if($this->wire('config')->advanced) $field->notes = $this->_('API: $template->noChangeTemplate = 1; // or 0 to disable'); // noChangeTemplate option, API notes
$field->attr('value', 1);
if($template->noChangeTemplate) {
$field->attr('checked', 'checked');
$form->collapsed = Inputfield::collapsedNo;
} else {
$field->collapsed = Inputfield::collapsedYes;
}
$fieldset->append($field);
// --------------------
$field = $this->modules->get('InputfieldCheckbox');
$field->attr('name', 'noUnpublish');
$field->label = $this->_("Don't allow unpublished pages");
$field->description = $this->_("When checked, pages using this template may only exist in a published state and may not be unpublished."); // noUnpublish option, description
if($this->wire('config')->advanced) $field->notes = $this->_('API: $template->noUnpublish = 1; // or 0 to disable'); // noUnpublish option, API notes
$field->attr('value', 1);
if($template->noUnpublish) {
$field->attr('checked', 'checked');
$form->collapsed = Inputfield::collapsedNo;
} else {
$field->collapsed = Inputfield::collapsedYes;
}
$fieldset->append($field);
// --------------------
$field = $this->modules->get('InputfieldCheckbox');
$field->attr('name', 'allowChangeUser');
$field->label = $this->_("Allow the 'created user' to be changed on pages?");
$field->description = $this->_("When checked, pages using this template will have an option to change the 'created by user' (for superusers only). It will also enable the \$page->createdUser or \$page->created_users_id fields to be saved via the API."); // allowChangeUser option, description
if($this->wire('config')->advanced) $field->notes = $this->_('API: $template->allowChangeUser = 1; // or 0 to disable. default is 0.'); // allowChangeUser option, API notes
$field->attr('value', 1);
if($template->allowChangeUser) {
$field->attr('checked', 'checked');
$form->collapsed = Inputfield::collapsedNo;
} else {
$field->collapsed = Inputfield::collapsedYes;
}
$fieldset->append($field);
// --------------------
/*
$field = $this->modules->get('InputfieldText');
$field->attr('name', 'pageNameFormat');
$field->label = $this->_('Page Name Format');
$field->description = sprintf($this->_('Optionally specify a format for page names used when a new page is added. This enables the "Page Add" step to be skipped when adding a new page. In order to work, the template used by parent page(s) must define this template (%s) as the only one allowed for children (see the "family" tab on the template used by the parent).'), $this->template->name); // Page name format, description
$field->notes = $this->_('You may enter any text you like here. When a new page is created and the name is not unique, an incrementing number will be appended to the end of it until it is unique.') . "\n"; // Page name format notes: general
$field->notes .= $this->_('**If you want your page names to derive their value from the title field:** enter "title" above (without the quotes).') . "\n"; // Page name format notes: title
$field->notes .= $this->_('**If you want your page names to reflect the created date/time:** enter a [date format](http://www.php.net/manual/en/function.date.php) above. Your date format must include at least one non-alphanumeric character (like a slash "/" or colon ":" for example) in order to be recognized as a date format. Example: "Y/m/d H:i:s" would result in page names like: "2014-10-30-12-39-01". As you can see, non-alphanumeric characters still present in a formatted date are converted to hyphens.') . ' '; // Page name format notes: date
$field->attr('value', $template->pageNameFormat);
$field->collapsed = Inputfield::collapsedBlank;
$form->append($field);
*/
// --------------------
return $form;
}
protected function buildEditFormSystem(Template $template) {
$form = new InputfieldWrapper();
$form->id = 'system';
$form->notes = $this->_('Please note that all of these system settings are intended for ProcessWire system development (not site development). Use them at your own risk.'); // System tab notes
// --------------------
$field = $this->modules->get('InputfieldCheckbox');
$field->attr('name', 'flagSystem');
$field->label = $this->_('System Flag?');
$field->description = $this->_("If checked, this template will be defined as for the system and it won't be deleteable. Once the system flag is enabled, it can only be removed via the API (flagSystemOverride)."); // System flag, description
$field->notes = $this->_('API: $template->flagSystem = 1; // or 0 to disable'); // System flag, API notes
$field->value = 1;
if($template->flags & Template::flagSystem) {
$field->attr('checked', 'checked');
} else {
$field->collapsed = Inputfield::collapsedYes;
}
$form->add($field);
// --------------------
$field = $this->modules->get('InputfieldText');
$field->attr('name', 'pageClass');
$field->label = $this->_('Page Class Name');
$field->description = $this->_("The name of the PHP class that will be used to create pages that use this template. By default pages will be created from the Page class. You should leave this blank unless you have another Page-derived class that you want to use."); // Page class, description
$field->notes = $this->_('API: $template->pageClass = "ClassName";'); // Page class, API notes
$field->attr('value', $template->pageClass ? $template->pageClass : '');
$field->collapsed = Inputfield::collapsedBlank;
$form->append($field);
if($template->pageClass) $form->collapsed = Inputfield::collapsedNo;
// --------------------
$field = $this->modules->get('InputfieldCheckbox');
$field->attr('name', 'noGlobal');
$field->label = $this->_('Disregard Global Fields?');
$field->description = $this->_("By default, when a field is marked 'global' it will be required on all templates (and automatically added to any templates that don't have it). If this template has a special purpose where 'global' fields wouldn't apply, you can check this box to make this template disregard 'global' fields."); // Global flag, description
$field->notes = $this->_('API: $template->noGlobal = 1; // or 0 to disable'); // Global flag, API notes
$field->attr('value', 1);
if($template->noGlobal) {
$field->attr('checked', 'checked');
$form->collapsed = Inputfield::collapsedNo;
} else {
$field->collapsed = Inputfield::collapsedYes;
}
$form->append($field);
// --------------------
$field = $this->modules->get('InputfieldCheckbox');
$field->attr('name', 'nameContentTab');
$field->label = $this->_("Display 'name' field in content tab?");
$field->description = $this->_("By default, the built-in 'name' field appears in the page editor 'settings' tab. If you would rather have it appear in the 'content' tab check this box."); // Name in content tab, description
$field->notes = $this->_('API: $template->nameContentTab = 1; // or 0 to disable'); // Name in content tab, API notes
$field->attr('value', 1);
if($template->nameContentTab) {
$field->attr('checked', 'checked');
$form->collapsed = Inputfield::collapsedNo;
} else {
$field->collapsed = Inputfield::collapsedYes;
}
$form->append($field);
// --------------------
$field = $this->modules->get('InputfieldCheckbox');
$field->attr('name', 'noMove');
$field->label = $this->_("Don't allow pages to be moved?");
$field->description = $this->_("If you want to prevent pages using this template from being moved (changing parent) then check this box."); // noMove option, description
if($this->wire('config')->advanced) $field->notes = $this->_('API: $template->noMove = 1; // or 0 to disable'); // noMove option, API notes
$field->attr('value', 1);
if($template->noMove) {
$field->attr('checked', 'checked');
$field->collapsed = Inputfield::collapsedNo;
} else {
$field->collapsed = Inputfield::collapsedYes;
}
$form->append($field);
// --------------------
$field = $this->modules->get('InputfieldCheckbox');
$field->attr('name', 'noTrash');
$field->label = $this->_("Disable Trash Option?");
$field->description = $this->_("When checked, pages using this template will not have the option of being sent to the trash."); // noTrash option, description
if($this->wire('config')->advanced) $field->notes = $this->_('API: $template->noTrash = 1; // or 0 to disable'); // noTrash option, API notes
$field->attr('value', 1);
if($template->noTrash) {
$field->attr('checked', 'checked');
$form->collapsed = Inputfield::collapsedNo;
} else {
$field->collapsed = Inputfield::collapsedYes;
}
$form->append($field);
$field = $this->modules->get('InputfieldCheckbox');
$field->attr('name', 'noSettings');
$field->label = $this->_("Disable Settings Tab?");
$field->description = $this->_("When checked, pages using this template will not have a 'settings' tab appear in the editor."); // noSettings option, description
$field->notes = $this->_('API: $template->noSettings = 1; // or 0 to disable'); // noSettings option, API notes
$field->attr('value', 1);
if($template->noSettings) {
$field->attr('checked', 'checked');
$form->collapsed = Inputfield::collapsedNo;
} else {
$field->collapsed = Inputfield::collapsedYes;
}
$form->append($field);
// --------------------
return $form;
}
protected function buildEditFormFamily(Template $template) {
$form = new InputfieldWrapper();
$form->attr('id', 'family');
// --------------------
$field = $this->modules->get("InputfieldRadios");
$field->attr('name', 'noChildren');
$field->label = $this->_('May pages using this template have children?');
$field->addOption(0, $this->labels['Yes']);
$field->addOption(1, $this->labels['No']);
$field->attr('value', (int) $template->noChildren);
$field->columnWidth = 50;
$field->optionColumns = 1;
$form->add($field);
// --------------------
$field = $this->modules->get("InputfieldRadios");
$field->attr('name', 'noParents');
$field->label = $this->_('Can this template be used for new pages?');
// $field->notes = $this->_("An example of a template that you wouldn't want to be used for new pages is your 'homepage' template."); // noParents option, description
$field->addOption(0, $this->labels['Yes']);
$field->addOption(1, $this->labels['No']);
$field->attr('value', (int) $template->noParents);
$field->columnWidth = 50;
$field->optionColumns = 1;
$form->add($field);
// ----------------------
$field = $this->modules->get('InputfieldAsmSelect');
$field->attr('name', 'childTemplates');
$field->label = $this->_('Allowed template(s) for children');
$field->description = $this->_('Select the template(s) that will be allowed for children of pages using this template. Use this only if you specifically want to restrict placement of pages using this template.'); // childTemplates option, description
foreach($this->templates as $t) $field->addOption($t->id, $t->name);
$field->attr('value', $template->childTemplates);
$field->collapsed = count($template->childTemplates) ? Inputfield::collapsedNo : Inputfield::collapsedYes;
$field->notes = $this->_("If none are selected then any are allowed, within the user's access limits. An example usage could be a 'news-list' template that is only allowed to have children using 'news-item' or 'press-release' templates."); // childTemplates option, notes
$field->showIf = 'noChildren!=1';
$form->add($field);
// ----------------------
$field = $this->modules->get('InputfieldAsmSelect');
$field->attr('name', 'parentTemplates');
$field->label = $this->_('Allowed template(s) for parents');
$field->description = $this->_("Select the template(s) that will be allowed as parents for pages using this template. Use this only if you specifically want to restrict placement of pages using this template."); // parentTemplates option, description
foreach($this->templates as $t) $field->addOption($t->id, $t->name);
$field->attr('value', $template->parentTemplates);
$field->collapsed = count($template->parentTemplates) ? Inputfield::collapsedNo : Inputfield::collapsedYes;
$field->notes = $this->_("If none are selected then any parent template is allowed, within the user's access limits. An example usage could be an 'employee' template that is only allowed to have a parent page using a 'company-directory' template."); // parentTemplates option, notes
$field->showIf = 'noParents!=1';
$form->add($field);
// --------------------
$field = $this->modules->get('InputfieldText');
$field->attr('name', 'childNameFormat');
$field->label = $this->_('Name format for children');
$field->description = $this->_('Optionally specify a format for page names used when a new child page is added. This enables the "Page Add" step to be skipped when adding a new page. In order to work, a single (1) template must be selected for the "Allowed template(s) for children" field above.'); // Page name format, description
$field->notes = $this->_('Leave blank to disable. Enter "title" (without quotes) to auto-generate the name from the page title. More options including date formats are available as well. [More](http://processwire.com/api/modules/process-template/)') . "\n"; // Page name format notes
$field->attr('value', $template->childNameFormat);
$field->collapsed = Inputfield::collapsedBlank;
$field->showIf = 'childTemplates.count=1, noChildren!=1';
$form->add($field);
// --------------------
$field = $this->modules->get("InputfieldRadios");
$field->attr('name', 'noShortcut');
$field->label = $this->_('Show in the add-page shortcut menu?');
$field->description = $this->_('When checked, this template is eligible to appear on the "add new page" shortcut button/menu that appears on the main Pages screen. This assumes all other conditions are met (see below).');
$field->notes = $this->_('**Conditions required for this to work**') .
"\n" . $this->_('1. You must select a parent template (see: "allowed templates for parents" above). If more than 1 is selected, only the first will be used.') .
"\n" . $this->_('2. The selected parent template must have defined this template as one allowed for children.') .
"\n" . $this->_('3. There may only be one instance of a page using the parent template in your system.') .
"\n" . $this->_('4. The admin theme must support this feature.');
$field->addOption(0, $this->labels['Yes']);
$field->addOption(1, $this->labels['No']);
$field->attr('value', (int) $template->noShortcut);
$field->collapsed = Inputfield::collapsedYes;
$field->showIf = "parentTemplates.count>0, noParents!=1";
$field->optionColumns = 1;
$form->add($field);
// --------------------
$fieldset = ProcessPageEdit::buildFormSortfield($template->sortfield, $this);
$fieldset->attr('name', 'sortfield_fieldset');
$fieldset->label = $this->_('Sort settings for children');
$fieldset->icon = 'sort';
$fieldset->description = $this->_('If you want children to automatically sort by a specific field, select it here. Otherwise select "None" to let this be set per-page instead. This overrides the page setting, so if you select anything other than "None", the sort option will not appear for pages using this template.');
$fieldset->showIf = 'noChildren!=1';
$form->add($fieldset);
return $form;
}
protected function buildEditFormURLs(Template $template) {
$form = new InputfieldWrapper();
$form->attr('id', 'urls');
// --------------------
$field = $this->modules->get('InputfieldCheckbox');
$field->attr('id+name', 'allowPageNum');
$field->label = $this->_('Allow Page Numbers?');
$field->icon = 'list-ol';
$field->attr('value', 1);
if($template->allowPageNum) $field->attr('checked', 'checked');
else $field->collapsed = Inputfield::collapsedYes;
$field->description = $this->_("If checked, pages using this template will accept page number URL segments in the form 'page123', where '123' may be any positive number. For example, a request URL of '/widgets/page3' automatically sets the \$input->pageNum to be 3. This is used for pagination and should only be enabled for templates that support pagination. Note that page numbers start at 1 (not 0). If combined with URL Segments (see next section), then the page number must be the last part of the URL."); // Allow page numbers, description
$field->notes = $this->_("Access the current page number from your templates at \$input->pageNum;"); // Allow page numbers, API notes
$form->append($field);
if($template->allowPageNum) $form->collapsed = Inputfield::collapsedNo;
// --------------------
$field = $this->modules->get('InputfieldCheckbox');
$field->attr('name', 'urlSegments');
$field->label = $this->_('Allow URL Segments?');
$field->icon = 'sitemap';
$field->description = $this->_("This template may optionally serve URL path segments below that of the page(s) using it. For example, you may want a page with path /path/to/page/ to also handle requests for /path/to/page/segment1/ or /path/to/page/segment1/segment2/. By default, ProcessWire will throw a '404 Page Not Found' error when such a URL is accessed. But if you want ProcessWire to render the page instead, check the box below. You can then manully check the URL segments from your template file to respond to them."); // Allow URL segments, description
$field->notes = $this->_('Up to 3 URL segments are supported after the page URL. These may be any combination of lowercase ASCII letters (a-z), numbers (0-9), dashes and underscores. You can access the URL segments from your template API code by referencing the $input->urlSegment(n) function or $input->urlSegment[n] property (replacing [n] with 1, 2 or 3).'); // Allow URL segments, notes
$field->notes .= "\n\n" . $this->_('For example, given the URL /path/to/page/a/b/c/, where /path/to/page/ is the page path, and /a/b/c/ are the segments: $input->urlSegment1 is "a", $input->urlSegment2 is "b", and $input->urlSegment3 is "c". If your template receives unknown URL segments, a best practice is to abort the request by throwing a 404 error. The API code to do this is: throw new Wire404Exception();'); // Allow URL segments, examples
$field->attr('value', 1);
if($template->urlSegments) {
$field->attr('checked', 'checked');
$form->collapsed = Inputfield::collapsedNo;
} else {
$field->collapsed = Inputfield::collapsedYes;
}
$form->append($field);
// --------------------
$field = $this->modules->get('InputfieldRadios');
$field->attr('name', 'slashUrls');
$field->label = $this->_('Should page URLs end with a slash?');
$field->addOption(1, $this->labels['Yes']);
if($template->name != 'admin') $field->addOption(0, $this->labels['No']);
$field->description = $this->_("If 'Yes', pages using this template will always have URLs that end with a trailing slash '/'. And if the page is loaded from a URL without the slash, it will be redirected to it. If you select 'No', the non-slashed version will be enforced instead. Note that this setting does not enforce this behavior on URL segments or page numbers, only actual page URLs. If you don't have a preference, it is recommended that you leave this set to 'Yes'."); // URLs end with slash, description
$field->attr('value', $template->slashUrls === 0 ? 0 : 1); // force default setting of 1
$field->collapsed = $template->slashUrls === 0 ? Inputfield::collapsedNo : Inputfield::collapsedYes;
if($template->slashUrls === 0) $form->collapsed = Inputfield::collapsedNo;
$form->append($field);
// --------------------
$field = $this->modules->get('InputfieldRadios');
$field->attr('name', 'https');
$field->label = $this->_('Schema/Protocol');
$field->addOption(0, $this->_('HTTP or HTTPS'));
$field->addOption(1, $this->_('HTTPS only (SSL encrypted)'));
$field->addOption(-1, $this->_('HTTP only'));
$field->collapsed = Inputfield::collapsedBlank;
$field->description = $this->_("If your site has an SSL certificate and is accessible by HTTPS, you may make pages using this template accessible only via HTTPS or HTTP. For example, if you select 'HTTPS only' below, and a request for a page using this template comes in through HTTP, it will be automatically redirected to the HTTPS version. By default, ProcessWire allows connection from either HTTP or HTTPS."); // Schema/Protocol, description
$field->attr('value', (int) $template->https);
$form->append($field);
if($template->https) $form->collapsed = Inputfield::collapsedNo;
return $form;
}
protected function buildEditFormFile(Template $template) {
$form = new InputfieldWrapper();
$form->attr('id', 'files');
// --------------------
$field = $this->modules->get('InputfieldText');
$field->attr('name', 'altFilename');
$field->label = $this->_('Alternate Template Filename');
$defaultFilename = $template->name . "." . $this->config->templateExtension;
$field->description = sprintf($this->_("The template's filename, if different from: %s"), $defaultFilename);
$field->notes = sprintf($this->_('Template files are assumed to be in directory: %s'), $this->config->urls->templates) . "\n" .
sprintf($this->_('Template file extension is assumed to be: %s'), '.' . $this->config->templateExtension);
$field->attr('value', $template->altFilename);
$form->append($field);
// --------------------
$f = $this->modules->get('InputfieldText');
$f->attr('id+name', 'prependFile');
$f->attr('value', $template->prependFile);
$f->label = $this->_('Prepend File');
$f->description = $this->_('File to prepend to template file during page render. Must be relative to /site/templates/.'); // prependFile description
$f->columnWidth = 50;
$form->add($f);
$f = $this->modules->get('InputfieldText');
$f->attr('id+name', 'appendFile');
$f->attr('value', $template->appendFile);
$f->label = $this->_('Append File');
$f->description = $this->_('File to append to template file during page render. Must be relative to /site/templates/.'); // appendFile description
$f->columnWidth = 50;
$form->add($f);
// --------------------
if($this->wire('config')->prependTemplateFile) {
$field1 = $this->modules->get('InputfieldCheckbox');
$field1->attr('id+name', 'noPrependTemplateFile');
$field1->label = sprintf($this->_('Disable automatic prepend of file: %s'), $this->wire('config')->prependTemplateFile);
//$field1->description = $this->_('This option disables the $config->prependTemplateFile setting in /site/config.php for this template only.');
if($template->noPrependTemplateFile) $field1->attr('checked', 'checked');
$form->add($field1);
} else $field1 = null;
if($this->wire('config')->appendTemplateFile) {
$field2 = $this->modules->get('InputfieldCheckbox');
$field2->attr('id+name', 'noAppendTemplateFile');
$field2->label = sprintf($this->_('Disable automatic append of file: %s'), $this->wire('config')->appendTemplateFile);
//$field2->description = $this->_('This option disables the $config->appendTemplateFile setting in /site/config.php for this template only.');
if($template->noAppendTemplateFile) $field2->attr('checked', 'checked');
$form->add($field2);
} else $field2 = null;
if($field1 && $field2) {
$field1->columnWidth = 50;
$field2->columnWidth = 50;
}
return $form;
}
protected function buildEditFormAccess(Template $template) {
$form = new InputfieldWrapper();
$form->attr('id', 'access');
// --------------------
$field = $this->modules->get('InputfieldRadios');
$field->attr('id+name', 'useRoles');
$field->label = $this->_('Do you want to manage view and edit access for pages using this template?'); // Use Roles?
$field->icon = 'key';
$field->description = $this->_("If you select 'Yes' you can define what roles have access to pages using this template. If you select 'No' then pages using this template will inherit access from their parent pages."); // Use Roles, description
$field->addOption(1, $this->labels['Yes']);
$field->addOption(0, $this->labels['No']);
$field->attr('value', (int) $template->useRoles);
$field->collapsed = Inputfield::collapsedNo;
$form->add($field);
// --------------------
$fieldset = new InputfieldWrapper();
$fieldset->attr('id', 'useRolesYes');
$form->add($fieldset);
// --------------------
$fieldset->add($this->buildEditFormAccessRoles($template));
// --------------------
$field = $this->modules->get('InputfieldRadios');
$field->attr('id+name', 'redirectLogin');
$field->label = $this->_('What to do when user attempts to view a page and has no access?');
$field->description = $this->_("If a user attempts to access a page using this template, and doesn't have access to the page, what should it do?"); // What to do when no access, description
$field->addOption(0, $this->_('Show a 404 Page'));
$field->addOption($this->config->loginPageID, sprintf($this->_('Show the Login page: %s'), $this->pages->get($this->config->loginPageID)->url));
$field->addOption(-1, $this->_('Redirect to another URL'));
$field->attr('value', !$template->redirectLogin || ctype_digit("{$template->redirectLogin}") ? (int) $template->redirectLogin : -1);
$field->collapsed = Inputfield::collapsedBlank;
$fieldset->add($field);
$field = $this->modules->get('InputfieldText');
$field->attr('id+name', 'redirectLoginURL');
$field->label = $this->_("Enter the URL you want to redirect to when a user doesn't have access");
$field->description = $this->_('This field is applicable only if you selected "redirect to another URL" in the field above.');
if($template->redirectLogin && !ctype_digit("{$template->redirectLogin}")) $field->attr('value', $template->redirectLogin);
$field->collapsed = Inputfield::collapsedNo;
$field->notes = $this->_("Optional: In your URL, you can include the tag '{id}' (perhaps as a GET variable), and it will be replaced by the requested page's ID number, if you want it."); // Redirect URL, notes
$fieldset->add($field);
// --------------------
$field = $this->modules->get('InputfieldRadios');
$field->attr('id+name', 'guestSearchable');
$field->label = $this->_('Should pages be searchable when user has no access?');
$field->description = $this->_("When a user doesn't have access to view a page using this template, what should happen in searches and page lists?"); // Guest searchable, description
$field->addOption(1, $this->_("Yes - Pages may appear in searches/lists even if the user doesn't have access to view them"));
$field->addOption(0, $this->_("No - Pages may NOT not appear in searches/lists unless the user has access to view them"));
$field->attr('value', (int) $template->guestSearchable);
$field->collapsed = Inputfield::collapsedBlank;
$field->notes = $this->_('API Note: This setting affects the results returned by $pages->find(), $page->children() and other functions that return PageArrays.'); // Guest searchable, notes
$fieldset->add($field);
// --------------------
return $form;
}
protected function buildEditFormAccessRoles(Template $template = null) {
$roles = $this->pages->get($this->config->rolesPageID)->children();
$guestRole = $roles->get("name=guest");
$checked = "checked='checked' ";
$disabled = "";
$field = $this->modules->get("InputfieldMarkup");
$field->thead = "Role";
$field->attr('id', 'roles_editor');
$field->label = $this->_('What roles can access pages using this template (and those inheriting from it)?');
$table = $this->modules->get("MarkupAdminDataTable");
$table->setEncodeEntities(false);
$table->headerRow(array(
$this->_x('Role', 'access-thead'),
$this->_x('View Pages', 'access-thead'),
$this->_x('Edit Pages', 'access-thead'),
$this->_x('Create Pages', 'access-thead'),
$this->_x('Add Children', 'access-thead'),
));
foreach($roles as $role) {
$label = $role->name;
$editable = false;
$details = '';
foreach($role->permissions as $permission) {
if(strpos($permission->name, 'page-') !== 0) continue;
if($permission->name == 'page-edit') $editable = true;
$details .= $permission->title;
$details .= "\n";
}
$details = rtrim($details, "\n");
if($label == 'superuser') continue;
if($label == 'guest') $label .= ' ' . $this->_('(everyone)');
$table->row(array(
$label,
("roles->has($role) ? $checked : '') . "' />"),
($editable ? ("id, $template->editRoles) ? $checked : '') . "' />") : $disabled),
($editable ? ("id, $template->createRoles) ? $checked : '') . "' />") : $disabled),
($editable ? ("id, $template->addRoles) ? $checked : '') . "' />") : $disabled)
));
}
$field->value = $table->render();
return $field;
}
/**
* Save the template and check to see if a Fieldgroup change was requested
*
*/
protected function ___executeSave() {
$languages = wire('languages');
$redirectUrl = '';
if(!$this->template) throw new WireException("No template specified");
$form = $this->buildEditForm($this->template);
$form->processInput($this->input->post);
if(isset($_POST['delete']) && $_POST['delete'] == $this->template->id && $this->numPages == 0) {
$fieldgroup = $this->template->fieldgroup;
$deleteFieldgroup = $fieldgroup->name == $this->template->name;
$this->session->message($this->_('Deleted template') . " - {$this->template->name}");
$this->templates->delete($this->template);
if($deleteFieldgroup) $this->fieldgroups->delete($fieldgroup);
$this->session->redirect("./");
return;
}
if($this->input->post->fieldgroup && $this->input->post->fieldgroup != $this->template->fieldgroup->id) {
$redirectUrl = "fieldgroup?id={$this->template->id}&fieldgroup=" . (int) $this->input->post->fieldgroup;
}
$this->template->allowPageNum = (int) $form->get('allowPageNum')->attr('value');
$this->template->redirectLogin = (int) $form->get('redirectLogin')->attr('value');
if($this->template->redirectLogin < 0) $this->template->redirectLogin = $form->get('redirectLoginURL')->attr('value');
$this->template->urlSegments = (int) $form->get('urlSegments')->attr('value');
$this->template->https = (int) $form->get('https')->attr('value');
$this->template->slashUrls = (int) $form->get('slashUrls')->attr('value');
$this->template->altFilename = basename($form->get('altFilename')->attr('value'), "." . $this->config->templateExtension);
$this->template->guestSearchable = (int) $form->get('guestSearchable')->attr('value');
$this->template->pageLabelField = $this->fuel('sanitizer')->names($form->get('pageLabelField')->attr('value'));
$this->template->childNameFormat = $this->fuel('sanitizer')->text($form->get('childNameFormat')->attr('value'));
$this->template->cache_time = $form->get('cache_time')->attr('value');
$this->template->useCacheForUsers = (int) $form->get('useCacheForUsers')->attr('value');
$this->template->noCacheGetVars = $this->fuel('sanitizer')->names($form->get('noCacheGetVars')->attr('value'));
$this->template->noCachePostVars = $this->fuel('sanitizer')->names($form->get('noCachePostVars')->attr('value'));
$this->template->cacheExpire = (int) $form->get('cacheExpire')->attr('value');
$this->template->tags = $this->sanitizer->text($form->get('tags')->attr('value'));
$this->template->noUnpublish = (int) $form->get('noUnpublish')->attr('value');
$this->template->noChangeTemplate = (int) $form->get('noChangeTemplate')->attr('value');
$this->template->allowChangeUser = (int) $form->get('allowChangeUser')->attr('value');
$this->template->noPrependTemplateFile = (int) $this->input->post('noPrependTemplateFile'); // field may not be present on all submissions
$this->template->noAppendTemplateFile = (int) $this->input->post('noAppendTemplateFile'); // field may not be present on all submissions
$this->template->tags = $this->sanitizer->text($form->get('tags')->attr('value'));
foreach(array('prependFile', 'appendFile') as $name) {
$value = $form->get($name)->attr('value');
if(empty($value)) {
$value = '';
} else {
$value = trim(trim($this->sanitizer->path($value), '/'));
if(strpos($value, '..')) $value = '';
if($value) {
if(!is_file($this->config->paths->templates . $value)) {
$this->error("$name: " . $this->config->urls->templates . $value . " - " . $this->_('Warning, file does not exist'));
}
}
}
$this->template->$name = $value;
}
// template label, including multi language versions if applicable
$templateLabel = $form->get('templateLabel');
$this->template->label = $this->sanitizer->text($templateLabel->attr('value'));
if($languages) foreach($languages as $language) {
$this->template->set('label' . $language->id, $this->sanitizer->text($templateLabel->get('value' . $language->id)));
}
if($this->template->cacheExpire == Template::cacheExpireSpecific) $this->template->cacheExpirePages = $form->get('cacheExpirePages')->value;
else $this->template->cacheExpirePages = array();
// family
if($this->input->post->noChildren) {
$this->template->noChildren = 1;
$this->template->childTemplates = array();
} else {
$a = array();
if(is_array($this->input->post->childTemplates)) foreach($this->input->post->childTemplates as $id) $a[] = (int) $id;
$this->template->childTemplates = $a;
$this->template->noChildren = 0;
}
if($this->input->post->noParents) {
$this->template->noParents = 1;
$this->template->parentTemplates = array();
} else {
$a = array();
if(is_array($this->input->post->parentTemplates)) foreach($this->input->post->parentTemplates as $id) $a[] = (int) $id;
$this->template->parentTemplates = $a;
$this->template->noParents = 0;
}
$this->template->noShortcut = $this->input->post->noShortcut ? 1 : 0;
$sortfield = $this->sanitizer->name($_POST['sortfield']);
if($sortfield && $sortfield != 'sort' && !empty($_POST['sortfield_reverse'])) $sortfield = '-' . $sortfield;
$this->template->sortfield = $sortfield;
// advanced
// system
if($this->config->advanced) {
if($form->get('flagSystem')->attr('value')) $this->template->flags = $this->template->flags | Template::flagSystem;
$this->template->noMove = (int) $form->get('noMove')->attr('value');
$this->template->pageClass = $this->sanitizer->varName($form->get('pageClass')->attr('value'));
$this->template->noGlobal = (int) $form->get('noGlobal')->attr('value');
$this->template->noSettings = (int) $form->get('noSettings')->attr('value');
$this->template->noTrash = (int) $form->get('noTrash')->attr('value');
$this->template->nameContentTab = (int) $form->get('nameContentTab')->attr('value');
}
// save roles
$this->template->useRoles = (int) $form->get('useRoles')->attr('value');
foreach(array('roles', 'addRoles', 'editRoles', 'createRoles') as $key) {
$value = $this->input->post->$key;
if(!is_array($value)) $value = array();
foreach($value as $k => $v) $value[(int)$k] = (int) $v;
$this->template->set($key, $value);
}
// remove deprecated property childrenTemplatesID
if(!$this->template->childrenTemplatesID) $this->template->remove("childrenTemplatesID");
if(!$redirectUrl) {
$this->saveFields();
$redirectUrl = "edit?id={$this->template->id}";
}
// check for template rename
if($rename = $form->get('rename')) {
$rename = $rename->attr('value');
if($rename && $this->template->name != $rename) $redirectUrl = "rename?id={$this->template->id}&name=$rename";
}
try {
$this->template->save();
$this->message(sprintf($this->_('Saved template: %s'), $this->template->name));
} catch(Exception $e) {
$this->error($e->getMessage());
}
// check for creation of clone
if($this->input->post->clone_template) {
$clone = $this->templates->clone($this->template);
if($clone) {
$this->message(sprintf($this->_('Created clone of template "%1$s" named "%2$s". You may rename it by editing "%2$s" and clicking the "advanced" tab.'), $this->template->name, $clone->name));
$redirectUrl = './';
} else {
$this->error($this->_('Error creating clone of this template'));
}
}
$this->session->redirect($redirectUrl);
}
/**
* Import the fields from the given fieldgroup to this template's fieldgroup
*
* This is used by both the add and save functions.
*
* @param Fieldgroup $fieldgroup Fieldgroup to import
* @param Template $template Template to import to
*
*/
protected function importFieldgroup(Fieldgroup $fieldgroup, Template $template) {
$total = 0;
foreach($fieldgroup as $field) {
// if template already has the field, leave it, unless it's a closing fieldset.
// necessary because the fieldAdded hook may automatically add a closing fieldset,
// so this prevents things from getting out of order.
if(!$template->fieldgroup->has($field) || $field->type instanceof FieldtypeFieldsetClose) {
$total++;
$template->fieldgroup->add($field);
$this->fieldAdded($field, $template);
}
}
$this->message(sprintf($this->_('Duplicated fields from "%1$s" to "%2$s"'), $fieldgroup, $template->fieldgroup));
}
/**
* Save the fields specified for this template/fieldgroup
*
*/
protected function saveFields() {
$ids = isset($_POST['fieldgroup_fields']) ? $_POST['fieldgroup_fields'] : array();
$removedFields = new FieldsArray();
$fieldgroup = $this->template->fieldgroup;
if($fieldgroup->name != $this->template->name) return;
foreach($ids as $id) {
if(!($id = (int) $id)) continue;
$isDeleted = $id < 0;
$id = abs($id);
if(!$field = $this->fields->get($id)) continue;
if(!$fieldgroup->has($field)) {
$fieldgroup->append($field);
$this->fieldAdded($field, $this->template);
} else {
$field = $fieldgroup->getField($field->id, true); // get in context
$fieldgroup->append($field);
}
if($isDeleted) {
if(($field->flags & Field::flagGlobal) && !$this->template->noGlobal) {
$this->error(sprintf($this->_('Field "%s" may not be removed because it is globally required by all fieldgroups'), $field));
} else {
$removedFields->add($field);
}
}
}
// check if any other fieldgroup should be imported
if($this->input->post->import_fieldgroup) {
$this->importFieldgroup($this->fieldgroups->get($this->sanitizer->name($this->input->post->import_fieldgroup)), $this->template);
}
$fieldgroup->save();
$this->message(sprintf($this->_('Saved fieldgroup: %s'), $fieldgroup->name), Notice::debug);
if(count($removedFields)) {
$url = "removeFields?id={$this->template->id}&fields=";
foreach($removedFields as $field) {
$url .= $field->id . ',';
}
$this->session->redirect(rtrim($url, ','));
}
}
/**
* Confirm the fieldgroup change with another form that shows what will be deleted
*
*/
public function ___executeFieldgroup() {
$this->fuel('breadcrumbs')->add(new Breadcrumb('./', $this->moduleInfo['title']))->add(new Breadcrumb("./edit?id={$this->template->id}", $this->template));
if(!isset($_GET['fieldgroup'])) $this->session->redirect('./');
$fieldgroup = $this->fieldgroups->get((int) $_GET['fieldgroup']);
if(!$fieldgroup) $this->session->redirect('./');
$form = $this->modules->get("InputfieldForm");
$form->attr('action', 'saveFieldgroup');
$form->attr('method', 'post');
$list = '';
foreach($this->template->fieldgroup as $field) {
if(!$fieldgroup->has($field)) $list .= "
$field
";
}
// if nothing will be lost with the fieldgroup change, then just do it now
if(!$list) $this->executeSaveFieldgroup($fieldgroup);
$f = $this->modules->get("InputfieldMarkup");
$f->attr('id', 'changed_fields');
$f->label = $this->_('Fields that will be deleted');
$f->description = sprintf($this->_('You have requested to change the Fieldgroup from "%1$s" to "%2$s".'), $this->template->fieldgroup, $fieldgroup) . ' ' .
sprintf($this->_n('This template is used by 1 page', 'This template is used by %d pages', $this->numPages), $this->numPages) . ' ' .
$this->_('The following fields will be permanently deleted on pages using this template:');
$f->value = "
$list
";
$form->append($f);
$f = $this->modules->get("InputfieldCheckbox");
$f->attr('name', 'fieldgroup');
$f->value = $fieldgroup->id;
$f->label = $this->labels['Are you sure?'];
$f->description = $this->_('Please confirm that you understand the above and that you want to change the fieldgroup by checking the box and submitting this form.'); // Confirm fieldgroup, description
$form->append($f);
$f = $this->modules->get("InputfieldHidden");
$f->attr('name', 'id');
$f->attr('value', $this->template->id);
$form->append($f);
$field = $this->modules->get('InputfieldSubmit');
$field->attr('name', 'submit_change_fieldgroup');
$field->attr('value', $this->_x('Continue', 'submit-fieldgroup'));
$form->append($field);
$form->description = sprintf($this->_('Please confirm that you want to change the Fieldgroup from "%1$s" to "%2$s"'), $this->template->fieldgroup, $fieldgroup);
$this->setFuel('processHeadline', sprintf($this->_('Change Fieldgroup for Template: %s'), $this->template));
return $form->render();
}
/**
* Save the fieldgroup
*
* May be called from a POST action, or from the executeFieldgroup() method directly.
* When called from the executeFieldgroup() method, a fieldgroup param should be provided.
*
* @param Fieldgroup $fieldgroup Optional
*
*/
public function ___executeSaveFieldgroup($fieldgroup = null) {
if(!$this->template) $this->session->redirect('./');
if(is_null($fieldgroup)) {
$this->session->CSRF->validate();
if(!isset($_POST['fieldgroup']) || !$fieldgroup = $this->fieldgroups->get((int) $_POST['fieldgroup'])) {
$this->message($this->_('Fieldgroup change aborted'));
$this->session->redirect("./");
}
}
$this->template->fieldgroup = $fieldgroup;
$this->template->save();
$this->message(sprintf($this->_('Changed template fieldgroup to: %s'), $fieldgroup));
$this->session->redirect("edit?id={$this->template->id}");
}
public function executeRemoveFields() {
if(!isset($_POST['submit_remove_fields'])) return $this->renderRemoveFields();
if(!isset($_POST['remove_fields']) || !is_array($_POST['remove_fields'])) $this->session->redirect("edit?id={$this->template->id}");
$this->session->CSRF->validate();
foreach($this->template->fieldgroup as $field) {
if(in_array($field->id, $_POST['remove_fields'])) {
$this->template->fieldgroup->remove($field);
$this->fieldRemoved($field, $this->template);
}
}
$this->template->fieldgroup->save();
$this->session->redirect("edit?id={$this->template->id}");
}
public function renderRemoveFields() {
if(!isset($_GET['fields'])) $this->session->redirect('./');
$fieldgroup = $this->template->fieldgroup;
$this->setFuel('processHeadline', sprintf($this->_('Remove Fields from Template: %s'), $this->template->name));
$this->fuel('breadcrumbs')->add(new Breadcrumb("./", $this->moduleInfo['title']));
$this->fuel('breadcrumbs')->add(new Breadcrumb("edit?id={$this->template->id}", $this->template->name));
$form = $this->modules->get("InputfieldForm");
$form->attr('method', 'post');
$form->attr('action', 'removeFields');
$checkboxes = $this->modules->get("InputfieldCheckboxes");
$checkboxes->label = $this->_('Remove fields from template');
$checkboxes->icon = 'times-circle';
$checkboxes->attr('name', 'remove_fields');
$checkboxes->description = $this->_("You have asked to remove one or more fields from the template. This will result in data associated with the fields below being permanently deleted. If the fields that are removed contain a lot of data, it may take time for this operation to complete after you confirm and submit this form. Please confirm that you understand this and want to delete the field(s) by checking the boxes below.");
$removeIds = explode(',', $_GET['fields']);
foreach($fieldgroup as $field) {
if(!in_array($field->id, $removeIds)) continue;
$checkboxes->addOption($field->id, sprintf($this->_('Remove field "%1$s" from template "%2$s"'), $field->name, $this->template->name));
}
$form->append($checkboxes);
$submit = $this->modules->get('InputfieldSubmit');
$submit->attr('value', $this->_x('Remove Fields', 'submit-remove'));
$submit->attr('name', 'submit_remove_fields');
$form->append($submit);
$field = $this->modules->get("InputfieldHidden");
$field->attr('name', 'id');
$field->attr('value', $this->id);
$form->append($field);
return $form->render();
}
/**
* Rename the template
*
*/
public function ___executeRename() {
if($this->template->flags & Template::flagSystem) throw new WireException($this->_('This template cannot be renamed because it is a system template'));
$this->fuel('breadcrumbs')->add(new Breadcrumb('./', $this->moduleInfo['title']));
$this->fuel('breadcrumbs')->add(new Breadcrumb('./?id=' . $this->template->id, $this->template->name));
$redirectUrl = $this->template ? "edit?id={$this->template->id}" : "../";
$name = '';
if($this->input->post->confirm_rename) $name = $this->input->post->confirm_rename;
else if($this->input->get->name) $name = $this->input->get->name;
$name = $this->sanitizer->name($name);
if(!$name) return $this->session->redirect($redirectUrl);
if($this->templates->get($name) || $this->fieldgroups->get($name)) {
$this->error(sprintf($this->_('The name "%s" is already in use'), $name));
return $this->session->redirect($redirectUrl);
}
$pathname = $this->template->filename;
$filename = basename($this->template->filename);
$basename = basename($this->template->filename, '.' . $this->config->templateExtension);
$newFilename = "$name." . $this->config->templateExtension;
$newPathname = $this->config->paths->templates . $newFilename;
$templateHasFile = is_file($this->template->filename) && $basename == $this->template->name; // template has file that it is also owner of
$writable = is_writable($this->template->filename);
if($this->input->post->confirm_rename) {
$this->session->CSRF->validate();
$oldName = $this->template->name;
$this->template->name = $name;
$this->template->fieldgroup->name = $name;
$this->template->save();
$this->template->fieldgroup->save();
$this->message(sprintf($this->_('Renamed template "%1$s" to "%2$s"'), $oldName, $name));
if($templateHasFile) {
if($writable) {
if(rename($pathname, $newPathname)) {
$this->message(sprintf($this->_('Renamed template file "%1$s" to "%2$s"'), $filename, $newFilename));
} else {
$this->error(sprintf($this->_('Unable to rename "%1$s" to "%2$s" in directory "%3$s". You must rename the file manually on your file system.'), $filename, $newFilename, $this->config->urls->templates));
}
} else if(!is_file($newPathname)) {
$this->error(sprintf($this->_('The template file "%1$s" was not found in directory "%2$s". You must rename the file "%3$s" to "%1$s" manually on your file system.'), $newFilename, $this->config->urls->templates, $filename));
}
}
return $this->session->redirect($redirectUrl);
}
$form = $this->modules->get("InputfieldForm");
$form->attr('method', 'post');
$form->attr('action', "rename?id={$this->template->id}");
$form->description = sprintf($this->_('Rename template "%1$s" to "%2$s"'), $this->template->name, $name);
$field = $this->modules->get("InputfieldCheckbox");
$field->label = $this->labels['Are you sure?'];
$field->attr('name', 'confirm_rename');
$field->attr('value', $name);
$field->description = $this->_('Please confirm that you want to rename this template by checking the box below.');
// check if we have a file to rename
if($templateHasFile) {
if($writable) {
$field->notes = sprintf($this->_('Template file "%s" appears to be writable so we will attempt to rename it when you click submit.'), $filename);
} else {
$this->error(sprintf($this->_('Template file "%1$s" is not writable. Please rename that file to "%2$s" before clicking submit.'), $this->config->urls->templates . $filename, $newFilename));
}
}
$form->add($field);
$field = $this->modules->get("InputfieldSubmit");
$field->attr('id+name', 'submit_confirm_rename');
$form->add($field);
return $form->render();
}
/**
* For hooks to listen to when a field is removed from a template
*
*/
public function ___fieldRemoved(Field $field, Template $template) {
$this->message(sprintf($this->_('Removed field "%1$s" from template/fieldgroup "%2$s"'), $field, $template));
}
/**
* For hooks to listen to when a field is added to a template
*
*/
public function ___fieldAdded(Field $field, Template $template) {
$this->message(sprintf($this->_('Added field "%1$s" to template/fieldgroup "%2$s"'), $field, $template));
}
/**
* Execute import
*
* @return string
*
*/
public function ___executeImport() {
$this->wire('processHeadline', $this->labels['Import']);
$this->wire('breadcrumbs')->add(new Breadcrumb('../', $this->moduleInfo['title']));
require(dirname(__FILE__) . '/ProcessTemplateExportImport.php');
$o = new ProcessTemplateExportImport();
$form = $o->buildImport();
return $form->render();
}
/**
* Execute export
*
* @return string
*
*/
public function ___executeExport() {
$this->wire('processHeadline', $this->labels['Export']);
$this->wire('breadcrumbs')->add(new Breadcrumb('../', $this->moduleInfo['title']));
require(dirname(__FILE__) . '/ProcessTemplateExportImport.php');
$o = new ProcessTemplateExportImport();
$form = $o->buildExport();
return $form->render();
}
}