SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Member
    Join Date
    Apr 2011
    Posts
    7
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Unhappy Using mod_rewrite to make dynamic url "friendly"

    Hello all,

    I have never used mod_rewrite before but I have been advised by a marketing company my workplace uses tthat I need to rewrite my urls which appear as so:

    mywebsite/insurance-news/news.php?id=800464237&title=building_stocks_plummet

    into something more like:

    mywebsite/insurance-news/id/800464237/title/building_stocks_plummet/

    or

    mywebsite/insurance-news/id/800464237/title/building_stocks_plummet.html

    I have been trying for over 9 hours now to figure this out and have followed all the tutorials I can find with no luck, mod_rewrite is functional on my server as I created a test redirect as exlpained on one of the tutorials and it worked perfectly so I am not sure what I am doing wrong.

    This is the link that brings the page up which creates the "non-friendly" urls I am trying to re-write

    <a href="news.php?id=<?php echo $row_BusinessInsuranceNews['newsArticleID']; ?>&title=<?php echo str_replace(array(' ', ' '), '_', preg_replace('/[^a-zA-Z0-9 s]/', '',$row_BusinessInsuranceNews['htmlTitle'])); ?>">more</a>

    However, after numerous attempts at different rules when I click on it all I get is my dynamic URL:

    mywebsite/insurance-news/news.php?id=800464237&title=building_stocks_plummet

    These are the rules I have tried so far: Note: my .htaccess file is located in the correct directory and is headed up with:
    Options +FollowSymlinks
    RewriteEngine On

    RewriteRule ^news/?([0-9]+)/([a-zA-Z_])/$ /news.php?id=$1&title=$2 [L]

    RewriteRule ^news/([^/]+)/([^/]+)/?$ /news.php?id=$1&title=$2&size=$3 [L]


    RewriteRule ^news/(.*)/(.*)/$ /insurance-news/news.php?id=$1&title=$2

    RewriteRule news/id/(.*)/title/(.*)/ news.php?id=$1&title=$2
    RewriteRule news/id/(.*)/title/(.*) news.php?id=$1&title=$2

    I have tried all of the above and many variations in between - Can anyone help me out? Any advice would be greatly appreciated

  2. #2
    SitePoint Member
    Join Date
    Apr 2011
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    generally friendly urls work with single "access point", like index.php. from that entry point you dispatch the request accordingly.

    This may help in routing all the requests to a single script (index.php). from there you can parse the request and route it (exploding the request url with "/" is a good start).

    Code:
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteBase /test/
    
        #Removes access to the system folder by users.
        #Additionally this will allow you to create a System.php controller,
        #previously this would not have been possible.
        #'system' can be replaced if you have renamed your system folder.
        RewriteCond %{REQUEST_URI} ^system.*
        RewriteRule ^(.*)$ /index.php?/$1 [L]
        
        #When your application folder isn't in the system folder
        #This snippet prevents user access to the application folder
        #Submitted by: Fabdrol
        #Rename 'application' to your applications folder name.
        RewriteCond %{REQUEST_URI} ^application.*
        RewriteRule ^(.*)$ /index.php?/$1 [L]
    
        #Checks to see if the user is attempting to access a valid file,
        #such as an image or css document, if this isn't true it sends the
        #request to index.php
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)$ index.php?/$1 [L]
    </IfModule>
    
    <IfModule !mod_rewrite.c>
        # If we don't have mod_rewrite installed, all 404's
        # can be sent to index.php, and everything works as normal.
        # Submitted by: ElliotHaughin
    
        ErrorDocument 404 /index.php
    </IfModule>

  3. #3
    SitePoint Wizard cranial-bore's Avatar
    Join Date
    Jan 2002
    Location
    Australia
    Posts
    2,634
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Mod rewrite translates a requested URL to another. It does not modify the URL in the address bar. So if the links your PHP is producing looks like mywebsite/insurance-news/news.php?id=800464237&title=building_stocks_plummet then mod rewrite is not going to change those links, or redirect the user if that's in their address bar.

    What it can do is make a request to news/building-stocks-plummet/800464237/ actually serve news.php?id=800464237&title=building-stocks-plummet

    Ideally you'd avoid having the long numeric ID in the URL (800464237). But you can only get rid of it, if you can map the title string to a unique news item. This will be more work, as you have to store a unique URL slug with each article, so use in place of an ID.

    Assuming you don't go that far I'm assuming the news.php script does not need to receive title in the query string? The ID is enough to get the rest of the data from the database?

    In which case this might work.

    Code:
    RewriteRule ^news/([a-zA-Z0-9\.\_\-]+)/([0-9]+)/?$ news.php?id=$2
    Then
    news/my-awesome-title/3501

    will request
    news.php?id=3501

    You need to change the links you output to be in the new form.
    As I said Mod rewrite won't change the hyperlinks you output. Only how those URLs are handled.

    By the way, did the marketing company mention that if you just change a lot of your URLs, any page rank or search engine position the old pages (URLs) had will be largely wasted, and the new pages could appear as duplicate content?
    You'll need to setup a 301 redirect from the old to the new URLs to avoid this.
    mikehealy.com.au
    diigital.com art, design . Latest WorkSaturday Morning

  4. #4
    SitePoint Member thebuddy's Avatar
    Join Date
    Apr 2011
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Try this one

    RewriteRule ^insurance\-news/id/([0-9]+)/title/([a-zA-Z_])\.html$ news.php?id=$1&title=$2

    <snip/>
    Last edited by Mittineague; Apr 4, 2011 at 17:22. Reason: Please wait until you get your signature for your links.

  5. #5
    SitePoint Member
    Join Date
    Apr 2011
    Posts
    7
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Cranial Bore thanks so much for explaining that the link shouldn't change if i don't change the URL I am calling - after all the tutorials I read I never actually understood it because they all talk about changing the way a user sees a url. However it raises another query for me - when I am calling the newly written link how do I take out spaces and special characters like I do when I call the link now:

    <a href="news.php?id=<?php echo $row_BusinessInsuranceNews['newsArticleID']; ?>&title=<?php echo str_replace(array(' ', ' '), '_', preg_replace('/[^a-zA-Z0-9 s]/', '',$row_BusinessInsuranceNews['htmlTitle'])); ?>">more</a>

    If this is what I call?

    <a href="news/building-stocks-plummet/800464237/">more</a>

    I am sorry for being such a dodo about this concept!

    P.s Thanks for the additional not about the 301's I haven't gone live with the php news section of my site yet so there are no current URLs so I don't think I'll need any 301's I am just in testing at the moment I have to go live in a week though and this is one of the last jobs I have to get done first.

  6. #6
    SitePoint Member
    Join Date
    Apr 2011
    Posts
    7
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    also - if my data is dynamic and constantly changing with new news items - I won't even be able to call that url will I - as I won't know what it is?

  7. #7
    SitePoint Wizard cranial-bore's Avatar
    Join Date
    Jan 2002
    Location
    Australia
    Posts
    2,634
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    /**
    * Create URL safe title
    * @param string $title
    * @return string
    */
    function title_slug($title) {
       
    $slug strtolower(trim($title));
       
    $slug preg_replace('/ +/''-'$slug);
       
    $slug preg_replace('/[^a-z0-9\.\,\_\-]/'''$slug);

       return 
    $slug;

    Pass in your full text titles to that function. It will convert spaces to dashes, and then remove everything except for alpha numeric characters and . , _ -

    This will be much tidier than doing the filtering inline.

    I'd go a step further and write a function to return the HTML hyperlink from the link data. By doing this you can change the format of the link at any time, and the flow of your code will be easier to understand.

    PHP Code:
    /**
    * Build the href value for news links
    * @param string $id
    * @param string $title full unfiltered HTML title
    * @return string
    */
    function news_link($id$title) {
       
    $slug title_slug($title);
       return 
    "news/$slug/$id/";

    To use:
    PHP Code:
    $href news_link($row_BusinessInsuranceNews['newsArticleID'], $row_BusinessInsuranceNews['htmlTitle']);
    echo 
    "<a href='$href'>more</a>"
    This would output a link that looks like this:
    Code:
    news/building-stocks-plummet/800464237/
    news.php only needs to get the last segment (id). It doesn't care what the only-the-fly URL slug was.

    Make sense?
    mikehealy.com.au
    diigital.com art, design . Latest WorkSaturday Morning

  8. #8
    SitePoint Member
    Join Date
    Apr 2011
    Posts
    7
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Oh that's an excellent way of doing it! I'll implement it and see how I go. Thanks so much for getting back to me so quickly!

  9. #9
    SitePoint Member
    Join Date
    Apr 2011
    Posts
    7
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi again Cranial Bore

    You are a genius! The whole thing worked perfectly, I just had to make the comma not allowed in the $slug as I actually had a title with a comma in it first up and it wouldn't match as the mod_rewrite rule didn't allow them.

    The only problem I have now is that I have to make all my links on news.php absolute rather than relative as they won't seem to work relatively anymore but that's ok it's just a one off page.

    Thanks so much for all your help!!!

  10. #10
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,095
    Mentioned
    153 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by nicemanda View Post
    The only problem I have now is that I have to make all my links on news.php absolute rather than relative as they won't seem to work relatively anymore but that's ok it's just a one off page.
    You can also use <base> in the head of your HTML.

    Code:
    <base href="/">
    That way the browsers will know that they are actually in the root directory of your site, and not in the "fake" news directory.

    Also, to add to cranial-bore's excellent description of how things work, I also make a point of letting PHP check if the URL a user entered is correct.
    For example if you have a news article, people link to it, and than you change the title, the old links will be "incorrect" (the title will be incorrect), but still work. Search engines might think it's duplicate content, because you have the exact same content on two different URLs.

    Assuming you already have the data, it would be something like

    PHP Code:
    if (isset($_GET['title']) && $_GET['title'] !== title_slug($row_BusinessInsuranceNews['htmlTitle']))
    {
       
    header('Location http://'.$_SERVER['HTTP_HOST'].'/'.news_link($row_BusinessInsuranceNews['newsArticleID'], $row_BusinessInsuranceNews['htmlTitle']), true301);

    So for example if you have an article named "Building stocks plummet" with a URL news/building-stocks-plummet/800464237/ and then change the title to "Building stocks won't stop plummeting" with a URL news/building-stocks-wont-stop-plummeting/800464237/ and people request the old URL, they will be 301 redirected to the new one.
    Rémon - Hosting Advisor

    SitePoint forums will switch to Discourse soon! Make sure you're ready for it!

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy


Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •