Jump to content

Adding pages without "name" field and automatically creating sub-pages


Luke Solar
 Share

Recommended Posts

Hello,

I have a page structure as follows:

- Company (only this page has a corresponding php template to show data)

  - Adresses 

    - Street/ZIP #1 (template "address" without php file)

    - Street/ZIP #2

    - ...

  - Projects

    - Project #1 (template "project" without php file)

    - Project #2

I would like to have the following workflow:

1. When I create a new Company, the pages "Addresses", "Projects" (only placeholders to structure data) should be created automatically.

2. When I add a Project or Address, the first step (Setting a "name", Selecting the only allowed template) should be skipped, instead an empty address should be created with just an ID and the name should/can use the ID too. 

Anyone knows of a module which helps here? something like "Entities4Processwire". I really like the Idea of everything is a page, but for structure only sometimes Im missing an "Entity" with just an id and custom fields.

I checked the core module ProcessPageAdd and probably the "___execute" method of the module would be the place to hook into, right?. Would be nice to hear your thoughts about this. 

Thanks!

Link to comment
Share on other sites

I did not use repeaters for these reasons:

  • I need to access lists of addresses and lists of projects with full access to their parents. Filter them with different criterias (project start date, address discrict,..) I found it not really convenient to "search" through repeater fieldtypes. E.g.: latest projects (showing also the company name etc), list of ALL addresses on google maps with infowindow including data from the parent (company). 
  • When I have more then 5-10 items its not really good usability to have such a huge form.
  • Somewhere its said that repeaters are not "infinitly scalable" but I would need to store a lot of addresses and work with them independently.

Would you agree on these points? Thanks for your comment. 

Hope to find a way to get rid of these repeating tasks to give a "name" to an address and create the placeholders for sub-pages just to structure them in the backend. Its annoying for the client. I hope that anyone has come across this....

Link to comment
Share on other sites

Those are valid points and I think using children is much cleaner here.

It is pretty trivial to build module which would create those two container pages whenever you add new company. I have posted one example in past, but on mobile now so cannot really search.

Second point: you can skip template selection (with family settings on template edit), but still need title / name. But you can modify the title label for address or project title.

Link to comment
Share on other sites

I'm not aware of any ready made modules that do exactly what you need but the placeholder creation part seems pretty straightforward. Some searching reveals this and this. Might be helpful.

Part 2, the skipping of name creation technically doesn't seem possible, because every page needs this. I guess you could make it so that 'name' is automatically/under water, populated by an id value. I'm not sure that a page id is already available before a page is first created though. Don't know how to tackle this.

Link to comment
Share on other sites

  • 2 weeks later...

Very nice - It was quite easy to add the 2 subpages. I added a Hook after 'save' and with $hookEvent->arguments[0] you get the page and add the Subpages if necessary

Module Code:

public function init() {

		// add a hook after the $pages->save
		$this->pages->addHookAfter('save', $this, 'createSubPagesForCompany'); 

	}

	/**
	 * Hook into the pages->save method and create two subpages if necessary
	 *
	 */
	public function createSubPagesForCompany($event) {
		$page = $event->arguments[0]; 
		$templates = wire('templates');

		// only for template 'company'
		// create two subpages 'engagement_list' & 'address_list' if necessary
		if (!$page->isTrash && $page->template->name == 'company'){
			if ($page->children('template=engagement_list')->count()==0){
				// create engagement list
				$eng_list = new Page($templates->get('engagement_list'));
				$eng_list->parent = $page;
				$eng_list->name = 'engagements';
				$eng_list->save();
				$this->message("Engagement Liste erstellt.");
		
			}
			
			if ($page->children('template=address_list')->count()==0){
				// create address list
				$addr_list = new Page($templates->get('address_list'));
				$addr_list->parent = $page;
				$addr_list->name = 'adressen';
				$addr_list->save();
				$this->message("Adressliste erstellt."); 
				
			}
	
		} 

		
	}
  • Like 2
Link to comment
Share on other sites

For the Automatic Name I wrote another module. It adds "template_[id]" as the name. Only if its the only allowed template to add AND it has no template file associated. This is basically usefull to group entities. e.g.

-- company

  -- address_list

    -- address_1

    -- address_2

I hook into the ProcessPageAdd ___execute Method. Its the only hookable method in the Module. And all properties are protected. I didnt want to check allowedTemplates again with custom code so I made the function of the ProcessPageAdd Module "getAllowedTemplates()" public. The parent_id is also available in the ProcessPageAdd object could be better to write a getter for that property too but I didnt want to change the core module "ProcessPageAdd" too much.

Any suggestions?

	public function init() {

		// add a hook after the Page/Add (= ProcessPageAdd.___execute())
		$this->pages->addHookAfter('ProcessPageAdd::execute', $this, 'addNameAndProceed'); 

	}

	/**
	 *  If we add a page to a EntityList
	 *
	 */
	public function addNameAndProceed($event) {

		$pageAddObj = $event->object;
		$allowedTemplates = $pageAddObj->getAllowedTemplates();

		$template = reset($allowedTemplates); // reset = first element in associative array

		// only execute if there is only 1 allowed template 
		// AND it has no file associated (means not visible / no real url)
		if (count($allowedTemplates)!=1 || is_file($template->filename)){
			return;
		}

		$parent_id = 0;
		if(isset($_POST['parent_id'])) {
			$parent_id = (int) $_POST['parent_id']; 
		} else {
			$parent_id = isset($_GET['parent_id']) ? (int) $_GET['parent_id'] : 1; 
		}
		
		//$event->replace = true;
		//$template = wire('templates')->get('engagement');

		$page = new Page($template);
		$page->name = 'dummy123'.rand();
		$page->parent = $parent_id;
		$page->save();
		$page->name = $template . "_" . $page->id;
		$page->addStatus(Page::statusUnpublished);
		$page->save();

		$this->message("Automatically added a Name (the id). Entity ready for edit."); 
		$this->session->redirect("../edit/?id={$page->id}");

		
		
	}

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

×
×
  • Create New...