Hooks to sync pages

I’ve got a calendar on two places in the structure which should have the same content and structure (I know, don’t ask :slightly_smiling:

The goal is: edit the calendar in one place and duplicate the data to the second place.

So I was playing around with hooks and everything seems to work except for sort($page->num()). When I sort pages the num for the specific page gets updated but the other items don’t update their num.
1-item-a
2-item-b
3-item-c

becomes

1-item-b
1-item-a
3-item-c

Anyone with a brilliant idea? (you may find this piece of code interesting :slightly_smiling:

Check out kirby()->hook(‘panel.page.sort’, function($page) {

kirby()->hook('panel.page.create', function($page) {

if($page->template() == 'calendar.year') {

  try {
    $targetdir = str_replace('particulier','organisaties',$page->parent()->id());
    $newPage = page(''.$targetdir.'')->children()->create(''.$page->slug().'', 'calendar.year', array(
    'title'     => ''.$page->title().''
    ));
    return;
  } catch(Exception $e) {
    return $e->getMessage();
  }

} elseif($page->template() == 'calendar.month') {

  try {
    $targetdir = str_replace('particulier','organisaties',$page->parent()->id());
    $newPage = page(''.$targetdir.'')->children()->create(''.$page->slug().'', 'calendar.month', array(
    'title'     => ''.$page->title().''
    ));
    return;
  } catch(Exception $e) {
    return $e->getMessage();
  }

} elseif($page->template() == 'calendar.item') {

  try {
    $targetdir = str_replace('particulier','organisaties',$page->parent()->id());
    $newPage = page(''.$targetdir.'')->children()->create(''.$page->slug().'', 'calendar.item', array(
    'title'     => ''.$page->title().''
    ));
    return;
  } catch(Exception $e) {
    return $e->getMessage();
  }

}
});

kirby()->hook('panel.page.update', function($page) {

if($page->template() == 'calendar.year') {

  try {
    $targetdir = str_replace('particulier','organisaties',$page->parent()->id());
    page(''.$targetdir.'/'.$page->slug().'')->update(array(
      'title'           => $page->title(),
      'subtitle'        => $page->subtitle(),
      'link'            => $page->link(),
      'showpostscount'  => $page->showpostscount(),
      'class'           => $page->class(),
      'metakeywords'    => $page->metakeywords(),
      'metadescription' => $page->metadescription(),
    ));
    return;
  } catch(Exception $e) {
    return $e->getMessage();
  }

} elseif($page->template() == 'calendar.month') {

  try {
    $targetdir = str_replace('particulier','organisaties',$page->parent()->id());
    page(''.$targetdir.'/'.$page->slug().'')->update(array(
      'title'           => $page->title(),
      'subtitle'        => $page->subtitle(),
      'link'            => $page->link(),
      'showpostscount'  => $page->showpostscount(),
      'class'           => $page->class(),
      'metakeywords'    => $page->metakeywords(),
      'metadescription' => $page->metadescription(),
    ));
    return;
  } catch(Exception $e) {
    return $e->getMessage();
  }

} elseif($page->template() == 'calendar.item') {

  try {
    $targetdir = str_replace('particulier','organisaties',$page->parent()->id());
    page(''.$targetdir.'/'.$page->slug().'')->update(array(
      'title'           => $page->title(),
      'subtitle'        => $page->subtitle(),
      'pageup'          => $page->pageup(),
      'date'            => $page->date(),
      'introtext'       => $page->introtext(),
      'fulletext'       => $page->fulltext(),
      'calendar'        => $page->calendar(),
      'nextday'         => $page->nextday(),
      'thumbnail'       => $page->thumbnail(),
      'defaultimg'      => $page->defaultimg(),
      'class'           => $page->class(),
      'buttontext'      => $page->buttontext(),
      'buttonlink'      => $page->buttonlink(),
      'metakeywords'    => $page->metakeywords(),
      'metadescription' => $page->metadescription(),
    ));
    return;
  } catch(Exception $e) {
    return $e->getMessage();
  }

}
});

kirby()->hook('panel.page.delete', function($page) {

try {
  $targetdir = str_replace('particulier','organisaties',$page->parent()->id());
  page(''.$targetdir.'/'.$page->slug().'')->delete($force = true);
  return 'The page has been deleted';
} catch(Exception $e) {
  return $e->getMessage();
}

});

kirby()->hook('panel.page.sort', function($page) {

try {
  $targetdir = str_replace('particulier','organisaties',$page->parent()->id());
  page(''.$targetdir.'/'.$page->slug().'')->sort($page->num());
  return 'The page is now visible and has the sorting number '.$page->num();
} catch(Exception $e) {
  return $e->getMessage();
}

});

kirby()->hook('panel.page.hide', function($page) {

try {
  $targetdir = str_replace('particulier','organisaties',$page->parent()->id());
  page(''.$targetdir.'/'.$page->slug().'')->hide();
  return 'The page is now invisible';
} catch(Exception $e) {
  return $e->getMessage();
}

});

kirby()->hook('panel.page.move', function($page) {

try {
  $targetdir = str_replace('particulier','organisaties',$page->parent()->id());
  page(''.$targetdir.'/'.$page->slug().'')->move();
  return 'The page has been moved';
} catch(Exception $e) {
  return $e->getMessage();
}

});

Hm, can’t test this right now, but it seems that the hooks are a bit buggy anyway: https://github.com/getkirby/panel/issues/701

But out of curiosity: Why do you want to have the same information in two locations?

I told you not to ask ;D

The site has two sections (clients/professionals), both with a calendar but for now the data in both is the same (that may change later). The client doesn’t want to add new events twice so I thought, what if I can create a sort of sync layer between the two.

It works fine except for the sorting part.

I know, but I don’t always listen …:stuck_out_tongue_winking_eye:

Ok, I see. Would it make sense to have only one calendar for both sections and flag the events accordingly using checkboxes for client/professional, and in your templates, filter by those checkboxes? Then you have only one location to enter event data, no matter what it is, especially if there are overlaps between the section.

Hehe :slightly_smiling:

Yeah, been thinking about that also but wanted to see what hooks could do first.

The thing with having a single calendar would be the urls at first thought.

I need clients/calendar/2016/january/training-day-for-whatever and professionals/calendar/2016/january/training-day-for-whatever because visitors need to stay in the correct section.

That would be no problem, as you could still have those pages (or virtual pages using routes), only they pull their content from a single source.

IMO, that would be a more stable solution.

Yeah, still have to explore routes but it crossed my mind.

Thanks for thinking with me.

Do you have an example of how to handle those virtual pages with a router?

Here is an example for a virtual ajax page:

c::set('routes', array(
    array(
        'pattern' => '(:all)/ajax',
        'action'  => function($uri) {
          tpl::load(kirby()->roots()->templates() . DS . 'ajax.php', array('uri' => $uri), false );
        }
    )
));