Jump to content

Getting PageTable containing page values


alexcapes
 Share

Recommended Posts

Hi,

I have a PageTable field that contains fields that I need populate with values from fields in the containing page when the page is saved.

I've tried to do this with a module but I can only get the fields to populate when it's saved for a second time (or saved after publishing), which is not ideal behaviour.

Here's my code:

public function init() {
    $this->pages->addHookBefore('save', $this, 'AddWorkReferenceQuote');
  }

  public function AddWorkReferenceQuote($event) {
    $page = $event->arguments(0);

    if($page->template == 'media_wall_quote') {
     
	if($page->id) {
        $work_page = wire('pages')->get("template=work, media_wall_work=$page");
        $page->media_wall_work_ref = $work_page->work_ref_id;

I think the issue is:

 $work_page = wire('pages')->get("template=work, media_wall_work=$page");

Which doesn't returning the PageTable containing page on first save/publish. 

I've tried changing the hook to addHookAfter but this has no effect and stops it from working altogether.

Anyone have an idea how I can access the containing page of a PageTable page before save?

 

Link to comment
Share on other sites

Getting the containing page seems like it will be difficult because the page isn't added to the PageTable field until after it is saved and published, so a hook on these won't work.

What is the reason for the "media_wall_work_ref" field? Perhaps there is another solution that can achieve the same.

Link to comment
Share on other sites

On 12/11/2016 at 8:27 AM, Robin S said:

Getting the containing page seems like it will be difficult because the page isn't added to the PageTable field until after it is saved and published, so a hook on these won't work.

What is the reason for the "media_wall_work_ref" field? Perhaps there is another solution that can achieve the same.

Basically the media_wall_work_ref was a reference number that relates to the containing page. I was hoping that if this was saved to the PageTable field, then I could make a two way connection between the page and the PageTable field.

Having a look at it, I've rethought my use of the PageTable field because these hooks won't work.

 

 

 

 

Link to comment
Share on other sites

2 minutes ago, alexcapes said:

Basically the media_wall_work_ref was a reference number that relates to the containing page. I was hoping that if this was saved to the PageTable field, then I could make a two way connection between the page and the PageTable field.

Unless you need the reference number inside PageEdit for some reason (e.g. an inputfield dependency, and for that there are workarounds using RuntimeMarkup or FieldtypeReference), it should be possible to get the reference using the API in your template.

You either get the page via the container page's PageTable field, or in the page's template you do similar to what you showed in your first post:

$container_pages = $pages->find("my_pagetable_field=$page");

 

  • Like 1
Link to comment
Share on other sites

BTW, to update pages after they are added to a PageTable field I found one approach, and that is to hook the field save done in InputfieldPageTableAjax.php. The reason you want to hook this for added pages rather than the save of the container page is that the editor could add pages to the PageTable field and then leave Edit Page without saving the page, meaning your hook wouldn't fire.

You have to place the hook in init.php - this hook doesn't fire for InputfieldPageTableAjax.php if you place it in ready.php (would love to know why).

$this->pages->addHookAfter('saveField', function($event) {
    $page = $event->arguments('page');
    $field = $event->arguments('field');
    if(is_string($field)) $field = $this->fields->get($field);
    if($field->name !== 'my_pagetable_field') return;

    $new_value = $page->{$field->name};
    $pages_added = $new_value->getItemsAdded();
    // here save something about $page to a field in $pages_added
});

 

To update pages after they are removed from a PageTable field you would hook Pages::saveReady for the container page and look for changes to the PageTable field, doing something similar to this section of ConnectPageFields.

  • Like 2
Link to comment
Share on other sites

3 minutes ago, Robin S said:

Unless you need the reference number inside PageEdit for some reason (e.g. an inputfield dependency, and for that there are workarounds using RuntimeMarkup or FieldtypeReference), it should be possible to get the reference using the API in your template.

You either get the page via the container page's PageTable field, or in the page's template you do similar to what you showed in your first post:


$container_pages = $pages->find("my_pagetable_field=$page");

 

Ah yeah I think I over complicated the issue (which I find quite easy to do with PageTable fields...!). 

 

Link to comment
Share on other sites

6 minutes ago, Robin S said:

BTW, to update pages after they are added to a PageTable field I found one approach, and that is to hook the field save done in InputfieldPageTableAjax.php. The reason you want to hook this for added pages rather than the save of the container page is that the editor could add pages to the PageTable field and then leave Edit Page without saving the page, meaning your hook wouldn't fire.

You have to place the hook in init.php - this hook doesn't fire for InputfieldPageTableAjax.php if you place it in ready.php (would love to know why).


$this->pages->addHookAfter('saveField', function($event) {
    $page = $event->arguments('page');
    $field = $event->arguments('field');
    if(is_string($field)) $field = $this->fields->get($field);
    if($field->name !== 'my_pagetable_field') return;

    $new_value = $page->{$field->name};
    $pages_added = $new_value->getItemsAdded();
    // here save something about $page to a field in $pages_added
});

 

To update pages after they are removed from a PageTable field you would hook Pages::saveReady for the container page and look for changes to the PageTable field, doing something similar to this section of ConnectPageFields.

Could this help with the issue I'm having with updating on updating PageTable after saving on the modal?

 

Link to comment
Share on other sites

15 minutes ago, alexcapes said:

Could this help with the issue I'm having with updating on updating PageTable after saving on the modal?

I don't know that it will, because the default behaviour for removing pages from a PageTable field involves marking them for deletion (uses JS) and the deletion takes place when the container page is saved. Pages don't disappear from the inputfield when marked for deletion, as opposed to the way pages appear when they are added.

But I can think of some alternatives. Seems like what you want is to have some featured Quote pages: you mark a Quote page as 'featured' when editing that page, and when editing the Home page you can see all the Quote pages that were marked 'featured'.

Option 1: use a 'featured' checkbox on the Quote template. Use a RuntimeMarkup field on the Home template to list all the featured pages, maybe with a link to Edit Page for each featured Quote to make it easy to 'unfeature' a page.

Option 2: Use the ConnectPageFields module. Create a 'featured_quotes' Page field on the Home template (multiple, allows pages using Quote template, uses AsmSelect inputfield) . Create a 'featured_on' Page field on the Quote template (single, allows pages using the Home template, uses Checkboxes inputfield). Link these Page fields in the ConnectPageFields module. Now you can add/remove featured Quotes when editing the Home or a Quote page.

  • Like 1
Link to comment
Share on other sites

2 minutes ago, Robin S said:

I don't know that it will, because the default behaviour for removing pages from a PageTable field involves marking them for deletion (uses JS) and the deletion takes place when the container page is saved. Pages don't disappear from the inputfield when marked for deletion, as opposed to the way pages appear when they are added.

But I can think of some alternatives. Seems like what you want is to have some featured Quote pages: you mark a Quote page as 'featured' when editing that page, and when editing the Home page you can see all the Quote pages that were marked 'featured'.

Option 1: use a 'featured' checkbox on the Quote template. Use a RuntimeMarkup field on the Home template to list all the featured pages, maybe with a link to Edit Page for each featured Quote to make it easy to 'unfeature' a page.

Option 2: Use the ConnectPageFields module. Create a 'featured_quotes' Page field on the Home template (multiple, allows pages using Quote template, uses AsmSelect inputfield) . Create a 'featured_on' Page field on the Quote template (single, allows pages using the Home template, uses Checkboxes inputfield). Link these Page fields in the ConnectPageFields module. Now you can add/remove featured Quotes when editing the Home or a Quote page.

Option 1 is unfortunately not viable as I need the client to be able to reorder the featured quotes.

Option 2 this sounds like it could be perfect but I've tried doing exactly as you said and I'm getting errors. If I try to save the Quote page with the checkbox ticked it timesout with the error:

Error: Maximum execution time of 30 seconds exceeded (line 1431 of /Users/alexcapes/Freelance-work/canongate/01_prototype/wire/core/Page.php) 

If I try to save the 'featured_quotes' page field on the homepage I get the following:

Session: Method NullPage::add does not exist or is not callable in this context

 

  • Like 1
Link to comment
Share on other sites

12 minutes ago, alexcapes said:

this sounds like it could be perfect but I've tried doing exactly as you said and I'm getting errors.

Looks like I didn't test my module for single Page fields. :rolleyes:

Will get that sorted in an update soon. In the meantime just set the 'featured_on' Page field to 'multiple' and it should work.

  • Like 1
Link to comment
Share on other sites

8 minutes ago, Robin S said:

Looks like I didn't test my module for single Page fields. :rolleyes:

Will get that sorted in an update soon. In the meantime just set the 'featured_on' Page field to 'multiple' and it should work.

Ah ha! Yes it's working now! Thank you :)

My final challenge on this is getting a couple of field values from the containing page of the quote into the custom page label format of 'quotes_featured'. I'm going to look at either RuntimeMarkup or FieldtypeReference for that challenge.

Link to comment
Share on other sites

55 minutes ago, alexcapes said:

My final challenge on this is getting a couple of field values from the containing page of the quote into the custom page label format of 'quotes_featured'. I'm going to look at either RuntimeMarkup or FieldtypeReference for that challenge.

Not sure I understand exactly where you need these value to be displayed, but this module may or may not be useful: https://processwire.com/talk/topic/14439-dynamic-description-notes/

Link to comment
Share on other sites

5 hours ago, adrian said:

Not sure I understand exactly where you need these value to be displayed, but this module may or may not be useful: https://processwire.com/talk/topic/14439-dynamic-description-notes/

I got what I needed working using RuntimeMarkup. Basically I needed to have two field values (book name and authors) from the containing page of a PageTable field page copied to the PageTable field page. These fields are needed to display in the Page field where you can select the 'featured' quote. Without the two fields in the dropdown you just have the quote which needs the context of the author and book name.

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