ProcessWire - Module Snippets
Nützliche Snippets für das Schreiben von Modulen
Siehe auch
ProcessWire - Module schreiben https://github.com/Toutouwai Github von Robin Salis mit vielen Beispielen
Grundrezepte
Adminseite erstellen (Non Process Module)
Das benötigt man NICHT IN PROCESS MODULEN. Da funktioniert das auch ohne manuelles erstellen.
Here is a short example on how you could do it (of course there are a lot of different ways to archive this):
public function ___install() {
// Creates a new Page object
$page = new Page();
// use your own selector to choose the parent page
$parent = $this->pages->get("name=setup");
$page->parent = $parent;
// choose a template
$page->template = $this->templates->get('admin');
// name and title
$page->name = "your-page";
$page->title = "Your Page";
// .. and save the new page object as a real page
$page->save();
// success message
$this->message(sprintf($this->_("Installed to %s"), $page->path));
}
public function ___uninstall() {
$parent = $this->pages->get("name=setup");
// the name has to be the same as defined above
// you could use a constant variable for this
$page = $parent->child("name=your-page");
// only delete page if existing
if($page->id) {
$this->pages->delete($page);
$this->message(sprintf($this->_("Removed %s"), $page->path));
}
}
</syntaxhighlights>
== Diverses ==
=== ProcessWire Version testen ===
<syntaxhighlight lang="php">
public function ___install()
{
if (ProcessWire::versionMajor == 2 && ProcessWire::versionMinor < 1) {
throw new WireException("This module requires ProcessWire 2.1 or newer");
}
//...
Testen ob ein bestimmtes Modul installiert ist
if (!$this->modules->isInstalled('Tasker')) {
$this->message('Tasker module is missing. Install it before using Dataset module.');
return;
}
$this->tasker = $this->modules->get('Tasker');
Seiten erstellen
https://processwire.com/talk/topic/352-creating-pages-via-api/ https://processwire.com/blog/posts/processwire-2.6.21-upgrades-comments-more-on-pw-3.x/#more-updates-on-processwire-3.0 (in multiinstance modules)
<?php
include(./index.php) // bootstrap PW (only if pw is not ready)
$p = new Page(); // create new page object
$p->template = 'page'; // set template
$p->parent = wire('pages')->get('/about/'); // set the parent
$p->name = 'mynewpage_url'; // give it a name used in the url for the page otherwise it will be created from title
$p->title = 'My New Page'; // set page title (not neccessary but recommended)
// added by Ryan: save page in preparation for adding files (#1)
$p->save();
// populate fields
$p->image = 'path/to/image.jpg'; // populate a single image field (#2)
$p->images->add('path/to/image1.jpg'); // add multiple to images field
$p->save();
// testing
echo 'id: '.$p->id.'<br/>';
echo 'path: '.$p->path;
You may need to add a
$page->setOutputFormatting(false)
depending on the context and if PW gives you an error about needing to turn off output formatting.
You can override a page by using id:
$p = new Page();
$p->template = "basic-page";
$p->parent = 1;
$p->title = "Page Title";
$p->id = 4254;
$p->of(false);
$p->save();
With
adjustName=>true
and not using name PW will create a unique name. Just omitting name might work too.
Get Unique Pagename
/**
* Given a page name, check that it is unique and return it or a unique numbered variation of it
*
*/
protected function getUniquePageName($pageName) {
$n = 0;
do {
$testName = $pageName . "-" . (++$n);
$test = $this->parent->child("name=$testName, include=all");
if(!$test->id) break;
} while(1);
return $testName;
}
Selektoren
Einfacher Check auf gültigen Selector
// check the page selector
if (strlen($selector)<2 || !strpos($selector, '=')) {
$this->error("ERROR: invalid page selector '{$selector}' found in the input.");
return false;
}
Admin Module
Admin Module sind Module die im Backend genutzt werden.
Skripte und Styles im Admin Bereich
ProcessWire - Skripte und Styles im Admin Bereich
Seite im Admin anlegen
Hinweis: Überholt. Geht heute viel einfacher (siehe Beispiel in Links von Bernhard Baumrock). Die Methoden install und uninstall sind trotzdem nützlich. getInstalledPage kann trotzdem nützlich sein. Man benötigt es aber nicht zwingend zum Anlegen der Seite, dies erledigt PW selbst wenn man es in der Konfiguration des Moduls angibt.
Wenn keine Seite angelegt ist wird sie angelegt. Nützlich z.B. für die ___install() und ___uninstall() Methoden
/**
* Return the page that this Process is installed on
*
*/
protected function getInstalledPage() {
$admin = $this->pages->get($this->config->adminRootPageID);
$parent = $admin->child("name=setup");
if(!$parent->id) $parent = $admin;
$page = $parent->child("name=" . self::adminPageName);
if(!$page->id) {
$page = new Page();
$page->parent = $parent;
$page->template = $this->templates->get('admin');
$page->name = self::adminPageName;
$page->title = "Import Pages From CSV";
$page->process = $this;
$page->sort = $parent->numChildren;
$page->save();
}
return $page;
}
/**
* Install the module and create the page where it lives
*
*/
public function ___install() {
if(ProcessWire::versionMajor == 2 && ProcessWire::versionMinor < 1) {
throw new WireException("This module requires ProcessWire 2.1 or newer");
}
$page = $this->getInstalledPage();
$this->message("Installed to {$page->path}");
if($page->parent->name == 'setup') $this->message("Click to your 'Setup' page to start using the CSV Importer");
}
/**
* Uninstall the module
*
*/
public function ___uninstall() {
$page = $this->getInstalledPage();
if($page->id) {
$this->message("Removed {$page->path}");
$this->pages->delete($page);
}
}
$filesPath = $page->filesManager->path;
User Interface im Admin Bereich - Helferlein
Buttons
Händisch Hier noch mit einer Abfrage ob man im Modal ist um Modals in Modals zu verhindern.
if(!$this->input->get('modal')) {
<a href="./link-to-page/" class="ui-button ui-state-default"> My Button </a>
}
Programmatisch Nützlich um ganze Sets zu erzeugen.
$out = '';
$buttons = [
'randomizeData' => 'Randomize Data',
'addDataset' => 'Add Dataset',
'addData' => 'Add Data',
'removeDataset' => 'Remove Dataset',
'removeData' => 'Remove Data',
];
$button = $this->modules->get('InputfieldButton');
$button->setSmall(true);
foreach($buttons as $id => $label) {
$button->id = $id;
$button->value = $label;
$out .= $button->render();
}
AdminTable
$table = $this->modules->get('MarkupAdminDataTable');
$table->headerRow(['A', 'B', 'C']);
$table->row([1, 2, 3]);
$table->row([4, 5, 6]);
return $table->render();
Seiten in Panel öffnen
Man kann Unterseiten in einem Panel aufmachen. Einfach die Klasse pw-panel zu Links hinzufügen.
<a href="./due-contracts/" class="ui-button ui-state-default pw-panel"> Fällige Verträge </a>
Mehr Infos im Quelltext (suche nach panel)
https://github.com/processwire/processwire/blob/master/wire/modules/Jquery/JqueryUI/panel.js
Skripte hinzufügen
public function ___executeChart() {
$this->config->scripts->add(
'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.min.js'
);
$this->config->scripts->add(
'http://www.chartjs.org/samples/latest/utils.js'
);
$this->config->scripts->add(
$this->config->urls->ProcessSimple . 'chart.js'
);
$out = '';
$buttons = [
'randomizeData' => 'Randomize Data',
'addDataset' => 'Add Dataset',
'addData' => 'Add Data',
'removeDataset' => 'Remove Dataset',
'removeData' => 'Remove Data',
];
$button = $this->modules->get('InputfieldButton');
$button->setSmall(true);
foreach($buttons as $id => $label) {
$button->id = $id;
$button->value = $label;
$out .= $button->render();
}
return $out;
}
Formulare im Backend/Admin
https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/#handling-user-input-using-forms-amp-inputfields https://gitlab.com/baumrock/ProcessSkyDashboard/blob/master/ProcessSkyDashboard.module.php.v2
Beispiel:
public function ___execute() {
$form = $this->modules->get('InputfieldForm');
bd($this->input->post);
$field = $this->modules->get('InputfieldMarkup');
$field->label = 'Table';
$field->value = $this->renderTable();
$field->columnWidth = 50;
$form->add($field);
$field = $this->modules->get('InputfieldMarkup');
$field->label = 'Chart';
$field->value = $this->renderChart();
$field->columnWidth = 50;
$form->add($field);
$fieldset = $this->modules->get('InputfieldFieldset');
$fieldset->label = 'Add Skyscraper';
//$fieldset->collapsed = Inputfield::collapsedYes;
$field = $this->modules->get('InputfieldText');
$field->name = 'Name';
$field->columnWidth = 33;
$fieldset->add($field);
$field = $this->modules->get('InputfieldText');
$field->name = 'Height';
$field->columnWidth = 33;
$fieldset->add($field);
// see InputfieldPage.module for all available options
$field = $this->modules->get('InputfieldPage');
$field->inputfield = 'InputfieldSelect';
$field->findPagesSelector = 'template=city';
$field->labelFieldName = 'title';
$field->name = 'City';
$field->columnWidth = 34;
$fieldset->add($field);
$button = $this->modules->get('InputfieldSubmit');
$button->value = 'Save';
$button->icon = 'floppy-o';
$fieldset->add($button);
$form->add($fieldset);
return $form->render();
}
public function ___executeAddSkyscraper() {
// build the add-skyscraper form
$form = $this->buildAddSkyscraper();
// if form not submitted, display it instead
if(!$this->input->post('submit')) return $form->render();
// process the InputfieldForm
$form->processInput($this->input->post);
if(count($form->getErrors())) {
// form had errors, ask them to fix
$this->error('Please fix the errors');
return $form->render();
}
// add skyscraper from submitted form
$p = new Page();
$p->template = 'skyscraper';
$p->parent = $form->get('City')->value->first();
$p->title = $form->get('Name')->value;
$p->height = $form->get('Height')->value;
$p->save();
// show message
$this->message('Added a new skyscraper to the database');
// redirect to our dashboard
$this->session->redirect('./');
}
Tabs im Backend
https://processwire.com/talk/topic/24934-using-tabs-wiretabs-in-a-module-config/
Tabs kann man im Admin mit dem InputfieldWrapper erzeugen. Da es ein Inputfield Objekt ist benötigt man auch ein Formular. Das Ganze sieht am Ende so aus:
InputfieldForm - InputfieldWrapper -- InputfieldWrapper --- InputfieldMarkup (oder andere Inputfields)
Im Programm kann das dann so ausschauen
public function ___execute(){
$form = $this->wire('modules')->get("InputfieldForm");
$form->name = 'select';
$form->method = 'post';
$tabsWrapper = new InputfieldWrapper();
$tabsWrapper->attr("id", "fulfillment-list");
//$tab = $modules->get('InputfieldWrapper'); // works
//$tab = new InputfieldWrapper(); // not recommended - could ressolve in issues All newly-created objects that are derived from Wire SHOULD have their dependencies injected. In order to do this, pass the new object through the wire() method.
$tab = $this->wire(new InputfieldWrapper()); // if you need compatibility for older pw
$tab->attr('id', 'tab_fulfillment-list'); // best way?
$tab->attr('title', 'Fulfillments');
$tab->attr('class', 'WireTab');
$f = $this->wire('modules')->get("InputfieldMarkup");
$f->attr('name', 'tab_content');
$out = '<div>Dies ist mein Inhalt</div>';
$f->attr('value', $out);
$tab->add($f);
// ... more fields...
$tabsWrapper->add($tab);
// next tab
$tab = new InputfieldWrapper();
$tab->id = 'tab2'; // alternative Schreibweise statt attr()
$tab->title = 'TAB 2';
$tab->attr('class', 'WireTab');
// ... more fields to add ...
$form->add($tabsWrapper);
return $form->render();
}
Eine andere Möglichkeit manuell Tabs zu erstellen dürfte das WireTabs Objekt sein (Todo-Test).
Schnipsel - Todo
Schnipsel...
// override css
$form->setClasses(array('form'=>'uk-form-horizontal InputfieldForm'));
Seiten
Einzigartiger Seitenname
Z.B. beim verschieben evtl. wichtig falls Seiten mit dem gleichen Namen vorhanden sind.
//In the context of the hook $p->name = $this->pages->names->uniquePageName($this->sanitizer->pageName($p->title));
oder
$p->name = $this->pages->names()->uniquePageName($p->name);
$p->parent = pages()->get('/news/');
$event->arguments(0, $p);
Felder
Textfelder auf read only (locked) setzen
$field->collapsed = Inputfield::collapsedLocked; // or $field->collapsed = Inputfield::locked;
Templates
Page Object an Template Datei übergeben
public function getInvoiceHtml($oid){
$html = '';
$order = $this->pages->get($oid);
$t = $this->getTemplate("padinvoice_pdf.php");
$t->set("order", $order);
$html = $t->render();
return $html;
}