Jump to content
Adam Kiss

How to modify admin breadcrumbs from module

Recommended Posts

Hi Ryan,

I'm trying to modify urls of links in breadcrumbs in admin pages, however, I can't (right now):

– figure out what to hook to at least 'Breadcrumbs::render' isn't it :) And documentation to hooks is.. well... none.

– figure out how to modify only breadcrumbs to PageEdit pages (although that should be simple preg_match/strpos+substr combo)

Thank you :)

Share this post


Link to post
Share on other sites

Hey Adam,

These breadcrumbs are output in the admin template, so I think you'll want to modify /wire/templates-admin/default.php. But to make sure your changes persist between upgrades, make another copy of that templates-admin to your /site/ dir (http://processwire.com/talk/index.php/topic,161.0.html).

When editing templates-admin/default.php, you should see this part:

<?php
<ul id='breadcrumb' class='nav'>
    <?php
    foreach(wire('breadcrumbs') as $breadcrumb) {
        $title = htmlspecialchars(strip_tags($breadcrumb->title));
        echo "\n\t\t\t<li><a href='{$breadcrumb->url}'>{$title}</a> ></li>";
    }
?>
</ul>

So you can modify that part to do whatever you need. OR, you can modify that wire('breadcrumbs') variable directly, anywhere before the part that outputs the breadcrumbs. It's just a WireArray, so you can manipulate it in the same way as any other WireArray. http://processwire.com/api/arrays/ ... and have a look at this file just so you know what the data type is (it's very simple): /wire/core/Breadcrumbs.php

Here's how to determine if they are currently editing a page from the default.php template:

<?php

if($process == 'ProcessPageEdit') {
    // they are editing a page
}

Share this post


Link to post
Share on other sites

Nooooo! :)

1., I would like to modify that breadcrumbs code template – Independent on template and basically need it in module :)

2., I would like to hook to that breadcrump creation (maybe?) to swap standard PW code with mine [actually, I want the breadcrumbs to go to list pages rather than edit pages for... pages :) (not templates lists, not fields lists, ...), so that's what I'm trying to do.]

Share this post


Link to post
Share on other sites

I didn't see any ways to hook into this at some point earlier than what I mentioned. You can't hook into WireArrays adding stuff... it would just be too slow since WireArrays deal with thousands of add()'s per request. While breadcrumbs don't deal with thousands of items, they do extend the WireArray class. So if you want to hook in via a module, I think you have to hook into something broader than specific to breadcrumbs. Adding a 'before' hook to Page::render would be an example. You could iterate the wire('breadcrumbs') in your module to modify them before the page is rendered: 

<?php

if($process == 'ProcessPageEdit') {
    foreach(wire('breadcrumbs') as $breadcrumb) {
       if(strpos($breadcrumb->url, '/edit/')) {
           $breadcrumb->url = str_replace('/edit/?id=', '/list/?id=', $breadcrumb->url); 
       }
    }
}

Personally I would just modify /site/templates-admin/default.php -- that's what it's there for, and this is why PW lets you customize your admin theme in /site/. Though the technique you use could be the same as in a module (like above). But in the template you could just do this in the existing output loop rather than creating another.

Share this post


Link to post
Share on other sites

Hooking up to Page::render [before] returns wire('breadcrumbs') as null, while [after] returns real breadcrumbs, so they must be generated somewhere between (and I'm looking for creation of the breadcrumbs array, rather than rendering it in browser)

:/

Share this post


Link to post
Share on other sites

Okay now I see why Page::render doesn't work, sorry. Everything has already run by that time. But it looks like there is another option. Try hooking in before ProcessPageEdit::execute

It looks like the breadcrumbs are already setup before that execute() method is called, so wire('breadcrumbs') should be set (and modifiable) in such a hook.

Share this post


Link to post
Share on other sites

if you use Page::loaded, it would be good to add that hook conditionally (like if $this->process == 'ProcessPageEdit', before attaching the hook). Otherwise that hook will get called on every single page loaded in the system -- that's great if that's what you want, but not so great if you are trying to deal with something very specific. If you are loading hundreds of pages in a request, this could be more overhead than you want. Even if you attach it conditionally, it could still involve overhead. For instance, if the page you are editing has Page reference fields, it's going to get called for every page in that page reference field too. Whereas something like ProcessPageEdit::execute would only get called once. But if Page::loaded suits your needs the best, then you could find more efficiency in removing the hook after it's done what you need, so that it doesn't get called any more:

<?php

public function init() { 
    if($this->process == 'ProcessPageEdit') $this->hookID = $this->addHook(...);
}

public function runHook($event) {

    // run the hook
    // ...

    // remove the hook
    $this->removeHook($this->hookID); 

}
  • Like 1

Share this post


Link to post
Share on other sites

I hooked it to Page::loaded [after] already. should be finished soon... You'll see! :)

Hey Adam,

Did you ever get a working solution for this? I haven't tried to code anything up yet, but thought I'd be lazy and see if you had anything to share first :)

  • Like 1

Share this post


Link to post
Share on other sites

Adrian, sorry, I don't even remember what project this was :)

I've tried to go through some of my past projects, which could have been it, but I haven't found anything. New thread with wha you need might be better way to be lazy :)

  • Like 1

Share this post


Link to post
Share on other sites

Thanks Adam - no problem at all - it's for a request for my AdminRestrictBranch module. I'll take a look when I get a chance to see how might be the best way to implement it.

Share this post


Link to post
Share on other sites

Just in case someone else wants to do something like this, I just wanted to note that hooking before ProcessPageEdit::execute and foreaching through wire('breadcrumbs') works well.

But for my particular needs I had problems with this approach and the Reno theme and so had to take another approach which worked: hooking after Process::breadcrumb

Anyway, thought it might be useful info for others.

  • Like 5

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.

×
×
  • Create New...