Pinegrow × WordPress – Cheat Sheet

0) Mentales Modell

  • Arbeite in den HTML‑Quellen (z. B. front-page.html, index.html).
  • Füge dort WP‑Aktionen (Template Parts, Code/PHP, Loops …) ein.
  • Export generiert die PHPs. Exportierte .php später nicht per Hand ändern (würde überschrieben).

1) Header & Footer – sauber trennen

Ziel: getheader()/getfooter() nutzen und Template‑Parts erzeugen.

Vorgehen in Pinegrow (PG 8.5):

  1. Header anlegen
  • In deiner HTML‑Quelle vom <!DOCTYPE html> bis inkl. öffnendem <body …> markieren.
  • WordPress → Define template partName: header → Datei „.
  • Inhalt von header.php sollte enthalten:
  • <!DOCTYPE html>
  • <html <?php languageattributes(); ?>>
  • <head> … <?php wphead(); ?> … </head>
  • <body … class="<?php echo implode(' ', getbodyclass()); ?>">
  • <?php if ( functionexists('wpbodyopen') ) wpbodyopen(); ?>
  1. Footer anlegen
  • Footer‑Markup bis ` markieren → Define template part`.
  • Enthält Footer‑HTML + <?php wpfooter(); ?> + </body></html>.
  1. Auf jeder Seite einbinden
  • Ganz oben im <body>: WordPress → Code → PHP:
&lt;?php get_header(); ?&gt;
  • Ganz unten vor </body>: WordPress → Code → PHP:
&lt;?php get_footer(); ?&gt;

> Hinweis: Die alten Template‑Part‑Marker nicht in <main> liegen lassen (sonst Wandersignale wie _WPENDHEADER).


2) „Site content“ vs. „The loop“ – nie mischen

  • Site content = fertiger Loop für singuläre Seiten (Front‑Page, Page, Single). Enthält thepost() + thecontent().
  • The loop + Post content = manuelle Variante.
  • Regel: In einem <main> immer nur eines von beiden verwenden.

Beispiel (Front‑Page, simpel)

&lt;?php get_header(); ?&gt;
&lt;main&gt;
&lt;?php // Variante A – Site content (empfohlen für Front/Page)
if ( have_posts() ) : while ( have_posts() ) : the_post();
the_content();
endwhile; endif; ?&gt;
&lt;/main&gt;
&lt;?php get_footer(); ?&gt;

Beispiel (Blogliste in index.php)

&lt;?php get_header(); ?&gt;
&lt;main class="container py-5"&gt;
&lt;?php if ( have_posts() ) : ?&gt;
&lt;div class="row g-4"&gt;
&lt;?php while ( have_posts() ) : the_post(); ?&gt;
&lt;article class="col-md-6 col-lg-4"&gt;
&lt;h2 class="h5"&gt;&lt;a href="&lt;?php the_permalink(); ?&gt;"&gt;&lt;?php the_title(); ?&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;?php the_excerpt(); ?&gt;&lt;/p&gt;
&lt;/article&gt;
&lt;?php endwhile; ?&gt;
&lt;/div&gt;
&lt;?php the_posts_pagination(); ?&gt;
&lt;?php else : ?&gt;
&lt;p&gt;&lt;?php _e('Keine Beiträge gefunden.', 'wpcgrau'); ?&gt;&lt;/p&gt;
&lt;?php endif; ?&gt;
&lt;/main&gt;
&lt;?php get_footer(); ?&gt;


3) Menü korrekt ausgeben (Bootstrap)

functions.php – Menü registrieren:

register_nav_menus([
'primary' =&gt; __('Hauptmenü', 'wpcgrau'),
]);

Template (z. B. im Header bei der <ul>):

&lt;?php
if ( has_nav_menu('primary') ) {
wp_nav_menu([
'theme_location' =&gt; 'primary',
'container' =&gt; '',
'menu_class' =&gt; 'navbar-nav ms-auto',
'fallback_cb' =&gt; '__return_empty_string',
]);
}
?&gt;

> Wichtig: Action auf die ` legen, nicht auf <nav>. Kein itemswrap => ‚%3$s‘ (sonst fehlt das <ul>`).


4) Logo oder Seitentitel – Fallback

Theme‑Support (einmalig):

add_theme_support('custom-logo', [
'height' =&gt; 200,
'width' =&gt; 200,
'flex-height' =&gt; true,
'flex-width' =&gt; true,
]);

Template (Navbar‑Brand):

&lt;?php if ( function_exists('the_custom_logo') &amp;&amp; has_custom_logo() ) : ?&gt;
&lt;?php the_custom_logo(); ?&gt;
&lt;?php else : ?&gt;
&lt;a class="navbar-brand" href="&lt;?php echo esc_url( home_url('/') ); ?&gt;"&gt;
&lt;?php bloginfo('name'); ?&gt;
&lt;/a&gt;
&lt;?php endif; ?&gt;

Optional – zur Logo‑Ausgabe hinzufügen:

add_filter('get_custom_logo', function($html){
return str_replace('custom-logo-link', 'custom-logo-link navbar-brand', $html);
});


5) Hintergrundbild via Customizer ohne Gradient zu verlieren

CSS ():

.masthead{
background-image:
linear-gradient(to bottom, rgba(0,0,0,.3) 0%, rgba(0,0,0,.7) 75%, #000 100%),
var(--masthead-img, url('../assets/img/bg-masthead.jpg'));
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* (Übergangslösung, falls noch inline background-image existiert) */
.masthead[style]{
background-image:
linear-gradient(to bottom, rgba(0,0,0,.3) 0%, rgba(0,0,0,.7) 75%, #000 100%),
var(--masthead-img, url('../assets/img/bg-masthead.jpg')) !important;
}

PHP ():

// Dev: Stylesheet cache-busten
add_action('wp_enqueue_scripts', function(){
wp_dequeue_style('wpcgrau');
wp_enqueue_style('wpcgrau', get_stylesheet_uri(), [], time());
}, 99);

function codekeks_get_mod_image_url($key, $size='full'){
$v = get_theme_mod($key);
if(!$v) return '';
if(is_numeric($v)) return wp_get_attachment_image_url((int)$v, $size) ?: '';
return esc_url_raw($v);
}

add_action('wp_head', function(){
$url = codekeks_get_mod_image_url('wpc_grau_header_wpc_grau_bgpic', 'full');
echo "\n&lt;!-- codekeks custom.php loaded --&gt;\n";
if($url){
echo '&lt;style id="codekeks-masthead-var"&gt;:root{--masthead-img:url(\''.esc_url($url).'\')}&lt;/style&gt;'."\n";
}
}, 999);


6) Template‑Hierarchie – Kurzreferenz

  • front-page.php – Startseite (höchste Priorität, egal ob Blog oder statische Seite).
  • home.php – Blog‑Index (Beiträge‑Übersicht).
  • page.php – einzelne Seite (Typ page). Varianten: page-{slug}.php, page-{id}.php.
  • single.php – einzelne Beiträge. Spezifisch: single-post.php.
  • singular.php – generisch für alle Singles, falls single.php/page.php fehlen.
  • index.php – Fallback, muss existieren.

Matrix Startseite:

  • Einstellungen → Lesen = „Statische Seite“: nimmt front-page.php, Inhalt kommt von der gewählten Seite.
  • Einstellungen → Lesen = „Neueste Beiträge“: nimmt front-page.php (Startseite) + home.php (Blogliste).

7) Häufige Stolperfallen (und Fixes)

  • Doppelter Content: Nicht Site content und Loop gleichzeitig im selben <main>.
  • Menü ohne `: Keine itemswrap => ‚%3$s‘ ohne eigenen <ul> Wrapper; Action gehört auf die <ul>`.
  • Header/Footer im Content: Falsch platzierte Template‑Part‑Marker. Lösung: echte getheader()/get_footer() nutzen.
  • Cache frisst Änderungen: DevTools → Disable cache aktiv, WP‑Cache leeren, Versioning (time()) nutzen.
  • Export überschreibt Hand‑Änderungen: Änderungen nur in HTML‑Quellen + WP‑Aktionen.

8) Export‑Workflow (sicher)

  1. HTML‑Quelle(n) bearbeiten, WP‑Aktionen setzen.
  2. WordPress → Export Theme.
  3. Im Frontend Quelltext prüfen (z. B. <!-- codekeks custom.php loaded -->).
  4. Keine produktiven Hand‑Edits in exportierten PHPs.

9) Nützliche Debug‑Snippets

Schneller Head‑Ping:

add_action('wp_head', fn()=&gt;print("&lt;!-- DEV ".time()." --&gt;\n"), 1000);

Body‑Klassen prüfen:

echo '&lt;!-- '.implode(' ', get_body_class()).' --&gt;';

Menü‑Registrierung sichtbar machen:

if ( ! has_nav_menu('primary') ) echo '&lt;!-- primary menu not assigned --&gt;';


10) Bootstrap‑Nav – Minimalbeispiel

&lt;nav class="navbar navbar-expand-lg navbar-light fixed-top" id="mainNav"&gt;
&lt;div class="container px-4 px-lg-5"&gt;
&lt;?php if ( function_exists('the_custom_logo') &amp;&amp; has_custom_logo() ) : the_custom_logo(); else : ?&gt;
&lt;a class="navbar-brand" href="&lt;?php echo esc_url( home_url('/') ); ?&gt;"&gt;&lt;?php bloginfo('name'); ?&gt;&lt;/a&gt;
&lt;?php endif; ?&gt;

&lt;button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"&gt;
&lt;?php _e('Menü','wpcgrau'); ?&gt; &lt;i class="fas fa-bars"&gt;&lt;/i&gt;
&lt;/button&gt;

&lt;div class="collapse navbar-collapse" id="navbarResponsive"&gt;
&lt;ul class="navbar-nav ms-auto"&gt;
&lt;?php
if ( has_nav_menu('primary') ) {
wp_nav_menu([
'theme_location' =&gt; 'primary',
'container' =&gt; false,
'items_wrap' =&gt; '%3$s', // wir benutzen die vorhandene &lt;ul&gt;
'fallback_cb' =&gt; '__return_empty_string',
]);
}
?&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/nav&gt;


Letzter Tipp: Orange PG‑Warnungen („action will be ignored“) ernst nehmen: Die Aktion hängt meist am falschen Element/Ort. Lieber einmal löschen und am richtigen Knoten neu setzen.