6

I have two php files in the same directory posts.php and postdetails.php. The posts.php page lists all posts and postdetails.php displays the post when the postid is set like: postdetails.php?id=3

I want to make the posts and postdetails pages accessible without the .php and also add a trailing forward slash like:

instead of www.domain.com/posts.php

I'd have:

www.domain.com/posts/

I used this:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]

and now I can access posts.php the way I want, as in: www.domain.com/posts/

but now all the posts show links as www.domain.com/posts/postdetails.php?id=NUMBER

The thing is I'd like them to also like they are in the posts subdirectory but I can't seem to make it work.

I also want to change the id to slug

So that I'd have something like postdetails.php?slug=this-is-a-post and have it proprerly rerouted to www.domain.com/posts/this-is-a-post/

and I'm using this function to create my slugs.

function createSlug($str)
{
    if($str !== mb_convert_encoding( mb_convert_encoding($str, 'UTF-32', 'UTF-8'), 'UTF-8', 'UTF-32') )
        $str = mb_convert_encoding($str, 'UTF-8', mb_detect_encoding($str));
    $str = htmlentities($str, ENT_NOQUOTES, 'UTF-8');
    $str = preg_replace('`&([a-z]{1,2})(acute|uml|circ|grave|ring|cedil|slash|tilde|caron|lig);`i', '\\1', $str);
    $str = html_entity_decode($str, ENT_NOQUOTES, 'UTF-8');
    $str = preg_replace(array('`[^a-z0-9]`i','`[-]+`'), '-', $str);
    $str = strtolower( trim($str, '-') );
    return $str;
}

Any help please?

5
  • Here you might find something that helps smashingmagazine.com/2011/11/02/introduction-to-url-rewriting Commented May 4, 2014 at 23:40
  • This question is a bit of a muddle: the first half tells us that you've succeeded in doing some rewriting of requests. Well done. The second half then says you'd like to change links inside the generated HTML to point to these pretty URLs, but are having some unspecified problem with code you don't show us. At the end, you show a convoluted function for creating slugs which appears to be unrelated to either of the above problems. Bottom line: break down your problem, and tackle one part at a time. Commented May 4, 2014 at 23:57
  • The key thing I like to remind people of is that RewriteRules don't make ugly URLs pretty, they make pretty URLs ugly: you put a pretty URL in some HTML, the user clicks it, and Apache has to work out what ugly URL it's equivalent to. You can also make RewriteRules to redirect all variants of a URL to the "prettiest" one that currently works, but that's just a tidying up step, as the ugly URLs should never be published anyway if you've done it right. Commented May 5, 2014 at 0:03
  • @IMSoP yes, I know it is kind of a muddle. What I want to accomplish in all simpleness: 1. Have trailing slashes www.domain.com/posts/ 2. Have postdetails URLs become www.domain.com/posts/slug/ Important to note: both of the files posts.php and postdetails.php are in the same directory Commented May 5, 2014 at 1:49
  • Those are still just aims, not separate tasks. Bluntly, you cannot just "have a URL", you create it in some PHP, and, separately, you read it in some Apache configuration. You don't need to think about RewriteRules while you're creating HTML links with PHP - just know that, at some stage, you'll fix those links to load correctly; and vice versa, while making sure www.example.com/posts/foo/ loads the correct content, you don't need to think about how you will generate HTML that includes that link. Commented May 5, 2014 at 3:06

2 Answers 2

1

Create a directory posts with an index-file (present a list of posts, link to the pretty url) and this .htaccess:

RewriteCond %{REQUEST_URI} ^/posts/[^/]+/.*$
RewriteRule ^/posts/([^/]+)/$ postdetails.php?slug=$1 [QSA,L]

The pretty url

in this pattern:
http://www.example.com/posts/slug/

e.g.:
http://www.example.com/posts/keywords-are-here/

In the file postdetails.php you can evaluate the param $_GET['slug'].

Sign up to request clarification or add additional context in comments.

1 Comment

then just use a database to translate the slug back in the id or be sure to make the slug unique for all posts and use it to select the key. I've changed the answer to fit your needs
0

guessing from your problem, you could save your slug in your database upon creation, and use that one to identify the post also (most likely always will be unique, and if not use something as a date to go with it or just add the id to the end of it?). in your posts.php file then you begin with

if(isset($_GET['id'])) { //your post identifier, if this is set, show a post

  include("postdetails.php");

} else {

  //your posts code

}

on your index you then include the page if it is being called:

if(isset($_GET['p'])) {
  include($_GET['p'] . '.php'); //include the page you want, it is a seperate php page
}

and for your htaccess, you use something like this (code based upon something i use myself), where $p is the page you are on (to make it more website friendly, in your case this would be posts, or any other page) and the id is the next variable. if you use this however, all pages you create must use these two variables, so you need to rename any other scripts to use these variables. more can be added in similar fashion of course.

RewriteEngine On
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ index.php?p=$1&id=$2&actie=$3
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ index.php?p=$1&id=$2
RewriteRule ^([^/\.]+)/?$ index.php?p=$1

this may be not the most elegant way to do it though, more experienced users should answer also.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.