1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-09 00:06:55 +02:00

Some cleanup in ProcessPageAdd plus add support for disabling template suggestions when adding pages per processwire/processwire-issues#424 via $config->pageAdd('noSuggestTemplates', true); or specify space-separated list of template names (string) for the "true" value.

This commit is contained in:
Ryan Cramer
2017-12-04 09:51:11 -05:00
parent 337e59663b
commit a865e0a053
5 changed files with 266 additions and 63 deletions

View File

@@ -1025,6 +1025,30 @@ $config->pageEdit = array(
'editCrumbs' => false,
);
/**
* PageAdd default settings
*
* #property string noSuggestTemplates Disable suggestions for new pages (1=disable all, or specify template names separated by space)
*
*/
$config->pageAdd = array(
'noSuggestTemplates' => '',
);
/**
* Disable template suggestions when adding new pages?
*
* Applies when adding a new page where more than one template may be selected for the newly added page.
*
* - true: Always disable template suggestions (forcing user to make selection)
* - false: Never disable template suggestions (default)
* - array: Array of template names or IDs where suggestions should be disabled when children are added.
*
* @var bool|array
*
$config->noSuggestTemplate = false;
*/
/*** 9. MISC ************************************************************************************/
@@ -1057,7 +1081,7 @@ $config->logIP = false;
*
* Module name of default admin theme for guest and users that haven't already selected one
*
* Core options include: **AdminThemeDefault** or **AdminThemeReno**.
* Core options include: **AdminThemeDefault** or **AdminThemeReno** or **AdminThemeUikit**.
* Additional options will depend on what other 3rd party AdminTheme modules you have installed.
*
* @var string
@@ -1195,6 +1219,7 @@ $config->lazyPageChunkSize = 250;
*
*/
/*** 10. RUNTIME ********************************************************************************
*
* The following are runtime-only settings and cannot be changed from /site/config.php

View File

@@ -113,6 +113,7 @@
*
* @property array $pageList Settings specific to Page lists. #pw-group-modules
* @property array $pageEdit Settings specific to Page editors. #pw-group-modules
* @property array $pageAdd Settings specific to Page adding. #pw-group-modules
* @property string $moduleServiceURL URL where the modules web service can be accessed #pw-group-modules
* @property string $moduleServiceKey API key for modules web service #pw-group-modules
* @property bool $moduleCompile Allow use of compiled modules? #pw-group-modules
@@ -182,7 +183,7 @@ class Config extends WireData {
* $url = $config->urls->admin;
* ~~~~~
*
* @param string $for Predefined ProcessWire URLs property or module name
* @param string|Wire $for Predefined ProcessWire URLs property or module name
* @return string|null
*
*/
@@ -195,7 +196,7 @@ class Config extends WireData {
*
* #pw-internal
*
* @param string $for Predefined ProcessWire URLs property or module name
* @param string|Wire $for Predefined ProcessWire URLs property or module name
* @return null|string
*
*/

View File

@@ -113,7 +113,10 @@ class Paths extends WireData {
public function get($key) {
static $_http = null;
if($key == 'root') return $this->_root;
if(strpos($key, 'http') === 0) {
$http = '';
if(is_object($key)) {
$key = "$key";
} else if(strpos($key, 'http') === 0) {
if(is_null($_http)) {
$scheme = $this->wire('input')->scheme;
if(!$scheme) $scheme = 'http';
@@ -123,8 +126,6 @@ class Paths extends WireData {
$http = $_http;
$key = substr($key, 4);
$key[0] = strtolower($key[0]);
} else {
$http = '';
}
if($key == 'root') {
$value = $http . $this->_root;

View File

@@ -8,23 +8,87 @@
* For more details about how Process modules work, please see:
* /wire/core/Process.php
*
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
* ProcessWire 3.x, Copyright 2017 by Ryan Cramer
* https://processwire.com
*
* @method string executeTemplate()
* @method bool processQuickAdd(Page $parent, Template $template)
* @method InputfieldForm buildForm()
* @method bool processInput(InputfieldForm $form)
* @method array getAllowedTemplates($parent = null)
*
*/
class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEditor {
protected $form;
protected $parent = null;
/**
* @var InputfieldForm
*
*/
protected $form;
/**
* @var Page|null
*
*/
protected $parent = null;
/**
* @var int
*
*/
protected $parent_id = 0;
protected $page;
protected $template = null;
/**
* @var Page
*
*/
protected $page;
/**
* @var Template|null
*
*/
protected $template = null;
/**
* @var array|null
*
*/
protected $allowedTemplates = null; //cache
/**
* @var array
*
*/
protected $predefinedTemplates = array();
protected $predefinedParents = array();
/**
* @var PageArray|array
*
*/
protected $predefinedParents = array();
/**
* @var WirePageEditor|ProcessPageAdd
*
*/
protected $editor; // WirePageEditor
/**
* Settings that may be specified with $config->pageAdd array
*
* @var array
*
*/
protected $settings = array(
'noSuggestTemplates' => '', // Disable suggestions: 1|true=disable all, or space-separated template names
);
/**
* @return array
*
*/
public static function getModuleInfo() {
return array(
'title' => __('Page Add', __FILE__),
@@ -36,19 +100,37 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
'useNavJSON' => true,
);
}
/**
* Construct and populate default config
*
*/
public function __construct() {
$this->editor = $this;
parent::__construct();
$this->set('noAutoPublish', false);
$this->set('shortcutSort', array());
$settings = $this->wire('config')->pageAdd;
if(is_array($settings)) $this->settings = array_merge($this->settings, $settings);
}
/**
* Module init
*
*/
public function init() {
$this->page = null;
return parent::init();
}
/**
* Set property
*
* @param string $key
* @param mixed $value
* @return Process|ProcessPageAdd
*
*/
public function set($key, $value) {
if($key == 'parent_id') $this->parent_id = (int) $value;
else if($key == 'template' && $value instanceof Template) $this->template = $value;
@@ -156,12 +238,14 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
unset($data['modified']);
// get additional from PageBookmarks
$bookmarks = $this->getPageBookmarks($this);
$bookmarks = $this->getPageBookmarks();
$options2 = $bookmarks->initNavJSON(array('add' => 'ignore-me'));
$lastItem = null;
$listLength = count($data['list']);
$n = 0;
foreach(array_values($options2['items']) as $p) {
/** @var Page $p */
if($p->id == 'bookmark' && !$user->isSuperuser()) continue;
$item = array(
'url' => ($p->id == 'bookmark' ? 'bookmarks/?role=0' : "?parent_id=$p->id"),
@@ -186,6 +270,13 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
return json_encode($data);
}
/**
* Ask user to select template and parent
*
* @return string
* @throws WireException
*
*/
public function ___executeTemplate() {
$templateID = (int) $this->input->get->template_id;
@@ -243,7 +334,13 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
$form->add($f);
return $form->render();
}
/**
* Render an HTML definition list template selection for when no parent/template is known
*
* @return string
*
*/
public function renderChooseTemplate() {
$data = $this->executeNavJSON(array('getArray' => true));
$out = '';
@@ -301,7 +398,15 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
}
return $out;
}
/**
* Method to handle AJAX call to check of a given page name exists for a parent
*
* Returns error or OK message in HTML
*
* @return string
*
*/
public function executeExists() {
$parentID = (int) $this->wire('input')->get('parent_id');
if(!$parentID) return '';
@@ -319,6 +424,14 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
return $out;
}
/**
* Main execution, first screen of adding a Page
*
* @return string
* @throws Wire404Exception
* @throws WireException
*
*/
public function ___execute() {
$input = $this->wire('input');
@@ -380,7 +493,11 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
$this->form->setTrackChanges();
if($input->post('submit_save') || $input->post('submit_publish') || $input->post('submit_publish_add')) {
$this->processInput($this->form);
if($this->processInput($this->form)) {
// redirect occurs within processInput
} else {
// errors occurred during process input, re-render form
}
}
$this->setupBreadcrumbs();
@@ -390,6 +507,9 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
/**
* Returns an array of templates that are allowed to be used here
*
* @param Page|null $parent
* @return array
*
*/
protected function ___getAllowedTemplates($parent = null) {
@@ -609,10 +729,14 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
/**
* Build the form fields for adding a page
*
* @return InputfieldForm
* @throws WireException
*
*/
protected function ___buildForm() {
/** @var InputfieldForm $form */
$form = $this->modules->get('InputfieldForm');
$form->attr('id', 'ProcessPageAdd');
@@ -641,6 +765,7 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
}
}
} else if($this->template) {
/** @var Field $field */
$field = $this->template->fieldgroup->getField('title', true);
if($field) {
if(in_array($field->collapsed, array(Inputfield::collapsedNoLocked, Inputfield::collapsedYesLocked))) {
@@ -653,10 +778,12 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
}
}
/** @var InputfieldPageName $field */
$field = $this->modules->get('InputfieldPageName');
$field->parentPage = $this->parent;
$field->attr('name', '_pw_page_name');
$field->required = true;
if($this->template) {
$field->slashUrls = $this->template->slashUrls;
$label = $this->template->getNameLabel();
@@ -665,6 +792,8 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
} else {
$languages = $this->wire('languages');
}
/** @var Languages $languages */
if($languages && $this->parent && $this->parent_id > 0) {
foreach($languages as $language) {
if($language->isDefault()) continue;
@@ -704,9 +833,25 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
} else {
// multiple templates are possible so give them a select
/** @var InputfieldSelect $field */
$field = $this->modules->get('InputfieldSelect');
$noSuggest = $this->settings['noSuggestTemplates'];
if(empty($noSuggest)) {
$noSuggest = false;
} else {
// determine whether to show blank option at top
$ptpl = $this->parent ? $this->parent->template->name : '';
$noSuggestArray = is_array($noSuggest) ? $noSuggest : explode(' ', $noSuggest);
if(((string) $noSuggest) === "1" || ($ptpl && in_array($ptpl, $noSuggestArray))) {
$field->addOption('', '', array('data-publish' => false, 'data-nolang' => false));
$noSuggest = true;
} else {
$noSuggest = false;
}
}
foreach($allowedTemplates as $template) {
if(!count($this->predefinedTemplates) && $this->template && $template->id != $this->template->id) continue;
$numFields = count($template->fieldgroup);
@@ -723,7 +868,7 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
));
}
$field->attr('value', $defaultTemplateId);
if(!$noSuggest) $field->attr('value', $defaultTemplateId);
}
$field->label = $this->_('Template'); // Template field label
@@ -731,7 +876,7 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
$field->icon = 'cubes';
$field->required = true;
$field instanceof InputfieldHidden ? $form->append($field) : $form->prepend($field);
if(count($this->predefinedParents) > 1) {
$field = $this->modules->get('InputfieldSelect');
$field->attr('name', 'parent_id');
@@ -753,7 +898,8 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
$field->attr('value', $value);
$form->append($field);
}
/** @var InputfieldSubmit $field */
$field = $this->modules->get('InputfieldSubmit');
$field->attr('name', 'submit_save');
$field->attr('value', $this->_('Save'));
@@ -767,6 +913,7 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
if($publishPermission->id && !$this->wire('user')->hasPermission('page-publish')) $allowPublish = false;
}
if($allowPublish) {
/** @var InputfieldSubmit $field */
$field = $this->modules->get('InputfieldSubmit');
$field->attr('id+name', 'submit_publish');
$field->attr('value', $this->_('Save + Publish'));
@@ -783,7 +930,6 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
}
}
// $allowedTemplates = $this->getAllowedTemplates();
if(count($allowedTemplates) == 1) {
$t = reset($allowedTemplates);
$form->description = $this->getTemplateLabel($t);
@@ -794,6 +940,9 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
/**
* Return the label for the given Template
*
* @param Template $template
* @return string
*
*/
protected function getTemplateLabel(Template $template) {
@@ -896,41 +1045,57 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
} else {
return false;
}
return true;
}
/**
* Populate a session message indicating info about created page
*
* @param Page $page
*
*/
protected function createdPageMessage(Page $page) {
$this->session->message(sprintf($this->_('Created page %1$s using template: %2$s'), $page->parent->url . $page->name, $page->template->name));
$this->session->message(
sprintf(
$this->_('Created page %1$s using template: %2$s'),
$page->parent->url . $page->name, $page->template->name
)
);
}
/**
* Save the submitted page add form
*
* @param InputfieldForm $form
* @throws WireException
* @return bool
*
*/
protected function ___processInput(Inputfield $form) {
protected function ___processInput(InputfieldForm $form) {
$this->page = $this->wire('pages')->newPage(); // must exist before processInput for language hooks
$form->processInput($this->input->post);
$nameField = $form->children->get('_pw_page_name');
/** @var InputfieldPageName $nameField */
$nameField = $form->getChildByName('_pw_page_name');
$name = $nameField->value;
if(!strlen($name)) {
$this->error($this->_("Missing required field: name"));
$nameField->error($this->_("Missing required field: name"));
return false;
}
/*
if($this->parent->child("name=$name, include=all")->id) {
$nameField->error($this->_("The name you selected is already in use. Please select another."));
return false;
}
*/
$template = $this->template;
if(is_null($template)) {
$templatesId = (int) $form->children->get('template')->value;
$template = $this->templates->get($templatesId);
/** @var InputfieldSelect $templateField */
$templateField = $form->getChildByName('template');
$templatesId = (int) $templateField->val();
$template = $templatesId ? $this->templates->get($templatesId) : null;
if(!$template) {
$templateField->error($this->_('Template selection is required'));
return false;
}
}
if(!$this->isAllowedTemplate($template, $this->parent)) {
@@ -1001,6 +1166,8 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
} else {
$this->session->redirect("../edit/?id={$this->page->id}&new=1" . ($this->input->get->modal ? "&modal=1" : ''));
}
return true;
}
/**
@@ -1012,19 +1179,28 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
$breadcrumbs = $this->wire(new Breadcrumbs());
$breadcrumbs->add(new Breadcrumb($this->config->urls->admin . 'page/list/', "Pages"));
foreach($this->parent->parents()->append($this->parent) as $p) {
/** @var Page $p */
$breadcrumbs->add(new Breadcrumb($this->config->urls->admin . "page/list/?open=" . $p->id, $p->get("title|name")));
}
$this->wire('breadcrumbs', $breadcrumbs);
}
/**
* Get the Page that is being edited
*
* @return Page|null
*
*/
public function getPage() {
return $this->page ? $this->page : $this->wire('pages')->newNullPage();
}
/**
* Set the WirePageEditor that is calling this Process
*
* @param WirePageEditor $editor
*
*/
public function setEditor(WirePageEditor $editor) {
$this->editor = $editor;
}
@@ -1079,7 +1255,7 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
$bookmarks = $this->getPageBookmarks();
$form = $bookmarks->editBookmarksForm();
$roleID = $this->wire('input')->get('role');
$roleID = $this->wire('input')->get('role'); // no integer sanitization is intentional
if(!is_null($roleID) && $roleID == 0 && $this->wire('user')->isSuperuser()) {
$f = $this->getShortcutSortField();
@@ -1094,13 +1270,20 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
return $form->render();
}
/**
* Get Inputfield that lets you define shorcuts and sort order
*
* @return InputfieldAsmSelect
*
*/
public function getShortcutSortField() {
$this->wire('session')->remove($this, 'nav');
$data = $this->executeNavJSON(array('getArray' => true));
$name = 'shortcutSort';
/** @var InputfieldAsmSelect $f */
$f = $this->wire('modules')->get('InputfieldAsmSelect');
$f->label = $this->_('Template shortcut sort order');
$f->description = $this->_('To change the order of the "Add New" page-template shortcuts, drag and drop the options to the order you want them in.');
@@ -1109,7 +1292,6 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
$f->icon = 'sort';
$f->setAsmSelectOption('removeLabel', '');
$out = '';
$value = array();
foreach($data['list'] as $item) {
@@ -1131,7 +1313,14 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit
return $f;
}
/**
* Get module configuration inputs
*
* @param array $data
* @return InputfieldWrapper
*
*/
public function getModuleConfigInputfields(array $data) {
$form = $this->wire(new InputfieldWrapper());

View File

@@ -1340,13 +1340,15 @@ class ProcessTemplate extends Process {
$fieldset->icon = 'toggle-on';
$fieldset->description = $this->_('You should generally leave these toggles unchecked unless you have a specific need covered here.');
$form->add($fieldset);
$label0 = $this->_('specify 0 to disable');
/** @var InputfieldCheckbox $field */
$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
if($this->wire('config')->advanced) $field->notes = 'API: $template->noChangeTemplate = 1; // ' . $label0;
$field->attr('value', 1);
if($template->noChangeTemplate) {
@@ -1363,7 +1365,7 @@ class ProcessTemplate extends Process {
$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
if($this->wire('config')->advanced) $field->notes = 'API: $template->noUnpublish = 1; // ' . $label0;
$field->attr('value', 1);
if($template->noUnpublish) {
@@ -1380,7 +1382,7 @@ class ProcessTemplate extends Process {
$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
if($this->wire('config')->advanced) $field->notes = 'API: $template->allowChangeUser = 1; // ' . $label0;
$field->attr('value', 1);
if($template->allowChangeUser) {
@@ -1397,7 +1399,7 @@ class ProcessTemplate extends Process {
$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
if($this->wire('config')->advanced) $field->notes = 'API: $template->noMove = 1; // ' . $label0;
$field->attr('value', 1);
if($template->noMove) {
@@ -1415,7 +1417,7 @@ class ProcessTemplate extends Process {
$field->attr('name', 'noLang');
$field->label = $this->_("Disable multi-language support for this template?");
$field->description = $this->_("When checked, pages using this template will only use the default language.");
if($this->wire('config')->advanced) $field->notes = $this->_('API: $template->noLang = 1; // default is 0.');
if($this->wire('config')->advanced) $field->notes = 'API: $template->noLang = 1; // ' . $label0;
$field->attr('value', 1);
if($template->noLang) {
@@ -1429,21 +1431,6 @@ class ProcessTemplate extends Process {
// --------------------
/*
$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;
}