241 lines
3.4 KiB
Markdown
241 lines
3.4 KiB
Markdown
# SkinBase – Category Link Building (AUTHORITATIVE SPEC)
|
||
|
||
This document defines the **ONLY valid way** to build public category and artwork URLs in SkinBase.
|
||
Copilot AI Agent MUST follow this specification exactly.
|
||
|
||
---
|
||
|
||
## 🎯 Goal
|
||
|
||
- SEO-friendly URLs
|
||
- No numeric IDs in public routes
|
||
- Unlimited category depth
|
||
- Predictable and deterministic link building
|
||
- One canonical URL per resource
|
||
|
||
---
|
||
|
||
## 🚫 Forbidden Concepts
|
||
|
||
Copilot MUST NOT:
|
||
- expose numeric IDs in URLs
|
||
- use legacy paths (`/Photography/3`)
|
||
- infer hierarchy from URL text
|
||
- mix `content_type_id` and `parent_id`
|
||
- create alternative URL formats
|
||
- generate uppercase URLs
|
||
|
||
---
|
||
|
||
## 🧱 Data Model (Authoritative)
|
||
|
||
### content_types
|
||
- `id`
|
||
- `slug` → FIRST URL segment
|
||
|
||
Examples:
|
||
```
|
||
|
||
photography
|
||
wallpapers
|
||
skins
|
||
other
|
||
|
||
```
|
||
|
||
---
|
||
|
||
### categories
|
||
- `id`
|
||
- `content_type_id`
|
||
- `parent_id`
|
||
- `slug`
|
||
|
||
Rules:
|
||
- `parent_id = NULL` → root category
|
||
- `parent_id != NULL` → child category
|
||
- `parent_id` MUST reference `categories.id`
|
||
- `content_type_id` MUST reference `content_types.id`
|
||
|
||
---
|
||
|
||
## 🧭 URL Structure (MANDATORY)
|
||
|
||
### Category URLs
|
||
|
||
```
|
||
|
||
/{content_type.slug}/{category-path}
|
||
|
||
```
|
||
|
||
Where:
|
||
- `category-path` is built from category slugs in hierarchy order
|
||
|
||
Examples:
|
||
```
|
||
|
||
/photography
|
||
/photography/abstract
|
||
/photography/abstract/dark
|
||
/skins/media-players
|
||
/other/art
|
||
|
||
```
|
||
|
||
---
|
||
|
||
### Artwork URLs
|
||
|
||
```
|
||
|
||
/{content_type.slug}/{category-path}/{artwork.slug}
|
||
|
||
```
|
||
|
||
Examples:
|
||
```
|
||
|
||
/photography/abstract/dark/night-city
|
||
/skins/media-players/zoom-player-dark
|
||
|
||
```
|
||
|
||
Rules:
|
||
- Artwork MUST belong to the last category in the path
|
||
- Artwork slug is ALWAYS the final segment
|
||
|
||
---
|
||
|
||
## 🧠 Category Path Construction (STRICT RULE)
|
||
|
||
Category paths MUST be constructed by walking parents.
|
||
|
||
Algorithm (conceptual):
|
||
|
||
1. Start with current category
|
||
2. Collect its `slug`
|
||
3. Move to `parent`
|
||
4. Repeat until `parent_id = NULL`
|
||
5. Reverse collected slugs
|
||
6. Join with `/`
|
||
|
||
Example:
|
||
```
|
||
|
||
Photography
|
||
└── Abstract
|
||
└── Dark
|
||
|
||
```
|
||
|
||
Produces:
|
||
```
|
||
|
||
abstract/dark
|
||
|
||
```
|
||
|
||
Final URL:
|
||
```
|
||
|
||
/photography/abstract/dark
|
||
|
||
````
|
||
|
||
---
|
||
|
||
## 🧩 Laravel Helper Contract
|
||
|
||
Category model MUST expose:
|
||
```php
|
||
$category->full_slug_path
|
||
````
|
||
|
||
Which returns:
|
||
|
||
```
|
||
abstract/dark
|
||
```
|
||
|
||
Final URL generation:
|
||
|
||
```php
|
||
'/' . $category->contentType->slug . '/' . $category->full_slug_path
|
||
```
|
||
|
||
---
|
||
|
||
## 🧭 Breadcrumb Rules
|
||
|
||
Breadcrumbs MUST reflect hierarchy exactly:
|
||
|
||
Example:
|
||
|
||
```
|
||
Home → Photography → Abstract → Dark
|
||
```
|
||
|
||
Each breadcrumb link MUST use the same slug-based URL logic.
|
||
|
||
---
|
||
|
||
## 🔐 Canonical URL RULE (SEO)
|
||
|
||
Every category and artwork page MUST include:
|
||
|
||
```html
|
||
<link rel="canonical" href="https://skinbase.org/{full-slug-url}">
|
||
```
|
||
|
||
Canonical URL MUST be:
|
||
|
||
* lowercase
|
||
* slug-based
|
||
* without IDs
|
||
* without query parameters
|
||
|
||
---
|
||
|
||
## 🧨 Legacy URL Handling
|
||
|
||
Legacy URLs MUST be handled ONLY via **301 redirects**.
|
||
|
||
Examples:
|
||
|
||
```
|
||
/Photography/3
|
||
/Photography/Business/564
|
||
```
|
||
|
||
Redirect to:
|
||
|
||
```
|
||
/photography/business
|
||
```
|
||
|
||
Copilot MUST NOT generate new legacy URLs.
|
||
|
||
---
|
||
|
||
## ✅ Validation Rules
|
||
|
||
Copilot MUST ensure:
|
||
|
||
* all URLs are lowercase
|
||
* slugs are used exclusively
|
||
* depth is unlimited
|
||
* parent relationships are respected
|
||
* only ONE URL exists per resource
|
||
|
||
---
|
||
|
||
## 🏁 FINAL STATEMENT
|
||
|
||
This document is the **single source of truth** for SkinBase category link building.
|
||
|
||
If any instruction conflicts with older code, documentation, or assumptions,
|
||
THIS DOCUMENT WINS.
|
||
|
||
END OF SPEC
|