Default to index.php when No Slug Present

I had this working but seem to have broken something?!

I have an “article” directory with an “article.php” and “index.php” within it.

“article.php” is a template file that takes a value in the query string and loads the appropriate Article from the database.

Inside “article.php” I have this code (high-level)…


	// ******************************
	// Attempt to Retrieve Article.	*
	// ******************************
	if (isset($_GET['slug']) && $_GET['slug']){
		// Slug found in URL.



	}else{
		// Slug Not found in URL.
		// This will never fire!!
		// Apache catches missing slug and re-routes to "articles/index.php"

	}//End of ATTEMPT TO RETRIEVE ARTICLE

?>
<!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">

and so on...

As you can see from my notes under ELSE, if a “slug” is not passed in the request to “article.php”, then Apache should kick in and re-direct to the “index.php” file (i.e. Listing of Articles) within the “article” directory.

In the last month I was playing around with my .htaccess file, and apparently deleted the line that made what I am describing happen.

I’m a real weenie when it comes to Apache and mod_rewrites, and am hoping this is a quick fix with some expert help?!

Thanks,

Debbie

Can you post what is in your .htaccess file right now so we can see what rules are being applied? As ideally you want the .htaccess file to perform the task correct?

This may be a good time for you to start learning and using a versioning system such as Git or SVN. It’s the ultimate undo. You’ll have a full log of every change you’ve ever made, and you can undo any one of those changes with just a couple clicks.

Those are words I live by. Of course, I learned the hard way too. Lost 3 weeks of work, never again!

Excellent Advice @Jeff_Mott; been using GIT since the beginning and has save myself and/or teams from blunders, bad decisions and electrical mayhem :slight_smile: GIT is not hard to learn there are many good articles on its’ use.

Here are the un-commented lines…


RewriteEngine on

# Rewrite only if the request is not pointing to a real file,
# such as add_comment.php or index.php
RewriteCond %{REQUEST_FILENAME} !-f

# Match any kind of slug; PHP will decide if it's valid or not
RewriteRule articles/(.+)$ articles/article.php?slug=$1


RewriteRule account/profile/([a-zA-Z0-9_.-]+)$ account/profile/$1/about-me

(That last line is probably screwed up and another topic on which I need help, but one thing at a time!!)

Debbie

Well, I sorta do that in NetBeans.

I make manual back-ups fairly regularly, and NetBeans has a “Local History”.

Problem is that apparently NetBeans doesn’t keep things over like 30 days, and I didn’t do a good job manually backing up my .htaccess since it never changed (until I changed it)?! :lol:

I would like to move into a real Change/Configuration Mgt System someday, but right now I just need to get my site up and running and making $$$!

Debbie

If GIT is what I recall, it is online and cloud-ish.

If so, NO WAY!!!

Some day my code will make me the next Bill Gates. Let the other lackies store their code for all to see or hack into. I’ll keep my pre-production code local. :cool:

Debbie

I was able to fix things using PHP, but I would still like help figuring out how to do the same thing using Apache.

Here is what I did in PHP…


<?php
	//Some code here...

	// ******************************
	// Attempt to Retrieve Article.	*
	// ******************************
	if (isset($_GET['slug']) && $_GET['slug']){
		// Slug found in URL.

		//Some more code here...

	}else{
		// Slug Not found in URL.
		// This will never fire!!
		// Apache catches missing slug and re-routes to "articles/index.php"

//NEW
		// Redirect to Display Outcome.
		header("Location: " . BASE_URL . "/articles/index.php");

		// End script.
		exit();

	}//End of ATTEMPT TO RETRIEVE ARTICLE

?>

Thanks,

Debbie

To fix this in Apache, you’ll need to do two things. First, add a flag to indicate that if any of the other rewrite rules match, then the rewrite process should stop after that rewrite. Then, at the very end, rewrite any other URL to index.php

RewriteEngine on

# Rewrite only if the request is not pointing to a real file,
# such as add_comment.php or index.php
RewriteCond %{REQUEST_FILENAME} !-f

# Match any kind of slug; PHP will decide if it's valid or not
RewriteRule articles/(.+)$ articles/article.php?slug=$1 [COLOR="#FF0000"][LAST][/COLOR]

RewriteRule account/profile/([a-zA-Z0-9_.-]+)$ account/profile/$1/about-me [COLOR="#FF0000"][LAST][/COLOR]

[COLOR="#FF0000"]RewriteRule ^(.*)$ index.php[/COLOR]

RewriteEngine on

# Rewrite only if the request is not pointing to a real file,
# such as add_comment.php or index.php
RewriteCond %{REQUEST_FILENAME} !-f
# Match any kind of slug; PHP will decide if it's valid or not
RewriteRule articles/(.+)$ articles/article.php?slug=$1

# Rewrite only if the request is not pointing to a real file,
# such as add_comment.php or index.php
RewriteCond %{REQUEST_FILENAME} !-f
# Match no slug
RewriteRule articles/? articles/index.php

# Rewrite only if the request is not pointing to a real file,
# such as add_comment.php or index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule account/profile/([a-zA-Z0-9_.-]+)$ account/profile/$1/about-me

** UPDATE ** Just saw that Jeff replied to your htaccess problem too. His is similar to mine, other than he caught the [LAST] part (I missed that), and he is redirecting to your root /index.php file and I am redirecting to one in the articles folder (not sure which is correct there).

I believe this will do what you want, also note I copied the RewriteCond to each Rule because RewriteCond only apply to the next RewriteRule.

GIT is another source control system. It differs from SVN in that it is a distributed system and not a central repository system (although it can be setup like a central repository system). You have full control of where your data is stored (with both SVN and GIT).

Both Git and SVN can be used locally.

Just thought I’d throw this out there… but you may find it simpler to use a front controller pattern. The idea is you rewrite all URLs to one PHP script that serves as the entry point, then that PHP script examines the URL to decide what actions to take.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ front-controller.php [QSA,L]
// front-controller.php

$uri = $_SERVER['REQUEST_URI'];
if ($uri == '') {
    require 'index.php';
} elseif ($uri == '/articles') {
    require 'article_list.php';
} elseif (preg_match('#/articles/([\\w\\-]+)#', $uri, $matches)) {
    $slug = $matches[1];
    require 'article_show.php';
} else {
    require '404.php';
}

We’ll save that for v3.0, but thanks!

Debbie

Should I always use RewriteCond ??

What is the % ??

Does this !-f mean “not a file” ??


# Rewrite only if the request is not pointing to a real file, such as article.php
RewriteCond %{REQUEST_FILENAME} !-f

# Match no slug
RewriteRule articles/? articles/index.php

What is the question mark??

Where should there be LAST in the code above?

Thanks,

Debbie

If you need a condition to apply to a rule, yes, you should have RewriteCond before each rule the condition applies to.

The % in this case denotes a variable supplied by apache ({REQUEST_FILENAME})

This was in your original .htaccess, but it simply means, that the rule following this condition should not be run, if a file with the name of the request exists (ex: if the user requested articles.php, the request shouldn’t run the rule, because that file should be executed instead of parsing a rule)

One or fewer matches of the proceeding character. In short, it says, if the request is for /articles or /articles/ redirect to serve up articles/index.php

After articles/index.php, example: articles/index.php [LAST]