Jump to content

How to hook into page ADD NEW and change sort order?


Klenkes
 Share

Recommended Posts

My clients website has a lot of categories and subcategories and editors mainly use ADD NEW. The sort order of categories there don't represent the sort order of the page tree (sometimes) and editors are complaining... (it's a looong list)

The first item is Balken -> Nadelholzbalken, but there are a few item more. They are way down at the bottom.
I couldn't figure out the existing sort order. It's not by ID.

There has to be a way to hook into this function and change sorting somehow?

image.png.13620172ca07967c64cd6d9378fe0c58.png

Link to comment
Share on other sites

To render the screen you showed, this happens:

  1. ProcessPageAdd::execute() is called. This is hookable, so you could mangle its markup output, but it’s going to be disgusting.
  2. Because neither parent nor template were given, execute() now calls renderChooseTemplate() and immediately returns its result. renderChooseTemplate() is not hookable.
  3. Within renderChooseTemplate(), ProcessPageAdd::executeNavJSON() is called. This is hookable, but it’s not going to be very useful.
  4. executeNavJSON() – surprise – doesn’t return json but an associative PHP array containing, among other things, the templates you’re allowed to add. It will sort these alphabetically by name using ksort().
  5. Back in renderChooseTemplate(), the allowed parents for each of these templates are now queried using this selector:
    $pages->find("template=$parentTemplates, include=unpublished, limit=100, sort=-modified")
    So now you know why Nadelholzbalken is #1: it was most recently modified. Also it’s hardcoded to only show 100 pages. Both are not easily changed.

So yeah, you’re basically stuck with post-processing the output of ProcessPageAdd::execute() and being limited to the 100 most recently modified pages.

Alternatively you could build the list yourself. It’s only a bunch of links to ./?template_id=123&parent_id=4567 after all. Something like this:

$this->addHookBefore("ProcessPageAdd::execute", function(HookEvent $event) {
    $process = $event->object;

    if (input()->get('template_id') || input()->post('template_id'))
        return;
    if (input()->get('parent_id') || input()->post('parent_id'))
        return;

    //we weren’t given a parent or a template, so we build our own list
    $event->replace = true;

    $templates = $process->executeNavJSON(array('getArray' => true))['list'];

    $out = '';

    foreach($templates as $tpl_data) {
        if(empty($tpl_data['template_id']))
            continue;

        $template = templates()->get($tpl_data['template_id']);
        if (!$template)
            continue;

        $out .= "<h3><a href='./?template_id={$template->id}'>{$template->name}</a></h3>";

        $parentTemplates = implode('|', $template->parentTemplates);
        if(empty($parentTemplates))
            continue;
        $parents = pages()->find("template=$parentTemplates, include=unpublished, sort=title");

        $out .= '<ul>';
        foreach($parents as $p)
            $out .= "<li><a href='./?template_id={$template->id}&parent_id={$p->id}'>{$p->title}</a></li>";
        $out .= '</ul>';
    }

    $event->return = $out;
});

Obviously this looks like ass, but functionally that’s the gist of it.

  • Like 2
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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...