0

im trying to write a script , that can rewrites urls in slug way such as this :

http://www.mysite.com/mystorytitle/

and i did this in my codes :

 RewriteRule ^(.*)\/$  app=News&file=article&title=$1  [L] 

and in my php codes, i created a slug out of story's title as :

$slug_title = mysql_real_escape_string($mtitle);
$show= "<a href=\"$slug_title/\">$mtitle</a>";

now everything is fine unless when i click on slugged link , it goes to the page but without any style and javascripts and images.

im sure that the problem is because of path for css files and ... which is been changed a level

as i'm in this path : http://www.mysite.com/ایمیل/

so if the page requiring css file as this :

<link rel="StyleSheet" href="includes/NAV.css" type="text/css" />

one level changed and to do this worked , i should come back a level as :

<link rel="StyleSheet" href="../includes/NAV.css" type="text/css" />

i guess , this is concidered as a folder not a rewrited path

but im sure there should be another way to make this script work without changing all paths

thanks in advance

Mac Taylor
  • 5,020
  • 14
  • 50
  • 73
  • Incidentally, `mysql_real_escape_string` is the wrong escape for putting text into HTML. It's only for MySQL queries and won't protect you from HTML-injection (XSS). You should be using `htmlspecialchars` instead, for `$mtitle`. Ideally you should also be using `urlencode` for `$slugtitle`, so that it works as a plain old URI as well as an IRI. – bobince Feb 26 '10 at 10:59
  • on what basis u r telling that urlencode is far better than mysql_real_escape_string , BTW when using urlencode it would add " + " to the title – Mac Taylor Feb 26 '10 at 11:25

4 Answers4

2

As you already wrote, this will happen because the browser thinks you are in a different directory named after your slug.

You will have to do something to the CSS URLs, either reference them relatively ../includes/ as you already do, or use absolute references /includes/NAV.css (the domain part being optional).

If this is a PHP project, I would create a central settings file containing the web root:

define("SITE_WEBROOT", "http://www.domain.com");

and reference all resources relative to that setting:

<link rel="stylesheet" type="text/css" 
      href="<?php echo SITE_WEBROOT; ?>/includes/NAV.css">
Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • that's what I do, I only shorted in to `=url?>` :D – casraf Feb 26 '10 at 10:23
  • thanks , all my attempt is not to change that much , if i want to follow ur idea , i should change more than 20 resource( css,js,..) links , and i should do the same for my customers who are using my CMS, im looking for a solution that can distinguish slug path from a folder path , u know what im saying ?! – Mac Taylor Feb 26 '10 at 10:24
  • @Mac Taylor I understand what you're saying but it can't be done properly really. It's the *browser* that thinks it's in a different directory. You could build a rewrite rule that redirects all requests for `/slugname/includes/NAV.css` to `/includes/NAV.css` but that is bullshit. I think introducing a web root setting is the only way to go, *especially* if you have a CMS that you ship to customers. – Pekka Feb 26 '10 at 10:26
  • actualy i set that web root path in my cms and i can use it , but as i said , still lots of change should be done – Mac Taylor Feb 26 '10 at 10:29
  • You can use the base tag in the header (probably included in CMS). It will work in all cases. Look at my answer. – Sagi Feb 26 '10 at 10:29
  • I would not use the `base` tag, especially if it's a product that gets shipped to customers. It makes the templates/pages harder to maintain. – Pekka Feb 26 '10 at 10:37
  • @Mac Taylor why is there lots of change, isn't it just changing a few style sheet references? – Pekka Feb 26 '10 at 10:38
  • @Pekka its not only style sheets , lots of direct image links or even javascripts , .... my current question is how can i find web root url in php , not to let it to users to define it – Mac Taylor Feb 26 '10 at 11:27
  • @Mac Taylor check `phpinfo()` to determine the current web root, but what if your app is in a sub directory? You won't get around using a defined web root. – Pekka Feb 26 '10 at 12:18
  • @Pekka actually, getting the base directory of $_SERVER['SCRIPT_NAME'] works also if your app is in a sub directory. If not, I would use "\" instead. – Sagi Feb 26 '10 at 12:23
  • @Sagi true if you are in the base directory of your app. Still, I'm not fond of using the `base` tag, it provides a quick fix but tends to cause problems long term. – Pekka Feb 26 '10 at 12:31
1

You should prepend the base URL (most of the time forward slash, but not always).

You can get it as follows (general expression that will work even if your site resides in a directory):

$baseUrl = rtrim((string)dirname($_SERVER['SCRIPT_NAME']), '/\\') . '/';

And then you'll write:

<link rel="StyleSheet" href="<?php echo $baseUrl ?>includes/NAV.css" type="text/css" />

Another possibility is to use the base tag in head:

<base href="<?php echo $baseUrl ?>" />

This has the advantage of changing only one line in your code.

You can go furthur and make utility method to do this:

function baseUrl($url = '', array $query = null, $fragment = null)
{
    static $baseUrl = rtrim((string)dirname($_SERVER['SCRIPT_NAME']), '/\\') . '/';

    if ($query !== null) {
        $url .= '?' . http_build_query($query);
    }

    if ($fragment !== null) {
        $url .= '#' . (string)$fragment;
    }

    $url = $baseUrl . $url;
    $url = trim(str_replace('\\', '/', (string)$url));

    return $url;
}
Sagi
  • 8,009
  • 3
  • 26
  • 25
0

Just add a forward slash before all resource URIs ... like /static/image.png. That will make the browser request it from the root (ie. www.site.com/path)

aviraldg
  • 9,531
  • 6
  • 41
  • 56
0

You can also use the base tag in your head section, then all relative links, stylesheets and images will go from there. We usually do that. It's set automatically in all our projects based on request URL and FILE path of the index.php

For example:

douwe
  • 1,305
  • 10
  • 12