Jump to content
ryan

How do I create a page that redirects to it's first child?

Recommended Posts

I really need to create pagetype, that will redirect me to first of it's children... I.E.

- Page 1 {/page1/}

- Child 1 {/page1/child1/}

- Child 2 {/page1/child2/}

and when you click on 'Page 1' in menu, you'll go straight to '/page1/child1/'.

For pages that you want to automatically direct to the first child, I would make them use a template that has this in it's code:

<?php if($page->numChildren) $session->redirect($page->child()->url);

And then, when you add another child, the internal pointer will redirect there.

If you add a new child page, and they aren't sorted by date added (descending) then the newly added page isn't likely to be the first child. If no default sort is selected, then it'll add it as the last child. So if you wanted to redirect to last page (rather than the first) then you'd want to do this:

<?php if($page->numChildren) $session->redirect($page->child("sort=-sort")->url);

By the way "sort" is just a name representing the order that pages have been dragged/dropped to. That's the default value if a page doesn't have another field selected as it's default sort field. The minus sign "-" in front of it represents descending sort. Without the minus sign, it would be ascending. Since you want to select the last page, that's why it's "-sort" rather than "sort".

Or if you wanted to make it select the most recent page added by date:

<?php if($page->numChildren) $session->redirect($page->child("sort=-created")->url);

The above is also descending since most recent added would be the highest date.

  • Like 7

Share this post


Link to post
Share on other sites

Hi Ryan,

I wonder if this technique may have any negative effect on search engines as it doesn't return a 301 that can be understood by the bots? What is your opinion/experience?

Best, Christoph

Share this post


Link to post
Share on other sites

Hi totoff,

It does set header 301 if you use Session::redirect by default.

Here's the method from the Session class:

<?php
	public function ___redirect($url, $http301 = true) {

		// if there are notices, then queue them so that they aren't lost
		$notices = $this->fuel('notices'); 
		if(count($notices)) foreach($notices as $notice) {
			$this->queueNotice($notice->text, $notice instanceof NoticeError ? 'error' : 'message', $notice->flags); 
		}

		// perform the redirect
		if($http301) header("HTTP/1.1 301 Moved Permanently");
		header("Location: $url");
		header("Connection: close"); 
		exit(0);
	}
  • Like 2

Share this post


Link to post
Share on other sites

hi wanze,

thanks pretty much for your reply. as i'm a beginner with php and in particular with object orientated programming could you give me a hint how to implement this? do i have to "hack" the core (i.e. amend the session class)?

best, christoph

EDIT: read twice through your reply and think i got it on the second try ;-) pw is setting 301 header by default, right? no need to edit anything.

  • Like 1

Share this post


Link to post
Share on other sites

Ryan. Thank you so very much for

if($page->numChildren) $session->redirect($page->child()->url);

here.

Totally rusty from far too long away from PW/PHP coding I was staring into space trying to work out how to do this. Until, that is, I searched for redirect page and your post came up... 1,000 thanks.

Share this post


Link to post
Share on other sites

Hi,

What's the difference between 

$page->child

 and 

$page->child()

and when I should use which one?

I know, noob question... but I had a problem with other usages not just at $page... :/

Share this post


Link to post
Share on other sites

There's really no difference. $page->child internally calls $page->child(). You really only need to use the function if you want to specify additional selectors like this:

$page->child("template=basic-page"); // First child matching this selector
  • Like 1

Share this post


Link to post
Share on other sites

My approach is to create page checkbox field named "redirects_to_first_child" and then execute redirect if this is true:

<?php if($page->numChildren && $page->redirects_to_first_child) $session->redirect($page->child()->url); ?>

This way I have full control over redirects via PW.

Also absolutely love the fact it does 301 redirect.

Share this post


Link to post
Share on other sites

I can't get this method to work on a multilingual site

On my default English site, it works fine.

/news/ 

redirects to its first child, which is

/news/2016/

but when I am on the French version

/fr/news/

redirects to a blank page.

Is it just me or anyone experience the same issue?

Thx

Rudy

Share this post


Link to post
Share on other sites

Hi @Rudy,

It's working for me here on a ML site.

Is it actually redirecting to a blank page, or not redirecting at all and just showing no content?

Is $page->child()->url returning the correct url to the first child?

Share this post


Link to post
Share on other sites

Bit of a longshot, but any chance the 2016 page is not activated for "fr" ? 

I get the same result as you if I uncheck the "active" checkbox on the settings tab.

  • Like 2

Share this post


Link to post
Share on other sites
On 3/1/2013 at 0:53 PM, Wanze said:

Hi totoff,

It does set header 301 if you use Session::redirect by default.

Here's the method from the Session class:


<?php
	public function ___redirect($url, $http301 = true) {

		// if there are notices, then queue them so that they aren't lost
		$notices = $this->fuel('notices'); 
		if(count($notices)) foreach($notices as $notice) {
			$this->queueNotice($notice->text, $notice instanceof NoticeError ? 'error' : 'message', $notice->flags); 
		}

		// perform the redirect
		if($http301) header("HTTP/1.1 301 Moved Permanently");
		header("Location: $url");
		header("Connection: close"); 
		exit(0);
	}

Using javascript works for me. Include following code in template file:

<?php
//If portfolio page make first child the current page
$portfoliopage = $pages->get(1019);
$posts = $pages->find("parent=$portfoliopage, sort=title");
if($page == $portfoliopage):
    $url = $posts->first()->url;
    ?>    
    <script type="text/jscript">
        location.replace("<?= $url ?>");
    </script>
    <?php    
endif;
?>

You can sort the posts array any way you like. For the latest addition use "sort=-sort"

Success!

Share this post


Link to post
Share on other sites

HI folks, hope this looks better.

Using javascript works for me. Include following code in template file:

<?php
//If portfolio page make first child the current page
$portfoliopage = $pages->get(1019);
$posts = $pages->find("parent=$portfoliopage, sort=title");
if($page == $portfoliopage):
    $url = $posts->first()->url;
    ?>    
    <script type="text/jscript">
        location.replace("<?= $url ?>");
    </script>
    <?php    
endif;
?>

You can sort the posts array any way you like. For the latest addition use "sort=-sort"

Success!

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