Jump to content

How to provide admin interface for editors?


jordanlev
 Share

Recommended Posts

Finally setting up an actual site with ProcessWire, and I'm baffled about how to set up the following situation:

* I have two data entities, "products" and "locations". So there will be a template for "product" and "location", and a product can be in any number of locations so I will use a page field to link the two.

* I have users who are *not* super-admins, but rather in a group I created called "editors". These users should have access to edit site pages but not configure templates and fields.

* I want to have 2 pages in the admin section that will contain the master lists of products and locations (the front-end of the site will use queries to display the appropriate data -- there will *not* be front-end pages representing these data entities, so I will house them under the admin section).

My first problem is that I can't just create pages under the "Admin" page, because there is no way for my "editor" users to see those via the page tree. I tried creating a new template for those 2 top-level "products" and "locations" pages, so I could assign permissions on them for the editors to be able to see them and add new pages underneath, but that didn't work because the editor users were never shown the sub-pages under the top-level "Admin" page. (Also there was no way to render the page contents within the overall admin theme... it appears you can only do that via Process Modules).

So I created ProcessModules for these 2 pages ("ProcessProductsAdmin" and "ProcessLocationsAdmin"), which can have permissions assigned in the module info, and also their pages will show up in the admin primary nav menu. So far, so good.far.

But now how do I actually create the interface on these pages to allow users to manage the individual "product" and "location" pages underneath? I read some things about the new "Lister" module in 2.5 which looks like it might work, but in the demo video ( 

), it shows an option to create a new lister, but this option does not appear on my site. I could re-create my own list of sub-pages, but then I'm having to do all of my own code for adding new sub-pages, editing, deleting, and re-ordering... which seems counter-productive (like, why am I bothering to have these data records stored in the "ProcessWire way" where they are pages and fields, if I'm having to write my own code to manage them instead of leveraging the functionality of the CMS?)

I came across this forum thread, where people seem to be talking about what I'm trying to do (well, just the "edit a page" part, not the "list pages and allow adding new, re-ordering, and deleting" part): https://processwire.com/talk/topic/6090-page-edit-in-another-module/?p=59589

...but you can see in the screenshot of the post I linked to that Tom Reno has kind of done what I'm asking to do... but I have no idea if that is just done with built-in functionality or if he went through the trouble to create his own code for that.

Seems like I'm going around in circles here... I'm hoping there's a relatively easy way to accomplish this within ProcessWire (since the whole point of using a system like this is to try to avoid writing my own code that creates/edits/deletes/sorts records).

Thanks!

Link to comment
Share on other sites

My first problem is that I can't just create pages under the "Admin" page, because there is no way for my "editor" users to see those via the page tree. I tried creating a new template for those 2 top-level "products" and "locations" pages, so I could assign permissions on them for the editors to be able to see them and add new pages underneath, but that didn't work because the editor users were never shown the sub-pages under the top-level "Admin" page. (Also there was no way to render the page contents within the overall admin theme... it appears you can only do that via Process Modules).

I think you are nearly there!

Instead of creating locations and products under the Admin parent page, create a new top-level hidden page called something like "Items" (or other name relevant to your sector), and then add the Locations and Products pages underneath that.

As it's hidden, it won't show on the front-end; and then you can just grant your editor role permission to edit those pages via the template "Access" settings at either the "Items" template, or products or locations - whichever will suit you the best.

Link to comment
Share on other sites

Some usefull modules are the AdminCustomPages addon!!

https://processwire.com/talk/topic/3474-admin-custom-pages-module/

you can control all the output via template access and roles but can use it with adminpages!!

and do the code with the api in a simple template....it's really great.

For me i've used the pagetree with different parent (hidden page like craig wrote!) and use the system popup box for editing:

https://processwire.com/talk/topic/7836-cant-wait-first-project-with-pw-nearly-finished/

(at the end of this post - i've used this for images and documents - but could used fo all)

regards mr-fan

you could even use the table formats in the backend to get a table editing via the api maybe you could look at this module:

https://processwire.com/talk/topic/5364-jquery-datatables-modulejs/

https://processwire.com/talk/topic/704-datatable/

https://processwire.com/talk/topic/3463-simple-custom-admin-page-for-online-store/

Link to comment
Share on other sites

Thanks for the great suggestions! @mr-fan, what a fantastic write-up of that first site you built -- gives me lots of ideas and new things to discover (like the "Template Decorator" and the "FormTemplateProcessor").

I wound up discovering a relatively easy way to achieve what I want, by creating a Process Module as follows:

<?php

class MyProductsAdmin extends Process {

	public static function getModuleInfo() {
		return array(
			'title' => 'My Products',
			'summary' => 'Dashboard interface for managing product data pages)',
			'version' => '001',
			'author' => 'Jordan Lev',
			'permission' => 'page-edit',
			'page' => array(
				'name' => 'my-products-admin',
				'title' => 'My Products',
//				'parent' => 'setup', //commented out because we want to be directly under admin
			),
			'nav' => array(
				array(
					'url' => 'products/',
					'label' => 'Products',
					'icon' => 'cubes',
				),
				array(
					'url' => 'locations/',
					'label' => 'Locations',
					'icon' => 'building',
				),
			),
		);
	}

	public function execute() {
		return $this->render('menu');
	}

	public function executeProducts() {
		$pages = $this->pages->find('template=product');
		return $this->render('products', array($pages));
	}

	public function executeLocations() {
		$pages = $this->pages->find('template=location');
		return $this->render('locations', array($pages));
	}

	private function render($template, $vars = array()) {
		$template_file_name = $template . '.' . $this->config->templateExtension;
		$template_file_path = $this->config->paths->MyProductsAdmin . "/templates/{$template_file_name}";
		$template_file = new TemplateFile($template_file_path);
		$template_file->setArray($vars);
		return $template_file->render();
	}
}

I found some really handy comments in /wire/core/Process.php file -- some features which I didn't find googling around or searching the forums -- basically you can create a sub-nav that corresponds to your various "execute" methods. Also note that I have a sub-directory called "templates" in my module directory, and this is where I can put the various templates I want to render for these admin pages (for example, "/templates/products.php" and "/templates/locations.php").

So this achieves one of my goals: it creates a new admin section that can be seen by people with the "edit-page" permission, and it has sub-pages underneath in the admin nav. The code I posted above is a simplified example... I actually implement a rails-like MVC system within this module (so each executeSomething() calls a controller class and passes it sub-actions for 'list', 'edit', 'delete', etc.)... but I wanted to keep this code simple for the sake of explanation.

Note that this module is only for the "admin interface" to the data (pages)... the pages themselves don't actually live under this module, but rather I created a separate page under Admin called "my-products-data" and all pages representing my products and locations live under there. This admin interface module basically treats that "data" section as a database... users will *not* be interacting with those pages directly in the site pages tree, nor will end users ever see those pages (because they're under "Admin"). This is exactly how I want it (although I can understand that other people might prefer to set up their sites differently, so I'm not saying this is the best solution for everyone, but it works for me).

The other half of my problem: listing / adding / editing / sorting / deleting pages... it appears that there is no automatic functionality in ProcessWire to achieve this. It looks like the new "ListerPro" module can handle this to an extent (it can list pages matching a certain selector, and provide actions to move/edit/delete them), and that would probably be a fantastic option if you don't want to have to do much programming. But I am very particular about the editing interfaces I provide to my non-technical clients: I want them to be as easy-to-use and straightforward as possible, and I think a downside to the PW admin is that you wind up with a slightly confusing interface (which is understandable because it needs to be all things to all people -- and it does a surprisingly good job at providing all these capabilities). So what I realized is it won't actually be too difficult for me to craft my own "CRUD" interface for these pages. Here's generally how I did this:

  • top-level "index" page for products/locations: I retrieve all pages having the 'product' or 'location' template, and output them into a table. Each row has an "edit" and "delete" button. And at the bottom is an "Add New" button.
  • Clicking the "Add New" button programatically creates a new page of the desired type and places it under the proper parent page in the "/admin/my-products-data" section of the sitemap. It assigns it the title "Untitled Product" (or "Untitled Location"), and the name is irrelevant (pw will auto-generate one, it doesn't matter because these pages only serve to store data... they are not used for display, and they will always be retrieved by id and not name). Then after that new page is created I redirect the user to the "edit" page.
  • Clicking the "edit" button on a record (or being redirected here from the "add new" function) uses this technique from soma to display the page's form with all the defined fields: https://gist.github.com/somatonic/5011926 (but note that you only need the first part of that code... *not* the "head.php" part of it because we're already in the admin section so the necessary js and css is already loaded by the system!).
  • Clicking "delete" on a record asks for confirmation from the user and then programatically deletes the page.
  • Sorting: I've implemented my own drag-and-drop sorting using jquery UI sortable... upon a drag-drop, an ajax request is sent back to the module (I have a "execute" method that reponds to it) containing the ordered list of id's... this method then sets the "sort" field on the appropriate pages. Note that this is only feasible for lists where you show all "records" (pages) at once... if you had paginated the list it is probably too long to allow for sorting manually like this.

So that's the basic idea... I did wind up having to recreate some functionality from scratch, but not much... the fact that I can leverage the "page edit" form using soma's code snippet means that the hard part is already taken care of for me :)

The structure I have laid out here gives me a lot of flexibility to manage my pages exactly as I want them to be, while providing my non-technical clients a very intuitive interface that shows them only what they need to manage their data. I actually have a much more complex schema than just "Products" and "Locations" (I wanted to keep things simple for this question so I didn't bother mentioning it)... so fortunately this technique will accomodate all sorts of crazy structures (because I am programmatically adding the pages, so I can be sure the correct type/template is used and it is placed in the proper location of the site tree... and in some cases I am actually creating several pages of different types based on 1 user action... e.g. placing a new "order" will create both an "order" page and sub-pages for each "line item" in the order, etc.).

Anyway, just wanted to write this up in case others (who think like me) want to do this in the future. Or if I forget about it in 6 months and need to read through some docs on it :)

Link to comment
Share on other sites

I don't think you need to place your data into admin branch. Why? It's meant for admin stuff and it would be no problem to put them in the root of home. If you don't have a template file they are not viewable or you could protect them by removing guest view access.

I can't agree with that the page tree and editing sorting deleting or crud if you will is confusing. Quite the opposite. And this is from a experience in about dozen different projects with no technical savvy users. Often we don't even need to explain them. While you of course can easily build custom crud and stuff I thonk you do too much for thinga already there. You don't have to build that really.

Edit. Don't get me wrong I don't mean it's all completely wrong. Just scratching my head and you must be hating me already :)

To me it sounds like. Ok I want only data, no frontend so I pllace them in admin/ .. but then users can't access them or edit them so I create my rails mvc crud to let them do edit them. While you can easily place them outside admin/ and let PW handle all this jus fine. But maybe I don't get what really is the reason.

Also you can render part of the tree in your module and have them edit using pw edit screen and sort or delete them with a fee lines of code.

  • Like 2
Link to comment
Share on other sites

Hey @soma,

I see what you mean about having the pages outside of the "Admin" section... I wasn't sure I would be able to hide them effectively until Craig mentioned this in his response above.

As for re-creating the editing interface... my issue is that I actually have a more complex data model than what I've used for an example in this thread. Specifically, a product can have "product variations" and "product locations". The product variations each have a name and a price (and some other miscellaneous info). The product locations also have additional info (so it's not just a reference to a location page from a product page). What I'm imaging is having sub-pages under each product for "variations" and "locations", then a page type for "product-variation" and another page type for "product-location". I'm concerned that it will get too tricky for my users to have to remember to add these various things in the right place. Instead I'd like for them just to be able to view a list of products, then click on a product to see a list of BOTH the variations AND the locations, and edit all that info in one place. (I know what you're thinking: I can have a "page" field that allows multiple selections... but again the problem is they aren't just choosing variations and locations, rather there is associated information pertaining to each one).

So maybe there is a way to achieve this management of complexity via the built-in page tree? Maybe some kind of Table or PageTable field? I would be very open to hearing suggestions... which is why I posted this question in the first place (and am really glad to have gotten so much good info from you and the other guys).

Last: Can you please explain in detail how to achieve "you can render part of the tree in your module and have them edit using pw edit screen and sort or delete them with a few lines of code"... I would *love* to see this code, if you could provide it.

Thank you!

Link to comment
Share on other sites

@jordanlev:

Commenting quickly on this. You want to use PageTables - you'll love them. They will provide your project the ability to include the product locations and variations on the same page with your product.

PageTable-fields have their own template attached to them. In your case, you can probably go ahead and use the existing product-variation and product-location templates. You just create two new PageTable-fields, one for each template and then attach the new fields to your product-template. For more information, check this post for an example https://processwire.com/talk/topic/6417-processwire-profields-table/?p=63119.

And don't be mislead by the term "field", these are pretty badass fields.

  • Like 5
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...