mod_rewrite messing up Header/Stylesheets

I am making an attempt at my first mod_rewrite and having troubles.

It works, BUT it also ignores (?) my Header, Footer and Stylesheets. :frowning:

Here is my code…

.htaccess


#PRETTY:		articles/postage-meters-can-save-you-money
#UGLY:			article.php?title=postage-meters-can-save-you-money

RewriteRule articles/([a-zA-Z0-9_-]+)$ article.php?title=$1

Here is part of my article.php file…


<body>
	<div id="wrapper" class="clearfix">
		<div id="inner">
			<!-- Include BODY HEADER -->
				<?php	require_once(ROOT . 'components/body_header.inc.php');	?>

			<!-- MIDDLE COLUMN -->
			<div id="middle_2col">
				<div class="box_Content">

					<!-- ARTICLE -->
					<div id="article">

And here is my config.inc.php file…


<?php
	define('ENVIRONMENT', 'development');
//	define('ENVIRONMENT', 'production');


	// File Root
	define('ROOT', ENVIRONMENT === 'development'
					? '/Users/user1/Documents/DEV/++htdocs/01_MyProject/'
					: '/var/www/vhosts/MyWebsite.com/httpdocs/');

	// Web Server Root
	define('WEB_ROOT', ENVIRONMENT === 'development'
					? 'http://localhost/01_MyProject/'
					: 'http://www.MyWebsite.com/');

	// Secure Web Server Root
	define('SECURE_WEB_ROOT', ENVIRONMENT === 'development'
					? 'http://localhost/01_MyProject/'
					: 'https://www.MyWebsite.com/');
?>

What did I do wrong?

Debbie

The rewrite rule wouldn’t affect any of that code. What’s the problem you’re having?

If your stylesheet isn’t loading, it’s probably because you used a relative path, and now the browser is requesting it relative to the articles/ directory of your URL where the “ugly” URL used to be in the root of the domain. Change to using a root-relative URL (/stylesheet.css) or absolute URL (http://www.example.com/stylesheet.css) in the <link> tag.

DD,

What you did wrong is to change directory levels via mod_rewrite. It’s not wrong, just the effect caused by not letting the browser know it’s in a different directory level than it requested. As I discuss in my tutorial Article, you have two options: Use absolute links or use the HTML <base> command (example provided in the article - look for topic “Relative Links Are Missing!”).

Regards,

DK

But if you look in the code I posted above, you’ll see I was using an absolute path.


<!-- Include BODY HEADER -->
 <?php   require_once(ROOT . 'components/body_header.inc.php'); ?>

I’m not sure what the mod_rewrite did to this statement above, but it shouldn’t have changed my constant ROOT, right?

I’ve been stuck on this all week and am soooo frustrated (and behind schedule)?!

Thanks,

Debbie

P.S. Dan, my page runs but I just get an HTML page with no Styles of (Styled) Header and Footer.

Debbie,

That PHP code is still working exactly the same as it did before the rewrite rule.

The problem is with your HTML, not your PHP code.

View the source of your page in your browser, the contents of body_header.inc.php are there.

You have, in that header file, a <link> tag pointing to your stylesheet.

That <link> tag’s href is not an absolute path/URL.

It no longer points to the right location because your URL now reflects a directory named /articles/ and your stylesheet is not in the same location relative to that.

So while none of your code changed, your stylesheet URL became incorrect because of your new URL scheme. That’s what you need to fix.

If it says something like

<link rel="stylesheet" href="styles.css" />

the browser is going to request http://www.yoursite.com/articles/styles.css, which isn’t where the stylesheet is.

If it says something like

<link rel="stylesheet" href="css/styles.css" />

the browser is going to request http://www.yoursite.com/articles/css/styles.css, which isn’t where the stylesheet is.

You need to change the path to be root-relative

<link rel="stylesheet" href="/styles.css" />

or a full absolute URL

<link rel="stylesheet" href="http://www.example.com/styles.css" />

which will point to http://www.yoursite.com/styles.css no matter what the current page URL is.

Dan,

Okay, at least I think we identified the correct problem!

Now I’m equally frustrated that I can’t get this working because now I have a dumb PHP issue?! :headbang:

I am trying this as it has served me well in other contexts…


<?php
	echo '<link type="text/css" rel="stylesheet" href="' 
	. ROOT 
	. 'css/dropdown.css" />';
?>

Where…


<?php
	define('ENVIRONMENT', 'development');
//	define('ENVIRONMENT', 'production');


	// File Root
	define('ROOT', ENVIRONMENT === 'development'
					? '/Users/user1/Documents/DEV/++htdocs/01_MyProject/'
					: '/var/www/vhosts/MyWebsite.com/httpdocs/');

	// Web Server Root
	define('WEB_ROOT', ENVIRONMENT === 'development'
					? 'http://localhost/01_MyProject/'
					: 'http://www.MyWebsite.com/');

	// Secure Web Server Root
	define('SECURE_WEB_ROOT', ENVIRONMENT === 'development'
					? 'http://localhost/01_MyProject/'
					: 'https://www.MyWebsite.com/');
?>

So what is wrong with my syntax, because I am getting:

Notice: Use of undefined constant ROOT - assumed ‘ROOT’

Debbie

Is there some way to actually see this wrong path so I could have problem-solved this myself?

Debbie

Not sure what’s wrong with your define statements (is that code before the code where you try to use the constants?).

But you would want to use WEB_ROOT or SECURE_WEB_ROOT in your <link> tag, not ROOT, because it’s a URL, not a filesystem path.

If you want to see the browser make the request, you can do so with the Firebug plugin for Firefox, or the Developer Tools in Chrome.

I tried this in my <head> section.

Is the issue we are trying to fix also affecting my “config/config.inc.php” file as well?

Debbie

Here is my <head> section…


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
	<!-- HTML Metadata -->
	<title></title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta name="description"
				content="">
	<meta name="keywords"
				content="">

	<!-- Page Stylesheets -->
	<link type="text/css" rel="stylesheet" href="css/main.css" />
	
<!-- NEW -->
	<?php echo '<link type="text/css" rel="stylesheet" href="' . WEB_ROOT . 'css/dropdown.css" />'; ?>
	
	<link type="text/css" rel="stylesheet" href="css/components.css" />
	<link type="text/css" rel="stylesheet" href="css/listing.css" />
</head>

Is the issue we are trying to fix also affecting my “config/config.inc.php” file as well?

Debbie

No. The rewrite rule does not change how any of your code works.

Are you including config.inc.php before this header file? The code you pasted does not answer the question.

I would forego the constants altogether and just use paths relative to the root of the domain.

    <link type="text/css" rel="stylesheet" href="/css/main.css" />
    <link type="text/css" rel="stylesheet" href="/css/dropdown.css" />
    <link type="text/css" rel="stylesheet" href="/css/components.css" />
    <link type="text/css" rel="stylesheet" href="/css/listing.css" />

Those <link>s will point to the same URLs no matter what the URL of the current page. You won’t need to define separate constants for http/https either.

The difference is the slash at the beginning of each URL. You can do the same with image tags and script tags.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head></head>

<body>
	<!-- Access Constants -->
	<?php	require_once('config/config.inc.php');	?>


Debbie

I don’t understand how this is related to the code before, which also had <head> tags. Where is this from? Is it before or after you include the header file? If you have this, then include the header file, the HTML for your page would not be valid… it’d have two <head> sections and two <html> tags, one set inside the <body> of the page.

OMG!

First, DD, without an R=301 flag in your redirection, you HAVE changed the perceived directory level to articles/, NOT your DocumentRoot!

Second, you are NOT using absolute links for your css (as Dan has told you) because all you need is

<link rel="stylesheet" href="[B][COLOR="Red"]/[/COLOR][/B]styles.css" />

Same treatment required for images, js, etc. BECAUSE the browser is requesting them from the articles/ directory, not from your DocumentRoot (which the http protocol accesses).

Regards,

DK

That was my way of saying I was being dumb and had my config file AFTER my <head> tags which have the problematic <link> in them.

Debbie

That would explain A LOT of the problems I have been having!!

So what is the exact syntax??

Current mod_rewrite


#PRETTY:		articles/postage-meters-can-save-you-money
#UGLY:			article.php?title=postage-meters-can-save-you-money

RewriteRule articles/([a-zA-Z0-9_-]+)$ article.php?title=$1

Possible new mod_rewrite???


#PRETTY:		articles/postage-meters-can-save-you-money
#UGLY:			article.php?title=postage-meters-can-save-you-money

RewriteRule articles/([a-zA-Z0-9_-]+)$ article.php?title=$1 [R=301]

Second, you are NOT using absolute links for your css (as Dan has told you) because all you need is

<link rel="stylesheet" href="[B][COLOR="Red"]/[/COLOR][/B]styles.css" />

Same treatment required for images, js, etc. BECAUSE the browser is requesting them from the articles/ directory, not from your DocumentRoot (which the http protocol accesses).

Regards,

DK

Well, I thought I fixed things - even with my retarded articles/ issue by doing this…

article.php


<!-- Page Stylesheets -->
<link type="text/css" rel="stylesheet" href="<?php echo WEB_ROOT; ?>css/main.css" />
<link type="text/css" rel="stylesheet" href="<?php echo WEB_ROOT; ?>css/dropdown.css" />
<link type="text/css" rel="stylesheet" href="<?php echo WEB_ROOT; ?>css/components.css" />
<link type="text/css" rel="stylesheet" href="<?php echo WEB_ROOT; ?>css/article.css" />

config.inc.php


<?php
	define('ENVIRONMENT', 'development');
//	define('ENVIRONMENT', 'production');

	// Web Server Root
	define('WEB_ROOT', ENVIRONMENT === 'development'
					? 'http://localhost/01_MyProject/'
					: 'http://www.MySite.com/');
?>

However I have discovered that the images in my articles are now not working because they have paths like:

h t t p: //localhost/01_MyProject/articles/<?php%20echo%20ROOT;%20?>images/some_image.jpg

So even with my WEB_ROOT, things won’t work. :frowning:

If you can clarify that R=301, maybe I can get my images working too?!

Thanks,

Debbie

He was just repeating what has already been said about why you had a problem. You do not want to change your rules. Adding [R=301] would turn the rewrite into a redirect and change the URL in the address bar from the “pretty URL” bad to the “ugly URL”.

But DKLynn said,

OMG!

First, DD, without an R=301 flag in your redirection, you HAVE changed the perceived directory level to articles/, NOT your DocumentRoot!

And I discovered after supper that was part of my problem.

So how do I get my mod_rewrite to “point” to the WEB ROOT (instead of “articles/”)?

I was able to fix the style sheet issue by doing…


	<!-- Page Stylesheets -->
	<link type="text/css" rel="stylesheet" href="<?php echo WEB_ROOT; ?>css/main.css" />

And I am trying to do this with the images in my articles, but so far the images aren’t working. (I think this is because I had nested php code but now I have another issue of phpMyAdmin not accepting single quotes which is a another major issue I have to resolve before I can try my new image code.

If I could have my mod_rewrite go from “pretty” to “ugly” URL and also point to my Web Root it would make life easier…

Hope you are following me?!

BTW, the reason I do NOT want to use relative links like I believe you suggested is because I am going between NetBeans which has a diffferent file structure than my Web Host. That is the whole reason I created the config file I posted above… Because I was having hellish problems with having thing either broken in development or production and being tired of having to change code between the two?!

Debbie

As an aside, you can set up a virtual server environment quite easily on your PC so that file paths are the same in both places. I just use MAMP with some simple settings on Mac, and there are PC equivalents, such as WAMP and XAMPP. It’s been a huge relief.

Yes, DK sometimes repeats things with CAPS and exclamations, but he didn’t say anything new. Relative URLs are resolved to absolute URLs by the browser relative to the URL of the current page. The browser doesn’t know a rewrite happened in the first place, it only knows the URL of the current page and the URLs of the stylesheets you told it to load.

If you want your pretty URLs then you have to adjust. You can’t change the rewrite rule to change that while keeping the new URLs. If you give up, you’re always free to go back to the ugly URLs.

I can’t fathom why your stylesheet URLs are coming out as you pasted… that’s what you’d get if you wrote something like <?php echo urlencode(“<?php echo WEB_ROOT; ?>”); ?>… but I’m sure you didn’t write that. It’s difficult to provide advice when looking at disjoint, partial snippets of out-of-context code and without knowing anything about the environment. Start doing some basic debugging, like <?php echo WEB_ROOT; ?> alone in the same file, fix whatever’s wrong so that you get that to print what you want it to print, then combine it with the rest of the HTML to print out the stylesheet URLs.