# Product Updates Individual Post Pages Documentation

## Overview

Individual feature post pages provide detailed views of specific product update features. These pages are accessible via `/posts/{slug}` URLs and display full feature details with proper SEO, schema markup, and navigation.

## URL Structure

- **Pattern**: `/posts/{feature-slug}`
- **Example**: `/posts/meet-ordio-novi-ai-agent`
- **Slug Format**: lowercase, alphanumeric, hyphens, and underscores only
- **Source**: `read_more_link` field in `produkt_updates.json`

## Page Structure

### Data Source

Posts are dynamically generated from `v2/data/produkt_updates.json`. Each feature with a `read_more_link` field pointing to `/posts/{slug}` becomes an individual post page.

### Page Components

1. **Header**

   - Standard Ordio header (via `base/header.php`)
   - Navigation breadcrumbs

2. **Back Navigation**

   - Link back to parent month page
   - "Zurück zu {Month} Updates" button

3. **Hero Section**

   - Feature number badge (#1, #2, etc.)
   - Month badge
   - Feature title (H1)
   - Published date

4. **Image Gallery**

   - All feature images displayed in responsive grid
   - First image preloaded with `fetchpriority="high"`
   - Lazy loading for subsequent images

5. **Feature Description**

   - Full feature description
   - Formatted in prose style
   - White card with shadow

6. **Call-to-Action**

   - "Zurück zu {Month} Updates" button
   - Link to all product updates

7. **Footer**
   - Standard Ordio footer (via `base/footer.php`)

## SEO Implementation

### Meta Tags

- **Title**: `{Feature Title} | Ordio Produkt-Updates`
- **Description**: First 155 characters of feature description
- **Canonical URL**: `https://www.ordio.com/posts/{slug}`
- **Open Graph**: Article type with title, description, image, URL, published_time
- **Twitter Card**: Summary large image

### Schema Markup

**BlogPosting Schema:**

- `@type`: BlogPosting
- `headline`: Feature title
- `author`: Ordio GmbH (Organization)
- `publisher`: Ordio GmbH with logo
- `datePublished`: Feature published date
- `dateModified`: Last updated date
- `image`: First feature image (if available)
- `keywords`: Feature title + "Ordio, Produkt-Updates"

**BreadcrumbList Schema:**

- Home → Produkt-Updates → {Month} → {Feature}
- 4-level breadcrumb navigation

## Routing

### .htaccess Rule

```apache
RewriteRule ^posts\/([^\/]+)\/?$ v2/pages/post.php?slug=$1 [L,QSA]
```

### Slug Matching Logic

1. Extract slug from URL parameter
2. Sanitize: only allow `a-z0-9\-_`, convert to lowercase
3. Search all months for feature with matching `read_more_link`
4. Case-insensitive comparison
5. Handle trailing slashes
6. Redirect to `/produkt-updates` if not found

## Data Flow

```
URL: /posts/meet-ordio-novi-ai-agent
  ↓
Extract slug: "meet-ordio-novi-ai-agent"
  ↓
Load produkt_updates.json
  ↓
Search all months → big_features → read_more_link
  ↓
Match: /posts/meet-ordio-novi-ai-agent === /posts/meet-ordio-novi-ai-agent
  ↓
Extract feature_data + parent_month
  ↓
Render page with feature details
```

## Sitemap Integration

### ~~sitemap.txt~~ (deprecated)

sitemap.txt is no longer used. Main site URLs are in v2/data/sitemap-pages.json; product updates are in /sitemap-produkt-updates.xml (on-demand).

### XML Sitemap

Post URLs included in `sitemap-produkt-updates.xml`:

- Priority: 0.6 (lower than month pages)
- Changefreq: monthly
- Lastmod: Feature published_date or last_updated

### RSS Feed

Individual posts included as RSS items:

- Title: Feature title
- Link: Post URL
- Description: Feature description (truncated to 200 chars)
- PubDate: Feature published_date

### LLMS Files

Post URLs included in both `llms.txt` and `llms-full.txt`:

- Format: `[FEATURE: {Title}] {Title} - {Description}...`
- Limited to 3 posts per month in `llms.txt` (essentials)
- All posts included in `llms-full.txt`

## Error Handling

### Invalid Slug

- Empty slug → Redirect to `/produkt-updates`
- Slug not found → Redirect to `/produkt-updates`
- Invalid characters → Sanitized automatically

### Missing Data

- Missing feature → Redirect to `/produkt-updates`
- Missing parent month → Redirect to `/produkt-updates`
- Missing images → Gallery section hidden
- Missing description → Fallback text displayed

## Styling

### Design System

- **Fonts**: Gilroy-Bold (headings), Inter (body)
- **Colors**: ordio-blue, #333, #6b7280
- **Spacing**: Consistent with `produkt_updates_month.php`
- **Cards**: White background, border, shadow, rounded corners
- **Buttons**: Gradient (ordio-blue to #286bcd), hover effects

### Responsive Design

- Mobile-first approach
- Grid layouts adapt to screen size
- Images scale appropriately
- Typography adjusts for readability

## Testing

### Test Script

Run `v2/test/test-post-page.php` to validate:

- Slug extraction and sanitization
- Feature lookup logic
- 404 handling
- Data structure validation

### Manual Testing

1. **Valid Post**: `/posts/meet-ordio-novi-ai-agent`

   - Should display feature content
   - Should show images
   - Should have working back link

2. **Invalid Post**: `/posts/non-existent`

   - Should redirect to `/produkt-updates`

3. **Schema Validation**: Use Google Rich Results Test
   - Should validate BlogPosting schema
   - Should validate BreadcrumbList schema

## Admin Integration

### Adding New Posts

1. Go to `/produkt-updates-admin`
2. Edit or create a feature
3. Set `read_more_link` to `/posts/{desired-slug}`
4. Save changes
5. Sitemaps and discovery files auto-regenerate

### Slug Guidelines

- Use lowercase letters, numbers, hyphens only
- Keep slugs descriptive and readable
- Match feature title when possible
- Avoid special characters
- Example: `meet-ordio-novi-ai-agent` (not `Meet_Ordio_Novi!`)

## Troubleshooting

### Post Not Found

**Symptoms**: Redirects to `/produkt-updates`

**Causes**:

- Slug doesn't match `read_more_link` exactly
- Feature removed from JSON
- Typo in URL

**Solution**:

1. Check `produkt_updates.json` for correct `read_more_link`
2. Verify slug matches exactly (case-insensitive)
3. Check for trailing slashes

### Images Not Displaying

**Symptoms**: Gallery empty or broken images

**Causes**:

- Image paths incorrect
- Images not uploaded
- File permissions issue

**Solution**:

1. Verify image paths in JSON start with `/`
2. Check files exist at specified paths
3. Verify file permissions (readable)

### Schema Validation Errors

**Symptoms**: Google Rich Results Test shows errors

**Causes**:

- Invalid JSON-LD syntax
- Missing required fields
- Date format issues

**Solution**:

1. Validate JSON-LD with jsonlint.com
2. Check all required BlogPosting fields present
3. Verify date formats (ISO 8601)

## Related Documentation

- [Product Updates Automation](product-updates-automation.md)
- [Product Updates Troubleshooting](product-updates-troubleshooting.md)
- [Admin Interface Guide](guides/PRODUCT_UPDATES_ADMIN.md) (if exists)
