Jump to content

Name format for children based on any field (not just title)


Lars282
 Share

Recommended Posts

Is there currently a way to base the name of a page on a field other than the title? I am not using the title on multiple templates (e.g. profile pages don't really have a title but fields for first name, last name, etc.). In this case it would be great to base the name derivation on a different field / combination of fields.

If this is not possible by default, could this be done with a module?

Thanks a lot

Lars

Link to comment
Share on other sites

If you want your page names to derive their value from the title field: Enter "title" (without the quotes) as your name format.

Instead of deriving this from the title field, I want to use any other field that the child template has ... but this does not seam to work.

Link to comment
Share on other sites

More or less, yes!

Can I use the existing $parent->template->childNameFormat attribute for this? It seems like a logic extension of the already available functionality. It is already working for the title field and I would want to extend this in two ways: (1) allow any field to be used (2) allow multiple fields to be used, i.e. concatenated with a '-'.

When I simply try to "misuse" the Child Name Format field to store a comma separated list of fields to be used by module, the temp pages created before the fields are filled have a very strange name, e.g.

"am00000030092014sun-09-nov-2014-09-30-12-0000_sundayam123011am11europe-london-am00000030092014sun-09-nov-2014-09-30-12-0000"

As a workaround, I have now adjusted the Pages core process from line 721 (e.g. here: https://github.com/ryancramerdesign/ProcessWire/blob/dev/wire/core/Pages.php#L721) to read as follows (lines 727 to 729 added by me):

		if(strlen($format)) {
			// @todo add option to auto-gen name from any page property/field

			if($format == 'title') {
				if(strlen($page->title)) $pageName = $page->title;
					else $pageName = $this->untitledPageName;
			} else if ($format == 'author_lastname,author_firstname') {
				if(strlen($page->author_firstname) || strlen($page->author_lastname)) $pageName = $page->author_firstname . '-' . $page->author_lastname;
					else $pageName = $this->untitledPageName;
			} else if(!ctype_alnum($format) && !preg_match('/^[-_a-zA-Z0-9]+$/', $format)) {
				// it is a date format
				$pageName = date($format);
			} else {
				
				// predefined format
				$pageName = $format;
			}

		} else if(strlen($page->title)) {
			$pageName = $page->title;

		} else {
			// no name will be assigned
		}

This seems to work exactly as required ... obviously not yet dynamic. Is there a way to achieve this behavior with a module, so that I do not have to adjust the core after every update? Ryan mentioned in a code comment that it was still a todo to make this work, so a module would only be required as a temporary solution.

Thanks a lot

Lars

Link to comment
Share on other sites

@Lars: it is better to not change the core files. If you have a look, your desired method already is precedeed by three underscores: ___setupPageName(. This makes it hookable!

The prefered way is to create a custom module and hook into pages::setupPageName. You can hook into before and/or after, or you also can replace it completly by using addhook instead of addhookbefore / addhookafter.

  • Like 3
Link to comment
Share on other sites

A skeleton as starting point could be:
 

public function HookSetupPageName(Event $event) {
    $page = $event->object;
    $options = $event->arguments(0);

    // maybe a check if the page belongs to a specific template, or not, and if not, return to core function
    if($page->template != 'myspecifictemplate') return;

    // your code here
    ...

    // at the end declare that you want replace the core method with your result
    $event->replace = true;
    $event->return = $name;
    return $name;    
}
  • Like 1
Link to comment
Share on other sites

I have started with a module like below, but it seems that the $page is not correctly available inside my function...

If I take out template check, I get some error about parent() not being a correct method in the context, but if I leave the check in, it always returns to the core function and proceeds as if I didn't have the module in place.

Can it be that I need to assign the $page somehow different?

Also, the setupPageName method edits the $page object - do I also need to specifically a´return the edited page from my module, or is it enough to simply edit it attributes?

Thanks a lot

Lars

public function init() {
	$this->addHookBefore('Pages::setupPageName', function($event) {
		$page = $event->object;
    		$options = $event->arguments(0);

    		// check if the page belongs to templates to be considered, and if not, return to core function
    		if($page->template != 'mytemplate') return;
Link to comment
Share on other sites

You are missing the second / third argument with the addHook call!

  • 'Pages::setupPagename'
  • $this
  • 'functionName'

Also I'm not sure if you can use anonymous functions like you have done. Why do you do want to do this? Is there any advantages over the "normal" method from the docs and the examples?

Have you tried it the other way too?

public function init() {
	$this->addHookBefore('Pages::setupPageName', $this, 'functionName');
}

public function functionName(Event $event) { 
...
Link to comment
Share on other sites

It seems that the issue was with how I got the arguments. I replaced

$page = $event->object;
$options = $event->arguments(0);

with

$page = $event->arguments[0];
$options = $event->arguments[1];

and then it worked as required ...

Using the anonymous function is also part of the documentations somewhere and explicitly shown as an alternative for newer versions of PW / PHP.

  • Like 1
Link to comment
Share on other sites

  • 1 year later...

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...