This document explains how the Red Rock Canyon trail system works behind the scenes. It covers how the data is stored, how URLs are turned into real pages, how the map is drawn, and how the entire process works without a database. Even if you're new to PHP or web routing, this guide walks through every part of the setup in an easy-to-follow way.
Instead of using MySQL, the site uses a simple PHP array to store all trail information. Think of this file as a small built-in database made from plain text. Each trail has a unique “slug”—a short name used in the URL—and the slug is the key to its data.
// trails-data.php
$trails = [
"turtlehead-peak" => [
"title" => "Turtlehead Peak",
"intro" => "A steep summit hike with panoramic views over the Las Vegas Basin.",
"distance" => 4.8,
"difficulty" => "Hard",
"gpx" => "/gpx/turtlehead.gpx",
"kml" => "/kml/turtlehead.kml",
"images" => ["/images/turtlehead-1.jpg"]
],
"ash-spring" => [
"title" => "Ash Spring",
"intro" => "Easy canyon walk ending at a lush spring.",
"distance" => 3.1,
"difficulty" => "Easy",
"gpx" => "/gpx/ash-spring.gpx",
"kml" => "/kml/ash-spring.kml",
"images" => ["/images/ash-1.jpg"]
]
];
The slug (example: turtlehead-peak) becomes the page URL:
https://redrockcanyonnca.com/turtlehead-peak
By using a slug as a key, the rest of the system instantly knows which trail to load. It keeps things simple, easy to modify, and avoids the overhead of a database.
Even though the site shows individual pages for each trail, they are all generated by
a single PHP file: trails.php.
This file reads the trail name from the URL (the slug), finds the matching entry in
trails-data.php, and builds the page on the fly.
// Get slug from URL
$slug = $_GET['slug'] ?? null;
// Load all trail data
include 'data/trails-data.php';
// Pull this specific trail from the array
$trail = $trails[$slug] ?? null;
If the slug exists, the system generates a full page: the map, pictures, GPX/KML downloads, difficulty rating, and intro text. If the slug is missing or invalid, the system shows a 404 error.
Result: The site has fully server-rendered, SEO-friendly pages without creating dozens of individual files.
/turtlehead-peak is internally treated as
trails.php?slug=turtlehead-peak.
The trails-index.php page provides a complete directory of all trails.
It is generated server-side for SEO, then enhanced with JavaScript to make browsing easier.
The directory includes:
Every trail is printed into the HTML so search engines can index the content. Once the page loads, JavaScript applies the sorting and filtering without refreshing the page.
<li data-title="turtlehead peak" data-difficulty="Hard" data-distance="4.8">
<h2>Turtlehead Peak</h2>
<p>4.8 miles • Hard</p>
</li>
The user sees a fast, interactive grid — while the underlying page remains SEO-safe.
Normally, PHP pages use query strings like this:
/trails.php?slug=turtlehead-peak
But these URLs are not ideal for search engines or real users.
Apache's .htaccess file transforms them into clean, modern URLs:
/turtlehead-peak
The rewrite rules check whether the URL matches a real file or folder.
If not, Apache passes the slug to trails.php.
RewriteEngine On
RewriteBase /
# If the request IS a real file or folder, stop rewriting.
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Otherwise, treat the URL as a trail slug.
RewriteRule ^([A-Za-z0-9\-]+)/?$ trails.php?slug=$1 [L,QSA]
This is the core of the SSR routing system. It mirrors how modern frameworks like Next.js or Laravel handle dynamic routes — but in a lightweight, custom-built form.
When someone visits:
/turtlehead-peak
trails.php?slug=turtlehead-peak.
trails.php reads the slug and loads the matching trail.The result is a light, efficient, future-ready trail system that behaves like a modern framework while remaining extremely simple under the hood.