Jump to content
alexcapes

Set order of pages in PageTable field via API

Recommended Posts

I have a PageTable field that is updated via a custom module.

Pages are updated by deleting them then re-adding but crucially need be re-added in the same order in the PageTable field.

If I re-add pages, they go to the bottom of the field (it's a manual drag n drop setting).

Is there a way to re-add where the page was previously? Or at the very least I need to maintain the first page in the field. It has a checkbox ticked if it's first so the re-added page could use that to test whether it needs to go first.

I just don't know how to set the order of pages in a PageTable field via the api.

Any help here much appreciated.

 

 

Share this post


Link to post
Share on other sites

You need to set the "sort" property of each item, so if you keep track if their initial sort value you can set them manually when you add them back in.

Share this post


Link to post
Share on other sites

I think page sorting could sport a more intuitive api like insertAfter/insertBefore/insertAt. But it seems currently most of the sorting stuff is hidden away in ProcessPageSort.

  • Like 1

Share this post


Link to post
Share on other sites
21 minutes ago, adrian said:

You need to set the "sort" property of each item, so if you keep track if their initial sort value you can set them manually when you add them back in.

Would you mind expanding on this Adrian? How would I set the sort property of each item in the PageTable field?

 

 

Share this post


Link to post
Share on other sites
45 minutes ago, alexcapes said:

Would you mind expanding on this Adrian? How would I set the sort property of each item in the PageTable field?

Sure - perhaps you could show me the code you have so far so it will be easier to modify to add the sort value back in.

Share this post


Link to post
Share on other sites

I've actually created a working solution (which I'm sure can be improved upon but it works for now).

I've made a simple module that populates a field ('edition_sort') on each PageTable page with it's order number:

$i = 1;
$editions = $page->editions;
foreach($editions as $edition) {

$edition->of(false);
$edition->edition_sort = $i;
$edition->save();

$i++;
}

I can then get this field ('edition_sort') value from the page being deleted and add it to the newly created page, then sort the PageTable by the field.

It all works but I'm sure there's a much neater way of doing it! 

  • Like 1

Share this post


Link to post
Share on other sites

You should be able to use the built-in "sort" field exactly the same way.

Share this post


Link to post
Share on other sites
9 minutes ago, adrian said:

You should be able to use the built-in "sort" field exactly the same way.

Should this output the sort #? Doesn't seem to output anything for me...

$edition->sort;

Share this post


Link to post
Share on other sites

Yeah, this is what I get where "items" is the name of my pagtable field.

Screen Shot 2016-11-07 at 1.25.27 PM.png

Share this post


Link to post
Share on other sites
1 hour ago, adrian said:

You should be able to use the built-in "sort" field exactly the same way.

I think "sort" is the sort order of the pages as they appear in the tree, which may be different than the order they appear in the PageTable field.

  • Like 3

Share this post


Link to post
Share on other sites
7 minutes ago, Robin S said:

I think "sort" is the sort order of the pages as they appear in the tree, which may be different than the order they appear in the PageTable field.

Wow - you are completely right. It's so weird that the sort db field for the page table field just matches the sort value of the actual pages. When you re-order the entries in the page table field it seems to recreate all the rows in the new order, but without changing the "sort" field value. I wonder if this was intentional or an oversight?

Share this post


Link to post
Share on other sites
8 minutes ago, adrian said:

It's so weird that the sort db field for the page table field just matches the sort value of the actual pages.

I think that's just a coincidence if you add several pages one after the other without reordering them in the field. But because a page that's in a PageTable field can reside anywhere in the page tree there could be other pages added (that have nothing to do with the PageTable field) which would affect the sort property of the page.

11 minutes ago, adrian said:

I wonder if this was intentional or an oversight?

Intentional, because there are really two sort values - the sort property that belongs to the page itself (the tree sort) and the sort that belongs to the PageTable field. This is in the PT database table but doesn't seem to be passed though as a property of the pages when you get them via the PT field.

 

@alexcapes

3 hours ago, alexcapes said:

I just don't know how to set the order of pages in a PageTable field via the api.

The order of the field is set according to the order of pages in the PageArray (or array of page IDs) when you save it to the field. For example:

$page->setAndSave('my_pagetable', array(1009, 1002, 1007)); // an array of page IDs
// or
$pa = $pages->find("template=my_template, sort=title"); // create and sort your PageArray however you like
$page->setAndSave('my_pagetable', $pa);

You could also do things like get the existing PageTable PageArray and then add pages using methods like insertAfter()

But are you sure you have to delete and recreate pages? You could keep the existing pages and change just about any property of them without actually deleting them. Maybe explain the whole process of what you're doing and someone may be able to suggest a different approach.

  • Like 4

Share this post


Link to post
Share on other sites

Thanks again @Robin S - seems like you have looked into this a lot more than me :)

I see now that the sort field in the field is actually correct, but as you said, is not available as a property from the API.

  • Like 1

Share this post


Link to post
Share on other sites
24 minutes ago, Robin S said:

 

The order of the field is set according to the order of pages in the PageArray (or array of page IDs) when you save it to the field. For example:


$page->setAndSave('my_pagetable', array(1009, 1002, 1007)); // an array of page IDs
// or
$pa = $pages->find("template=my_template, sort=title"); // create and sort your PageArray however you like
$page->setAndSave('my_pagetable', $pa);

You could also do things like get the existing PageTable PageArray and then add pages using methods like insertAfter()

But are you sure you have to delete and recreate pages? You could keep the existing pages and change just about any property of them without actually deleting them. Maybe explain the whole process of what you're doing and someone may be able to suggest a different approach.

Thanks for this - I'm going to experiment more with the PageArray and methods like insertAfter().

Unfortunately I do need to delete + recreate the pages. I'm dealing with large XML data files, which are updating existing pages in PW. Not only does the XML update fields but it will sometimes not include fields which is seen as the equivalent of deleting those fields entirely. It gets complicated and messy and was agreed that deleting and recreating the pages was all round cleaner way of doing things. Not ideal I know but it works for this project.

 

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By ngrmm
      I have a page with a table. Each table row has a page-reference field and a checkbox.
      The Page sends emails to all users (page-refrence->email-field) and change the value of the checkbox in a row to 1.
      It works with this:
      <?php // event ID fron url query $eventID = $input->get('eventID','int'); // get event-page $event = $pages->get($eventID); // config $fromEmail = $event->event_mail_from; $fromName = $event->event_mail_from_name; $emailSubject = $event->event_subject; // email html body ob_start(); include('./_inc/emailbody.inc'); $emailBody = ob_get_clean(); // make event-page editable $event->of(false); // loop through table and send out emails foreach($event->event_clients_list as $event_table_row) { // get client page $clientPage = $event_table_row->client_name; // get client email $clientEmail = $clientPage->email; // if client isn't invited yet (checkbox not checked) if($event_table_row->client_invited == '') { // send email $m = new WireMail(); $m->to($clientEmail); $m->from($fromEmail, $fromName); $m->subject($emailSubject); $m->bodyHTML($emailBody); $m->send(); // mark client as invited $event_table_row->client_invited = 1; $event->save('event_clients_list'); } } ?> But i have to use a variable in my emailbody.inc which i'm able to get in the table-loop.
      So i do the including of the body inside my loop. But this doesn't work anymore. Page sends out the emails but is unable to change the value of the checkbox.
      I get no errors!
      I'm using ProTable
      <?php // event ID fron url query $eventID = $input->get('eventID','int'); // get event-page $event = $pages->get($eventID); // config $fromEmail = $event->event_mail_from; $fromName = $event->event_mail_from_name; $emailSubject = $event->event_subject; // loop through table and send out emails foreach($event->event_clients_list as $event_table_row) { // get client page $clientPage = $event_table_row->client_name; // get client email $clientEmail = $clientPage->email; // email html body ob_start(); include('./_inc/emailbody.inc'); $emailBody = ob_get_clean(); // make event-page editable $event->of(false); // if client isn't invited yet (checkbox not checked) if($event_table_row->client_invited == '') { // send email $m = new WireMail(); $m->to($clientEmail); $m->from($fromEmail, $fromName); $m->subject($emailSubject); $m->bodyHTML($emailBody); $m->send(); // mark client as invited $event_table_row->client_invited = 1; $event->save('event_clients_list'); } } ?>  
    • By Vigilante
      In general, is there an easy way to know which method should be used to access the API?
      For example, when _ini.php is used in the theme, it would seem you have to use wire()->addHookBefore(...). But on other sites where they used ready.php, I've seen it go straight to just doing $this->addHookAfter() even though there is no class or namespace set up in the ready.php file.
      So how do I know when I can do $this, or $wire, or wire() to access things? And any other variables I'm not aware of.
      Thanks!
    • By Noel Boss
      Hi everyone 🙌
      Is there a way to order the language tabs in the backend? Currently, they seem to be ordered based on the created date (or id?) …
      ( time passes … ⏰ 🚶‍♂️)
      Just answered my own question. One can reorder the languages in the page tree under admin » languages or directly in the DB » pages » template_id=54 » sord field.
      Anyone knows if there are side effects when moving the default language from sort 0 to somewhere higher?
    • By VeiJari
      Hello forum,
      This is really a weird one, because front end editing works in a earlier website we did to a customer. 
      When I check the source code for current website it does initiate front end edit: 
      <span id=pw-edit-1 class='pw-edit pw-edit-InputfieldPageTitle' data-name=title data-page=1021 data-lang='1017' style='position:relative'><span class=pw-edit-orig>Tekijät</span><span class=pw-edit-copy id=pw-editor-title-1021 style='display:none;-webkit-user-select:text;user- select:text;' contenteditable>Tekijät</span></span>  But when I double click nothing happens (yes I'm 100% sure I'm superuser and logged in)
      I also tried to apply the front end with other methods than:
      $page->edit('title'); But didn't work either.
      We are using jquery 2.2.4, so it should not be a problem.
      Is this a bug related to current master or something else?
      Someone else having this problem as well?
    • By jom
      Hi everyone
      It seems that I don't fully understand the wireTempPath() function and I need some help.
      I use wireTempPath() to create a new location in assets/cache/WireTempDir and than copy a pdf from the assets/files/page folder to the new folder. I want the file to be accessible only for a limited time, that's why I use wireTempPath.
      The file seems to be copied to the right location, but gets deleted right afterwards, according to 
      As mentioned in the topic above, 
      $wireTempDir->setRemove(false); prevents the file to be deleted. But I like the file to be automatically deleted after a few days. So, how can I do that?
      My code so far (everything works, but the automatic removal of the tempDir folder):
      //generate and show download link $folder = time(); // timestamp as temporary folder $maxAge = (int) $settings->options_downloadlink_valid_hours * 3600; //tempDir wants maxAge as seconds $options = array( 'maxAge' => $maxAge ); $wireTempDir = wireTempDir($folder, $options); $wireTempDir->setRemove(false); $src_file = $page->ebook_download->filename; // Create a new directory in ProcessWire's cache dir if(wire('files')->mkdir($wireTempDir, $recursive = true)) { if(wire('files')->copy($src_file, $wireTempDir)){ //get subdirs from tempDir: $pos = strpos($wireTempDir, "WireTempDir"); $subdir = substr($wireTempDir, $pos, 100); $out .= "<p><a href='" . wire('pages')->get('template=passthrough')->httpUrl . "?file=" . $subdir . $page->ebook_download->basename . "' target='_blank'>$page->title</a></p>"; } } I appreciate any ideas - thanks!
      Oliver
×
×
  • Create New...