Advertisement
  1. Web Design
  2. WordPress
  3. WordPress CMS

Extending the ProcessWire Admin Using Custom Modules

Scroll to top

In this tutorial we’re going to look into extending ProcessWire’s admin using custom modules. With three example modules I will give you small a taste of the power ProcessWire modules have for adding new functionality to the admin.

Create Custom Admin Pages

Creating pages for your website in ProcessWire (PW) couldn’t be easier, but what about making custom pages in the CMS? Say you want to make a custom settings page, FAQs or video page?

Read on, we’ve got your back.

The module ProcessSimpleAdminPage shows simply to create a module that extends the Process class to add a new admin Process, and then create a page for the new Process. Process is the base class for the PW’s admin so using it we can create a page that shows our content.

Tip: Your new Process extending module can also display forms and other functionality as well as return content.

We’re going to create a new Process that returns some content, then create a new page in the admin navigation to reach that content (in this example I’ve named the page “CMS FAQ”). To build our module we start by creating a file called “ProcessSimpleAdminPage.module” and saving our module details to it.

1
class ProcessSimpleAdminPage extends Process {
2
3
    public static function getModuleInfo() {
4
        return array(
5
            'title' => 'Process Simple Admin Page',
6
            'summary' => 'Simple Process module that adds new admin page with',
7
            'version' => 001,
8
        );
9
    }
10
    public function execute() {
11
        return '

12
            <h2>Edit the text here in the module</h2>

13
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam mattis eros vitae metus sodales eget suscipit purus rhoncus. Proin ultrices gravida dolor, non porttitor enim interdum vitae. Integer feugiat lacinia tincidunt. Nulla laoreet tristique tristique. Sed elementum justo a nisl elementum sit amet accumsan nisi tempor. Nulla quis eros et massa dignissim imperdiet a vitae purus.</p>

14
            ';
15
    }
16
}

At this point, if we installed our module we would have everything we need to create our new Process ProcessSimpleAdminPage and return the content. However, there is currently no page to execute our code. We have several options to do this:

  1. Manually create a new page in the PW pagetree under Admin, give it the template admin and in the field Process: ProcessSimpleAdminPage. Moving the new page in the pagetree list under Settings, for example, will see the page added to the top navigation under Settings.
  2. Add a page attribute to the module’s getModuleInfo() array. If the module extends Process (which ours does), then adding a page attribute array with at least a name and parent on install will automatically create a new admin page under your specified parent with the module as its Process. Here is an example from the hello module.
  3. Create install() and uninstall() functions and add the new page. This is detailed below to show you how you might add a page:
1
public function install(){
2
    // create new page to add to CMS

3
	$page = new Page();
4
5
    // add page attributes, I've called this page CMS FAQ'

6
    $page->template = "admin";
7
    $page->name = "cms-faq";
8
    $page->title = "CMS FAQ";
9
    $page->save();
10
11
    // set this module as the page process, this allows us to display the above

12
    $page->process = 'ProcessSimpleAdminPage';
13
14
    // get admin page and set as page parent

15
    $admin = $this->pages->get("id=2");
16
    $page->parent = $admin;
17
18
    // save page

19
    $page->save();
20
}
21
22
public function uninstall(){
23
    // delete created page

24
    $page = $this->pages->get("name=cms-faq");
25
    if(count($page)) $this->pages->delete($page, true);
26
}

Go forth and create admin pages for your website!

Add Custom Text Formatter

By using Textformatters you can manipulate the input of text fields with the PW admin. For example, say you want to create snippets of code that are added instead of someone typing their own snippets, it’s perfectly possible (in a similar way to the hana code plugin for Wordpress).

This time I’ve created a module that extends another base class Textformatter to create our new module TextformatterFindReplace and created a separate config file:

1
class TextformatterFindReplace extends Textformatter implements Module {
2
3
    public static function getModuleInfo() {
4
    	return array(
5
			'title' => 'TextformatterFindReplace',
6
			'version' => 0.1,
7
			'summary' => "Finds and replaces any instance of config input to config output",
8
			'singular' => true,
9
		);
10
	}
11
12
	/**

13
     * Find and Replace the input string

14
     *

15
     * @param string $str The block of text to parse

16
     *

17
     * The incoming string is replaced with the formatted version of itself.

18
	 **/
19
20
	public function format(&$str) {
21
		$find = $this->findStr;
22
		$str = preg_replace_callback($find, array($this,"replace"), $str);
23
24
	}
25
	// adding three underscores to a function allows other modules to hook it

26
	public function ___replace($match) {
27
		return $this->replaceStr;
28
	}
29
}
1
class TextformatterFindReplaceConfig extends ModuleConfig{
2
3
    public function getDefaults() {
4
5
	    return array(
6
	      'findStr' => '----',
7
	      'replaceStr' => '<b>REPLACED TEXT</b>',
8
	    );
9
	}
10
11
	/*

12
	* getInputfields()

13
	* return:  $inputfields

14
	*/
15
16
	// create form within PW admin to enable configuration of module

17
	public function getInputfields() {
18
19
		// get module getInputfields set config class

20
    	$inputfields = parent::getInputfields();
21
22
		// get InputfieldText module

23
    	$f = $this->modules->get('InputfieldText');
24
    	$f->attr('name', 'findStr');
25
    	$f->label = 'Find in text';
26
		$f->description = 'Add a word or pattern to find and replace within your text.';
27
28
		// add User role input to form config

29
		$inputfields->add($f);
30
31
		// get new InputfieldText module

32
		$f = $this->modules->get('InputfieldText');
33
	    $f->attr('name', 'replaceStr');
34
	    $f->label = 'Replace text';
35
		$f->description = 'text to show on the front end.';
36
37
		// add Page redirect input to form config

38
	    $inputfields->add($f);
39
40
		// return module config inputs

41
	    return $inputfields;
42
  	}
43
}

Now in the module settings I can specify a string to match, and a string to replace it with (in our example above the default is find: ---- and replace with <b>REPLACED TEXT</b>).

All I then need to do is add our new TextFormatter to a text field within the field’s details tab. Now every time I type ---- I will get the replaced text string.

Add New Functionality to Admin Pages

As the PW admin is itself created using PW’s API-like library, PW modules have pretty much access to hook into anywhere you need to.

For my last example on extending PW’s admin, I’ve created a module that adds buttons to the edit page and pagetree, creates two new fields and adds them globally to every page. It requires another module, LazyCron, to operate.

The module PageDeferredPublish, on clicking one of the Publish Later buttons, sets LazyCron to check that page’s countdown every minute and publishes the page when its countdown reaches 0. This means I can publish a page approximately 24 hours in advance (obviously the checking interval and delay time can be changed to your requirements).

I did this by:

  • Creating two fields within my install() function: a checkbox field to set to true when a button is checked to indicate the page should countdown, and a countdown field to store the count in seconds for that specific page.
  • Adding hooks to both ProcessPageEdit::buildForm and ProcessPageListActions::getExtraActions enabling me to add the two buttons.
  • Checking to see if one of the buttons was clicked with my ready() function then setting the corresponding page’s checkbox to true.
  • Using a LazyCron hook function to check all pages that are unpublished for true checkboxes and then comparing the seconds field to see if the page needs publishing. If not then deduct the elapsed time in seconds.

The result is a module that has settings (the time interval to check and publish at a later time), hooks into the admin using buttons and fields, and enables us to use other modules installed in PW (i.e. LazyCron).

Wrapping up

Often, a module you need has already been created and can be downloaded from PW’s module page. However, if you find yourself in need it’s nice to know it is relatively easy to jump in, extend a core class and create new functionality that solves your problem or alters PW’s default solution.

I hope you’ve found this small taster of the power of extending PW useful, and please check out the other ProcessWire tutorials on Envato Tuts+ for more tips and tricks.

Useful Resources







Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.