Jump to content
neildaemond

adding perma links to my site

Recommended Posts

before I add in one of those "FB,TWITTER,TUMBLR..etc" things to my blog, I was thinking of adding some sort of perma links functionality to my site so that If I ever re-organize the page structure from the the admin, the fact that the link changed wont matter.

I was thinking about doing something like this:

$name = $page->name
$template = $page->template

echo "<a href='http://www.neilpahl.com/perma-link?name={$name}&template={$template}'>perm-link to this page</a>";

then the permalink template would look something like this:

<?php

$findName = $sanitizer->name($_GET["name"]);
$findTemplate = $sanitizer->name($_GET["template"]);

$redirectLink = $pages->get('template={$findTemplate}, name={$findName})->url;

header("Location: {$redirectLink}");

?>

I haven't tried it yet, and its my first time to use GET variables (thank goodness for the $sanitize function). Is there a more common way of implementing perma-links? Is there anything wrong with the method I'm suggesting? (there MUST be something wrong with the syntax at least)

Share this post


Link to post
Share on other sites

You can use:

<?php

$findName = $sanitizer->name($_GET["name"]);
$findTemplate = $sanitizer->name($_GET["template"]);

$redirect =$pages->get('template='.$findTemplate.', name='.$findName)->url;

if($redirect) {
$session->redirect($redirect);
}

?>

Share this post


Link to post
Share on other sites

Why not just use in URL the page's id for identification or create special field with random token generated on first save?

Share this post


Link to post
Share on other sites

I would use page id also. Depending on your site structure, but name + template doesn't mean unique.

Share this post


Link to post
Share on other sites

Thanks Nico, i'm going to try that out~

Why not just use in URL the page's id for identification or create special field with random token generated on first save?

oh yeah, why didn't I think of that

Share this post


Link to post
Share on other sites

Are permalinks really necessary outside of a blog? I always thought the point of them was to provide a permanent link for stories that appear on the homepage and in date ordered paginated pages. Since the page they would appear on keeps changing with the number of entries, a permalink is necessary to establish a long term URL for the story. But it seems unnecessary outside of that environment. A page URL in PW is really no different than a permalink elsewhere (?). With a blog in PW, I would just use the entry's page URL as the permalink when needed in date ordered presentation.  My opinion is that it's good to build around a URL structure that you consider permanent. And when/if you need to change it, use 301 redirects.

Share this post


Link to post
Share on other sites

I totally agree with you Ryan, its best when you have a permanent URL structure. I followed this ideal when I created my "Cheatsheet" Section. All my cheat sheet pages were under their own folder, then there was a tree structure for the categories which could be 'tagged' via a page field within the cheat sheet.

However, the ability to easy move pages around in the admin section tempted me to categorize my Blog Categories solely by the path of the entry. This made me wonder what I was going to do if I sorted it by moving pages around in the admin. Doesn't $page->url provide the url path? If I changed the path of the page, then surely the url would change, right?

One reason I brought up the topic of perma links is that, to me, it seemed easy enough to implement given PW's api. Also, I was looking for a reason that using them would cause problems. I can foresee the situation where someone just copies and pastes the link 6from the address bar instead of using the "Share me" link (which uses the perma link) to share the page/entry. Another fail could be when posted to facebook or something, the link might just stay as a text link instead of showing the icon,title and description... I'll have to test.

I guess it boils down to a flaw with with my category tree method instead of just using tags. Tags allow the page to remain where you made it, while sorting your blogs by their file path will result in changed urls if you move it.

Generally, I think tags are good, but I just wanted to try something different (while utilizing the usability of PW's admin). I felt that perma-links would give me a one-time solution as opposed to creating redirects each time I move a page.

Share this post


Link to post
Share on other sites

There will be a way to do it, but I thought I'd just weigh in with the note that if you keep moving published content, you'll hurt your search engine rankings, especially if it's a page that's been indexed for a while.

The best thing to do is stick to a structure and not be tempted to move stuff about. That said, if you're only going to move a page once maybe, then a 301 is the best way to go as ryan says. You could even write a little module to edit your .htaccess file and have it append moved pages to the end whenever you move one theoretically, but that's a bit overkill as you shouldn't be moving that many pages that often anyway :D

Share this post


Link to post
Share on other sites

if you keep moving published content, you'll hurt your search engine rankings, especially if it's a page that's been indexed for a while.

very good point! Search engine rankings are always a good reason to do something different.

I have to confess that, knowing "perma links" are a kind of buzz word these days, I had a feeling those who have been in the business longer will have something to say about them. I'm glad to hear the response, thanks guys! From now on, I think I'll try keep my url structures put.

Share this post


Link to post
Share on other sites

One way to do categories is to have them as page fields. That way your urls would be something like this:

www.site.com/blog/name-of-the-article/

instead of:

www.site.com/blog/categoryname/name-of-the-article/

Not sure which way is better in your case, but I usually prefer the first one most. It is bad thing to change urls, but there might be some heavy restructuring if you change all your category names (something you should definitely avoid though). If you have first url schema, then you don't break any links and they are all pretty much "permalinks".

And doing this way you will use urlSegments to get pages like:

www.site.com/blog/categoryname/

or

www.site.com/blog/2011/

or

www.site.com/blog/2011/11/

etc..

Share this post


Link to post
Share on other sites

That's the way I'd suggest doing it too - much tidier :)

Share this post


Link to post
Share on other sites

One way to do categories is to have them as page fields.

That's how I did it in my cheat sheet section... but for sorting my blog topics, I was worried about changing the category page field of many pages.

My site is little so I feel a little bit guilty dragging this thread on (I really appreciate the feed back and have learned a few best practices along the way though). My main goal is for someone to easily see the topics which I have experience with, and that makes it important for me to categorize things nicely and maybe re categorize things as my experience evolves. I will rethink my categorizing strategy and post the results.

Share this post


Link to post
Share on other sites

If your post can belong only to one category and your categories are considered static, then I don't see anything wrong in your approach - it is probably little bit easier for editor. But if you have situation where categories may change, then I would use category as a field instead of having it as parent page.

Share this post


Link to post
Share on other sites
I have to confess that, knowing "perma links" are a kind of buzz word these days, I had a feeling those who have been in the business longer will have something to say about them. I'm glad to hear the response, thanks guys! From now on, I think I'll try keep my url structures put.

Permalinks are still a good idea in your case because you have reverse chronological blog pages displaying 3 entries per page. If someone wants to link to one of those, you want them to link to the entry's full URL (permalink) rather than the paginated entries. I was just trying to say that it'd be preferable for your permalink to be just ProcessWire's URL to the page, rather than some other system of URLs on top of that. If you need to go outside that, then you could have the same entry by itself living at two URLs in your site. To minimize SEO issues, you'd want to use an canonical meta tag to make it clear to Google what the actual permanent home of that entry is. Still, if possible, save yourself the trouble and use a structure that doesn't need to change regularly and I think you'll get better performance out of it.

Share this post


Link to post
Share on other sites

I've long been a fan of something I first encountered in Textpattern, the ability to visit

example.com/cooking/29/the-best-way-to-cook-leeks
example.com/cooking/29/the-best-way-to-cook-leek
example.com/cooking/29/the-best-cook-leeks
example.com/cooking/29/the-best-I-cant-type

and always simply see the page about cooking leeks. Effectively the URL beyond /29/ is getting ignored. For example this allows one to use example.com/cooking/29/ as a short, permanent link to a page while retaining the full URL for normal use (and healthy SEO).

Now Twitter self-shortens links <- insert debate if that's good here -> what I am trying to do is perhaps less important, but I like the idea of being able to refer to a page with an alternate, ultra-short, permanent URL.

To that end I used the code examples here (thank you) and came up with this:

if($page->id == 1232) // the id of a utility page with the URL /p/
{
$pageId = $sanitizer->selectorValue($input->urlSegment1);

$redirect = $pages->get('id='.$pageId)->url;

if($redirect) {
	if($page->viewable())
	{
		$session->redirect($redirect);
	}
}
}

The ->viewable() test is not really working, but that aside I can visit:

example.com/p/1190

and get instantly directed to the page with ID 1190 at it's normal, full URL. Useful :)

The problem is the viewable test. If someone tries to visit a page ID for a page not normally visible they are directed to Login, not ideal.

If anyone sees a neat way I can identify all pages that are suitable for display (e.g. the output of the navigation) and use that as a filter to test against so if the ID is not one of those pages I can 404, I'd be most grateful for ideas.

Share this post


Link to post
Share on other sites

In your example what would "example.com/deep-frying/29/the-best-way-to-deep-fry-leeks" would resolve to?

I've long been a fan of something I first encountered in Textpattern, the ability to visit

example.com/cooking/29/the-best-way-to-cook-leeks
example.com/cooking/29/the-best-way-to-cook-leek
example.com/cooking/29/the-best-cook-leeks
example.com/cooking/29/the-best-I-cant-type

and always simply see the page about cooking leeks. Effectively the URL beyond /29/ is getting ignored. For example this allows one to use example.com/cooking/29/ as a short, permanent link to a page while retaining the full URL for normal use (and healthy SEO).

Share this post


Link to post
Share on other sites

If you've got URL segments turned on for the template used by page /cooking/29/ then all the URLs you mentioned should load the page /cooking/29/ and whether you choose to do something with the URL segment is up to you.

In your case, I think that the viewable() check isn't working because you are checking $page->viewable(); rather than $redirect->viewable() ?

Your $page->viewable(); call will never come into play because $page is the page you are currently on, and PW will never serve a request for a $page that isn't viewable. So I'm thinking you could fix it just by changing $page to $redirect?

Here's another way to do it:

if($page->id == 1232) {
   $id = (int) $input->urlSegment1; 
   $redirect = $id ? $pages->find("id=$id")->first() : null; 
   if($redirect) $session->redirect($redirect->url);
}

The viewable() check isn't necessary above since PW's find() function doesn't return pages the user can't view.

Share this post


Link to post
Share on other sites

@SiNNut

In your example what would "example.com/deep-frying/29/the-best-way-to-deep-fry-leeks" would resolve to?

It would resolve to that URL, that is the default one stored in the db, the permalink, but if someone typo'd and visited

example.com/deep-frying/29/the-best-way-to-deep-fry-onion-family

then the system would be gentle and show the correct page, not a 404.

@Ryan

Wow, excellent, thanks yet again Ryan for the great example, I will go edit...

Share this post


Link to post
Share on other sites

Ryan, FYI keeping my code and changing $page->viewable() to $redirect->viewable() results in an error. But I swapped to your new code and that works perfectly as far as it goes but I think I need to do more because although visiting example.com/p/1190 pops me straight over to the full, correct URL for that page, visiting an ID that happens to be a page in the trash gives me a 404 (probably the correct outcome) but trying another ID at random resolved to

example . com /pw/repeaters/for-field-107/for-page-1188/

and I ended up at a login page (which I don't want people to stumble over).

I've moved the below over to a new topic as I hope it is one that may be of some general use (not only to me!).

This isn't an urgent thing, but not for the first time I have wondered how I would build/use a function that in pseudo code did:

if(section-is-part-of-nav) {
if(page-in-section-is-part-of-nav) {
	visible-pages-array[store-page]
}
}

...and left me able to test a page to see if it was in the visible-pages-array and hence one I want to do stuff with that the public is allowed to see.

Edited by alan

Share this post


Link to post
Share on other sites
but trying another ID at random resolved to

example . com /pw/repeaters/for-field-107/for-page-1188/

and I ended up at a login page (which I don't want people to stumble over).

Sorry Alan, I was incorrect about the automatic access checking in find(). I'll blame it on too many days (or drinks) at sea. :) Since an actual page ID was specified, there is no access checking because IDs are very specific. If you know so much about a page as to specify it's ID, then PW assumes you really must want it. So the find() would perform the same as get() in that case, which is what I forgot in my last code example. I think this may be more what you want:

if($page->id == 1232 && $id = (int) $input->urlSegment1) {
   $redirect = $pages->get("id=$id"); 
   if($redirect->id && $redirect->viewable()) {
       $session->redirect($redirect->url);
   } else {
       throw new Wire404Exception();
   }
}

Share this post


Link to post
Share on other sites

Ryan, that's a GOOD thing to hear, "...too many days (or drinks) at sea", there can't ever be too many of those ;)

No worries whatsoever and thank you for the new code and I understand about that degree of specificity meaning access checking is different, makes total sense.

I'll take your code and also one from Soma and see where I get :D Thanks again!

Share this post


Link to post
Share on other sites

@Ryan, thank you, apart from the 404 redirect, that new code worked a treat, I used a line from Soma in place of it and now it works perfectly. Thanks again!

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