Jump to content

Changing structure of Pages


cehlo
 Share

Recommended Posts

Hi,

so I am starting my first bigger project in PW after some smaller. My actual challenge is to make website portal, internal managment of DB and Newsletter. My problem is the structure of pages tree. Normal: 

- Home 

      - About 

      - ...

      - Internal Db / hidden / - some basic data structure to manage, members of clubs and their info for example /

      - Newsletter / hidden / 

 

I am finding these little bit chaotic, or misleading for my client and not very good for my purpose. I also want to make admin home page dashboard, where client can choose only to manage website, internal Db or Newsletter. So my idea for better strucure is this: 

- WebPortal / empty page which only contains all above mentioned / 

     - Website Home

             - About...

     - Internal Db 

     - Newsletter 

 

I can't find solution for this matter here on Processwire website and my first tries always crashed on moving Home to child, and exclude it from nav etc... Maybe solution is Multisite Modul, but I don ' t need more domains so it is irrelevant.

I just really love PW, hope I wil make it here! 

Cheers.

 

Cehlo 

Link to comment
Share on other sites

Welcome to the forums. ?

8 hours ago, cehlo said:

my first tries always crashed on moving Home to child

The structure of the page tree (Page List) always reflects the path to pages on the front-end. That fact is part of the ProcessWire philosophy that Ryan has talked about somewhere (can't remember where exactly). So you can't have the Home page appear anywhere other than at the root of the page tree.

 

8 hours ago, cehlo said:

I also want to make admin home page dashboard, where client can choose only to manage website, internal Db or Newsletter.

In terms of having a dashboard instead of Page List there are several forum topics that are relevant. A Google search will find them: https://www.google.com/search?q=site:processwire.com+dashboard

 

And here is another approach you can try...

1. Install the AdminOnSteroids module, and use the "Add pages to navigation" feature to add your Internal DB and Newsletter pages as custom nav items. This will add those pages to the Pages menu so that if you click them you'll see only those sections in Page List.

2. Add a hook to /site/ready.php (add the file if it doesn't exist) so that your Internal DB and Newsletter pages do not appear in the main Page List, so they are not confusing to your users.

$wire->addHookAfter('Page::listable', function(HookEvent $event) {

    // Only for non-superusers
    if($this->user->isSuperuser()) return;

    // The ID of the page that Page List is listing children of
    $id = $this->input->get->int('id');

    $page = $event->object;
    // Don't list pages with certain templates under Home (adjust template names as needed)
    if($id === 1 && ($page->template == 'internal_db' || $page->template == 'newsletter')) {
        $event->return = false;
    };

});

 

  • Like 3
Link to comment
Share on other sites

Hello Robin, 

thank you for your answer! 

9 hours ago, Robin S said:

The structure of the page tree (Page List) always reflects the path to pages on the front-end. That fact is part of the ProcessWire philosophy that Ryan has talked about somewhere (can't remember where exactly). So you can't have the Home page appear anywhere other than at the root of the page tree.

Yes I am aware of this, but I was looking if there is some solution to override this, or simply make empty page only for structure, which will not react to Processwire page tree, so only visual structure purpose.

Dashboard is not a problem, I have already prepared stuff for this.

Your solution looks very interesting and I will definitely look into it, and I think in each case I will implement this module also. But I was playing, searching, experimenting and here is what I found out like solution in my case:

- I make new template root, which will have the root page - old home page:

<?php
	echo $pages->get(1017)->render(); // render content from new Home page
?>

Then I make new home page, and get to it homepage template. And to  _head.php I just change navigation to exclude old home page title from nav - so basically use url from root and title from new home page. ( To eliminate issue with url after clicking on home - test.dev/home, expected: test.dev ).

<?php
	homepage = $pages->get('/home/');
	$children = $homepage->children();

	echo "<li><a href='$urls->httpRoot'>$homepage->title</a></li>"; // Making first item in nav, overriding url issue 

	foreach($children as $child) {
		if($child->id == $page->rootParent->id) {
			echo "<li class='current' aria-current='true'><span class='visually-hidden'>Current page: </span><a href='$child->url'>$child->title</a></li>";
		} else {
			echo "<li><a href='$child->url'>$child->title</a></li>";
		}
	}
?>

So now it is working like charm, but I want to ask if this is optimal solution, if there are some disadvantages for this, maybe in SEO?

I just found out that one problem will be url structure of child pages of home - it is not very charming like this - test.dev/home/about, etc.. 

Thank you. 
 

Link to comment
Share on other sites

 

The AdminOnSteroids is just awesome, I didn't know something like this exists. But the other part of your solution does not seems to work the addHookAfter function throws this error: Call to a member function addHookAfter() on null. Some suggestions? 

 

ll 

Link to comment
Share on other sites

9 hours ago, cehlo said:

the addHookAfter function throws this error: Call to a member function addHookAfter() on null

That's weird - the $wire API variable should be in scope there. Add the ProcessWire namespace to the top of /site/ready.php if it isn't there already. You are running PW 3.x right? And double-check the ready.php file is in the right place, in the /site/ folder and not in /site/templates/ or anything like that (I only mention it because it's happened before ?). Your /site/ready.php file should look like this:

<?php namespace ProcessWire;

$wire->addHookAfter('Page::listable', function(HookEvent $event) {

    // Only for non-superusers
    if($this->user->isSuperuser()) return;

    // The ID of the page that Page List is listing children of
    $id = $this->input->get->int('id');

    $page = $event->object;
    // Don't list pages with certain templates under Home (adjust template names as needed)
    if($id === 1 && ($page->template == 'internal_db' || $page->template == 'newsletter')) {
        $event->return = false;
    };

});

Here is more information about /site/ready.php: https://processwire.com/blog/posts/processwire-2.6.7-core-updates-and-more/#new-core-files-for-site-hooks

Link to comment
Share on other sites

7 hours ago, cehlo said:

Some idea?

Are you logging in as a non-superuser?

If that's not it and you have copy/pasted the hook code then it would be worth checking to see if any invisible characters got pasted which will prevent the code from working. I notice that this forum software has gotten quite bad recently at inserting invisible characters into code blocks - I see these characters in the email notifications I get from the forum.

Most reliable thing for short blocks of code from the forum is to retype them yourself in your code editor. Another way is to use a tool that shows hidden characters. When I copy/pasted the hook code above into this online tool this is what I got:

2018-09-25_091824.png.c7e3f6930ac3d598a19b870111cff1b9.png

 

If that's still not it then I'm out of ideas, but you can try debugging with Tracy Debugger. Assuming you are developing your site locally, you'll need the "Force guest users into DEVELOPMENT mode on localhost" option checked in order to see the Tracy bar when logged in as a non-superuser. Bar dump $id and $page->template->name to check that these are what the hook is looking for in the conditional.

I've modified the hook slightly just to make it clearer how the conditional relates to what you will be seeing in the bar dumps:

$wire->addHookAfter('Page::listable', function(HookEvent $event) {

    // Only for non-superusers
    if($this->user->isSuperuser()) return;

    // The ID of the page that Page List is listing children of
    $id = $this->input->get->int('id');

    $page = $event->object;
    
    // Dump to Tracy bar
    bd($id, 'parent page id');
    bd($page->template->name, 'template name');
    
    // Don't list pages with certain templates under Home (adjust template names as needed)
    if($id === 1 && ($page->template->name === 'internal_db' || $page->template->name === 'newsletter')) {
        $event->return = false;
    };

});

 

  • Like 3
Link to comment
Share on other sites

OK, I finally get it working. I must admit that I don't know where the problem was. Solution with Page::listable, does not seem to work. I was using also Tracy debugger, bardump - return what I expected, but nothing changes on page. So I was doing little testing and searching and I come with this, which seems to work. ? 

<?php namespace ProcessWire;

$wire->addHookAfter('ProcessPageList::find', function(HookEvent $event) {
	if($this->user->isSuperuser()) return;

    $pages = $event->return;

        if($this->config->ajax){
            foreach($pages as $p) {
                if($p->template == 'test') $pages->remove($p);
            }
            $event->return = $pages;
        }

});

 

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