# Blog Frontend Patterns Extraction

**Last Updated:** 2026-01-09

Extracted component patterns, HTML structures, CSS classes, and styling patterns from WordPress blog frontend analysis for PHP template implementation.

## Overview

This document extracts patterns from `docs/data/blog-frontend-structure.json` and WordPress blog analysis to inform PHP template component development.

## Page Type Analysis

### 1. Blog Index (`/insights/`)

**URL**: `https://www.ordio.com/insights/`

**Meta Tags Pattern**:

- Title: "Tipps zu Schichtplanung & HR-Management | Ordio Blog"
- Description: 155-160 chars, du tone
- Robots: "index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1"
- OG Type: "article" (not "website")
- OG URL: `/insights/`
- Article Modified Time: Present

**Schema Markup Pattern**:

- Organization schema (all pages)
- WebSite schema (all pages)
- WebPage schema (with breadcrumb reference)
- BreadcrumbList schema

**Content Structure**:

- Main tag: `<main>`
- H1: 1 (page title)
- H3: 17 (post titles in cards)
- Images: 16
- Links: 42

**Components Detected**:

- Post Cards: 8 cards
- Pagination: 1 component

**CSS Classes** (from main_content):

- None detected in main tag (WordPress generated)

**Post Card Pattern** (inferred):

- Featured image
- Category badge
- Title (H3, linked)
- Excerpt/preview
- Publication date
- Link to post

### 2. Category Archive - Lexikon (`/insights/lexikon/`)

**URL**: `https://www.ordio.com/insights/lexikon/`

**Meta Tags Pattern**:

- Title: "Lexikon - Ordio"
- Robots: "noindex, follow" (category archives not indexed)
- OG Type: "article"
- OG URL: `/insights/category/lexikon/` (note: `/category/` in URL)

**Schema Markup Pattern**:

- Organization schema
- WebSite schema
- ImageObject schema (primary image)
- CollectionPage schema (with primaryImageOfPage reference)
- BreadcrumbList schema

**Content Structure**:

- Main tag: `<main>`
- H1: 1 (category title)
- H3: 22 (post titles)
- Images: 0 (no featured images in cards)
- Links: 73

**Components Detected**:

- Pagination: 1 component
- Post Cards: 22 cards (inferred from H3 count)

**Category Header Pattern**:

- H1 with category name
- Category description (inferred)

### 3. Category Archive - Ratgeber (`/insights/ratgeber/`)

**URL**: `https://www.ordio.com/insights/ratgeber/`

**Meta Tags Pattern**:

- Title: "Ratgeber - Ordio"
- Robots: "noindex, follow"
- OG Type: "article"
- OG Description: "Praxisnahe Tipps zu Dienstplänen..."

**Schema Markup Pattern**:

- Same as Lexikon (CollectionPage, ImageObject, BreadcrumbList)

**Content Structure**:

- Main tag: `<main>`
- H1: 1 (category title)
- H2: 2 (section headings)
- H3: 37 (post titles)
- Images: 37 (featured images in cards)
- Links: 76

**Components Detected**:

- Pagination: 1 component
- Post Cards: 37 cards (with featured images)

**Differences from Lexikon**:

- Has H2 section headings
- Post cards include featured images
- More posts (37 vs 22)

### 4. Category Archive - Inside Ordio (`/insights/inside-ordio/`)

**URL**: `https://www.ordio.com/insights/inside-ordio/`

**Meta Tags Pattern**:

- Title: "Inside Ordio - Ordio"
- Robots: "noindex, follow"
- OG Description: "Erhalte spannende Einblicke..."

**Content Structure**:

- Main tag: `<main>`
- H1: 1 (category title)
- H3: 6 (post titles)
- Images: 0
- Links: 14

**Components Detected**:

- Pagination: 1 component
- Post Cards: 6 cards

**Smallest Category**:

- Only 6 posts
- No featured images in cards

### 5. Single Post (`/insights/{category}/{slug}/`)

**URL Example**: `https://www.ordio.com/insights/lexikon/leitfaden-zur-finanzbuchhaltung/`

**Meta Tags Pattern**:

- Title: "{Post Title} | {Category} | Ordio"
- Description: Post-specific, 155-160 chars
- Robots: "index, follow, max-image-preview:large..."
- OG Type: "article"
- Article Published Time: ISO 8601 format
- Article Modified Time: ISO 8601 format
- Author: Present (e.g., "Emma")
- Twitter Labels: "Written by", "Est. reading time"

**Schema Markup Pattern**:

- Organization schema
- WebSite schema
- ImageObject schema (featured image)
- WebPage schema (with primaryImageOfPage, breadcrumb reference)
- BreadcrumbList schema
- Article schema (with author Person reference)
- Person schema (author)

**Content Structure**:

- Main tag: `<main>` with classes: `max-w-7xl mx-auto px-4 sm:px-6 text-gray antialiased`
- H1: 1 (post title)
- H2: 4 (main sections)
- H3: 4 (subsections)
- Images: 9 (featured + content images)
- Links: 18

**Components Detected**:

- Post Header: Featured image, title, date, author
- Post Content: Main article content
- Related Posts: 14 post cards
- Pagination: 1 component (Previous/Next navigation)

**Main Content CSS Classes**:

- `max-w-7xl` - Max width 1280px
- `mx-auto` - Centered horizontally
- `px-4 sm:px-6` - Responsive padding (16px mobile, 24px desktop)
- `text-gray` - Text color
- `antialiased` - Font smoothing

## Component Patterns Extracted

### Post Card Component Pattern

**HTML Structure** (inferred from analysis):

```html
<article class="post-card">
  <a href="/insights/{category}/{slug}/" class="post-card-link">
    <?php if ($featured_image): ?>
    <img
      src="<?php echo $featured_image; ?>"
      alt="<?php echo $title; ?>"
      class="post-card-image"
      loading="lazy"
    />
    <?php endif; ?>

    <div class="post-card-content">
      <span class="post-card-category"><?php echo $category_label; ?></span>
      <h3 class="post-card-title"><?php echo htmlspecialchars($title); ?></h3>
      <p class="post-card-excerpt"><?php echo htmlspecialchars($excerpt); ?></p>
      <time class="post-card-date" datetime="<?php echo $publication_date; ?>">
        <?php echo format_blog_date($publication_date); ?>
      </time>
    </div>
  </a>
</article>
```

**Variations**:

- **Index/Category**: Full card with image
- **Related Posts**: Smaller card, may omit excerpt
- **No Image**: Lexikon, Inside Ordio (image_count: 0)

**CSS Classes** (inferred):

- Container: `post-card` or similar
- Image: `post-card-image`
- Content: `post-card-content`
- Category: `post-card-category` (badge style)
- Title: `post-card-title` (H3)
- Excerpt: `post-card-excerpt`
- Date: `post-card-date`

### Pagination Component Pattern

**HTML Structure** (inferred):

```html
<nav class="pagination" aria-label="Seitennavigation">
  <?php if ($has_prev): ?>
  <a
    href="<?php echo $prev_url; ?>"
    class="pagination-link pagination-prev"
    rel="prev"
  >
    ← Vorherige
  </a>
  <?php endif; ?>

  <div class="pagination-numbers">
    <?php foreach ($page_numbers as $page): ?>
    <?php if ($page === $current_page): ?>
    <span class="pagination-current" aria-current="page"
      ><?php echo $page; ?></span
    >
    <?php elseif ($page === '...'): ?>
    <span class="pagination-ellipsis">...</span>
    <?php else: ?>
    <a href="<?php echo $page_url; ?>" class="pagination-link"
      ><?php echo $page; ?></a
    >
    <?php endif; ?>
    <?php endforeach; ?>
  </div>

  <?php if ($has_next): ?>
  <a
    href="<?php echo $next_url; ?>"
    class="pagination-link pagination-next"
    rel="next"
  >
    Nächste →
  </a>
  <?php endif; ?>
</nav>
```

**URL Pattern**:

- Index: `/insights/page/2/`
- Category: `/insights/{category}/page/2/`

### Post Header Component Pattern

**HTML Structure** (inferred from single post):

```html
<header class="post-header">
  <?php if ($featured_image): ?>
  <img
    src="<?php echo $featured_image; ?>"
    alt="<?php echo htmlspecialchars($title); ?>"
    class="post-header-image"
    width="1024"
    height="576"
    fetchpriority="high"
  />
  <?php endif; ?>

  <div class="post-header-content">
    <span class="post-header-category">
      <a href="/insights/<?php echo $category; ?>/"
        ><?php echo $category_label; ?></a
      >
    </span>

    <h1 class="post-header-title"><?php echo htmlspecialchars($title); ?></h1>

    <div class="post-header-meta">
      <time
        datetime="<?php echo $publication_date; ?>"
        class="post-header-date"
      >
        <?php echo format_blog_date($publication_date); ?>
      </time>

      <?php if ($author): ?>
      <span class="post-header-author">
        Von
        <?php echo htmlspecialchars($author); ?>
      </span>
      <?php endif; ?>

      <?php if ($reading_time): ?>
      <span class="post-header-reading-time">
        <?php echo $reading_time; ?>
        Minuten Lesezeit
      </span>
      <?php endif; ?>
    </div>
  </div>
</header>
```

### Post Content Component Pattern

**HTML Structure** (inferred):

```html
<article class="post-content">
  <div class="post-content-inner prose prose-lg max-w-none">
    <?php echo sanitizeHtmlOutput($html_content); ?>
  </div>
</article>
```

**Content Processing**:

- HTML sanitization (allow safe tags only)
- Image optimization (srcset, lazy loading)
- Link processing (internal/external)
- Responsive typography (prose classes)

**CSS Classes**:

- Container: `post-content`
- Inner: `post-content-inner prose prose-lg max-w-none`
- Typography: Tailwind prose classes

### Related Posts Component Pattern

**HTML Structure** (inferred):

```html
<section class="related-posts">
  <h2 class="related-posts-title">Ähnliche Artikel</h2>

  <div
    class="related-posts-grid grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6"
  >
    <?php foreach ($related_posts as $post): ?>
    <?php
            // Set PostCard props
            $title = $post['title'];
            $featured_image = $post['featured_image'];
            $excerpt = $post['excerpt'];
            $publication_date = $post['publication_date'];
            $category = $post['category'];
            $url = $post['url'];
            include __DIR__ . '/../components/blog/PostCard.php';
            ?>
    <?php endforeach; ?>
  </div>
</section>
```

**Count**: 14 posts (from analysis)

### Category Navigation Component Pattern

**HTML Structure** (inferred):

```html
<nav class="category-nav" aria-label="Blog-Kategorien">
  <ul class="category-nav-list">
    <li>
      <a
        href="/insights/"
        class="category-nav-link <?php echo $current_category === 'all' ? 'active' : ''; ?>"
      >
        Alle Artikel
      </a>
    </li>
    <li>
      <a
        href="/insights/lexikon/"
        class="category-nav-link <?php echo $current_category === 'lexikon' ? 'active' : ''; ?>"
      >
        Lexikon <span class="post-count">(<?php echo $lexikon_count; ?>)</span>
      </a>
    </li>
    <li>
      <a
        href="/insights/ratgeber/"
        class="category-nav-link <?php echo $current_category === 'ratgeber' ? 'active' : ''; ?>"
      >
        Ratgeber
        <span class="post-count">(<?php echo $ratgeber_count; ?>)</span>
      </a>
    </li>
    <li>
      <a
        href="/insights/inside-ordio/"
        class="category-nav-link <?php echo $current_category === 'inside-ordio' ? 'active' : ''; ?>"
      >
        Inside Ordio
        <span class="post-count">(<?php echo $inside_ordio_count; ?>)</span>
      </a>
    </li>
  </ul>
</nav>
```

**Variations**:

- Tabs style (horizontal)
- Links style (vertical)
- Active state highlighting

### Breadcrumbs Component Pattern

**HTML Structure** (inferred from schema):

```html
<nav class="breadcrumbs" aria-label="Breadcrumb">
  <ol
    class="breadcrumbs-list"
    itemscope
    itemtype="https://schema.org/BreadcrumbList"
  >
    <li
      itemprop="itemListElement"
      itemscope
      itemtype="https://schema.org/ListItem"
    >
      <a href="/" itemprop="item">
        <span itemprop="name">Home</span>
      </a>
      <meta itemprop="position" content="1" />
    </li>
    <?php if ($category): ?>
    <li
      itemprop="itemListElement"
      itemscope
      itemtype="https://schema.org/ListItem"
    >
      <a href="/insights/<?php echo $category; ?>/" itemprop="item">
        <span itemprop="name"><?php echo $category_label; ?></span>
      </a>
      <meta itemprop="position" content="2" />
    </li>
    <?php endif; ?>
    <li
      itemprop="itemListElement"
      itemscope
      itemtype="https://schema.org/ListItem"
    >
      <span itemprop="name"
        ><?php echo htmlspecialchars($current_page_title); ?></span
      >
      <meta itemprop="position" content="<?php echo $position; ?>" />
    </li>
  </ol>
</nav>
```

**Schema Integration**:

- Microdata attributes (itemscope, itemprop)
- JSON-LD schema (separate script tag)

## CSS Class Patterns

### Container Classes

**Main Content Container**:

- `max-w-7xl` - Max width 1280px
- `mx-auto` - Centered
- `px-4 sm:px-6` - Responsive padding

**Post Content Container**:

- `prose prose-lg max-w-none` - Typography (Tailwind Typography plugin)

### Grid Classes

**Post Grid** (inferred):

- `grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3` - Responsive grid
- `gap-6` or `gap-8` - Grid gap

**Related Posts Grid**:

- `grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3` - Responsive grid
- `gap-6` - Grid gap

### Typography Classes

**Headings**:

- H1: `font-gilroybold text-4xl sm:text-5xl` (inferred from other pages)
- H2: `font-gilroybold text-3xl sm:text-4xl`
- H3: `font-inter600 text-xl` (post card titles)

**Body Text**:

- `text-base` or `text-lg` - Base size
- `text-gray-600` or `text-gray-700` - Color
- `leading-relaxed` - Line height

### Component-Specific Classes

**Post Card**:

- Container: `bg-white rounded-xl shadow-md border border-gray-200`
- Hover: `hover:shadow-lg hover:border-blue-300`
- Transition: `transition-all duration-300`

**Category Badge**:

- `inline-block px-2 py-1 text-xs bg-gray-100 text-gray-600 rounded-full`

**Pagination**:

- Container: `pagination`
- Link: `pagination-link`
- Current: `pagination-current`
- Ellipsis: `pagination-ellipsis`

## Responsive Breakpoints

Based on Tailwind CSS classes:

- **Mobile**: Default (< 640px)

  - Padding: `px-4` (16px)
  - Grid: 1 column
  - Text: Base size

- **Small** (`sm:`): 640px+

  - Padding: `sm:px-6` (24px)
  - Grid: 2 columns
  - Text: Larger sizes

- **Large** (`lg:`): 1024px+
  - Grid: 3 columns
  - Text: Largest sizes
  - Max width containers

## Image Patterns

### Featured Image Pattern

**Single Post**:

- Width: 1024px
- Height: 576px
- Format: JPEG (from WordPress)
- Fetchpriority: "high" (hero image)

**Post Card**:

- Responsive sizes (srcset)
- Lazy loading
- WebP format (for migration)

### Image Optimization Requirements

1. **Responsive Srcset**:

   - 640w, 768w, 1024w, 1280w variants
   - WebP format

2. **Sizes Attribute**:

   - `(max-width: 640px) 640px, (max-width: 1024px) 1024px, 1280px`

3. **Lazy Loading**:

   - Below-fold: `loading="lazy"`
   - Hero: `fetchpriority="high"`

4. **Explicit Dimensions**:
   - Width and height attributes
   - Prevents CLS

## Link Patterns

### Internal Links

**Post Links**:

- Pattern: `/insights/{category}/{slug}/`
- Anchor text: Post title

**Category Links**:

- Pattern: `/insights/{category}/`
- Anchor text: Category name

**Index Link**:

- Pattern: `/insights/`
- Anchor text: "Alle Artikel" or "Ordio Insights"

### External Links

**Pattern**:

- `target="_blank"`
- `rel="noopener noreferrer"`
- Visual indicator (icon or text)

## Navigation Patterns

### Header Navigation

**Structure**:

- Main site navigation
- Blog/Insights link
- Category links (if present)

**Mobile**:

- Collapsible menu
- Hamburger icon

### Category Filters

**Location**: Blog index and category pages

**Pattern**:

- Tabs or buttons
- Active state highlighting
- Post counts per category

## Schema Markup Patterns

### Common Schemas (All Pages)

1. **Organization Schema**:

   - @id: `https://www.ordio.com/#organization`
   - Name: "Ordio GmbH"
   - Logo: ImageObject reference
   - SameAs: Social media links

2. **WebSite Schema**:

   - @id: `https://www.ordio.com/#website`
   - SearchAction: Search functionality
   - Publisher: Organization reference

3. **WebPage Schema**:
   - @id: `{url}#webpage`
   - isPartOf: WebSite reference
   - about: Organization reference
   - breadcrumb: BreadcrumbList reference

### Page-Specific Schemas

**Index Page**:

- WebPage schema
- BreadcrumbList schema

**Category Archive**:

- CollectionPage schema
- ImageObject schema (primary image)
- BreadcrumbList schema

**Single Post**:

- Article schema
- Person schema (author)
- ImageObject schema (featured image)
- BreadcrumbList schema

## Meta Tag Patterns

### Common Meta Tags

**All Pages**:

- Viewport: `width=device-width, initial-scale=1.0`
- Robots: Varies by page type
- OG Locale: `de_DE`
- OG Site Name: "Ordio"

**Index Page**:

- Robots: `index, follow, max-image-preview:large...`
- OG Type: `article` (not `website`)

**Category Archives**:

- Robots: `noindex, follow`
- OG Type: `article`

**Single Posts**:

- Robots: `index, follow, max-image-preview:large...`
- OG Type: `article`
- Article Published Time: ISO 8601
- Article Modified Time: ISO 8601
- Author: Present
- Twitter Labels: "Written by", "Est. reading time"

## PHP Implementation Patterns

### Component Props Pattern

```php
<?php
// Set component props before include
$title = $post['title'];
$featured_image = $post['featured_image'];
$excerpt = $post['excerpt'];
$publication_date = $post['publication_date'];
$category = $post['category'];
$url = $post['url'];

// Include component
include __DIR__ . '/../components/blog/PostCard.php';
?>
```

### Conditional Rendering Pattern

```php
<?php if ($featured_image): ?>
    <img src="<?php echo $featured_image; ?>" alt="<?php echo htmlspecialchars($title); ?>" />
<?php endif; ?>

<?php if ($author): ?>
    <span class="author">Von <?php echo htmlspecialchars($author); ?></span>
<?php endif; ?>
```

### Loop Pattern

```php
<?php foreach ($posts as $post): ?>
    <?php
    // Set props
    $title = $post['title'];
    $url = $post['url'];
    // ... other props

    // Include component
    include __DIR__ . '/../components/blog/PostCard.php';
    ?>
<?php endforeach; ?>
```

## Accessibility Patterns

### Semantic HTML

- `<article>` for post cards
- `<nav>` for navigation
- `<main>` for main content
- `<header>` for post header
- `<section>` for related posts
- `<time>` for dates

### ARIA Attributes

- `aria-label` for navigation
- `aria-current="page"` for current pagination
- `aria-live` for dynamic content
- `aria-hidden="true"` for decorative elements

### Keyboard Navigation

- Focus states visible
- Tab order logical
- Skip links (if implemented)

## Performance Patterns

### Image Loading

- Hero images: `fetchpriority="high"`
- Below-fold: `loading="lazy"`
- Responsive srcset
- WebP format

### CSS Loading

- Critical CSS inline or preloaded
- Non-critical CSS deferred
- Tailwind classes (utility-first)

### JavaScript Loading

- Defer non-critical scripts
- Alpine.js for interactivity
- No blocking scripts

## Related Documentation

- [Template Patterns Analysis](TEMPLATE_PATTERNS_ANALYSIS.md)
- [Frontend Layouts](FRONTEND_LAYOUTS.md)
- [Frontend Components](FRONTEND_COMPONENTS.md)
- [Frontend SEO Structure](FRONTEND_SEO_STRUCTURE.md)
