Jag ska visa dig specifikt hur jag registrerar kortkoder direkt i temat, levererar dem på ett säkert sätt och återger dem på rätt plats - så här bygger jag en wordpress kortkod tema med en tydlig struktur, ren kod och snabba laddningstider. Jag ger praktiska exempel, förklarar do_shortcode i mallen, diskuterar attribut, escaping och caching och lägger till bästa praxis för långsiktigt underhållbara teman.
Centrala punkter
- Registrering via funktionerna add_shortcode och clear callback
- Integration i editorn, i widgetar och i mallar med do_shortcode
- Säkerhet genom escaping, attribut och validering
- Underhåll med barntema, dokumentation och versionskontroll
- Effekt med cachelagring, ekonomiska förfrågningar och ogiltigförklaring av cache
Kortkoder i temat: registrering och struktur
Jag placerar registreringen i temat i funktioner.php eller i ett litet plugin som måste användas om jag vill separera funktionaliteten från layouten. Varje callback-funktion returnerar en sträng och använder inte ett eko, annars hamnar utdata på oväntade ställen. Jag väljer unika prefix för namngivningen för att undvika konflikter med plugins. På så sätt håller jag koden läsbar och skapar en tydlig ordning, till exempel /inc/shortcodes.php med en riktad require_once i functions.php. Till att börja med räcker det med en enkel kortkod för hälsningar, som jag senare utökar steg för steg.
<?php
// /wp-content/themes/mitt-tema/functions.php
require_once get_template_directory() . '/inc/shortcodes.php';
<?php
// /wp-content/themes/my-theme/inc/shortcodes.php
funktion my_greeting_shortcode() {
return "Hej, välkommen till min webbplats!
}
add_shortcode('greeting', 'my_greeting_shortcode');
Använd kortkoder i mallen: do_shortcode
Jag kallar kortkoder i mallen med gör_kortkod när jag integrerar innehåll i sidhuvuden, sidfötter eller särskilda mallar. På så sätt håller jag redigeraren överskådlig och återkommande moduler finns på en central plats. Jag dokumenterar mallanrop i koden med en kort kommentar så att andra omedelbart vet vilken kortkod som körs här. För dynamiska parametrar skapar jag kortkodsträngen i PHP och skickar värdena säkert escapade. Den här metoden fungerar i alla mallfiler, t.ex. header.php, footer.php eller page-templates.
<?php
// I en mallfil
echo do_shortcode('[hälsning]');
echo do_shortcode('[colourbox color="green"]Fin text[/colorbox]');
Attribut, innehåll och säkerhet
Jag ställer in attribut med kortkod_atts och skydda värden med esc_html, esc_attr och esc_url. Detta förhindrar XSS och säkerställer giltig HTML i alla utdata. Jag behandlar valfritt innehåll som omsluts av en kortkod med wp_kses om jag bara vill tillåta vissa taggar. För färger accepterar jag bara värden från vitlistan eller kontrollerar med regex så att inga skript slinker igenom. Med dessa regler förblir kortkoderna tillförlitliga och ger förutsägbar utdata.
<?php
function my_colorbox_shortcode($atts, $content = null) {
$atts = shortcode_atts([
'color' => 'blue',
], $atts, 'colourbox');
$color = preg_match('/^#?[0-9a-fA-F]{3,6}$/', $atts['colour']) ? $atts['color'] : 'blå';
$inner = wp_kses($content, ['strong' => [], 'em' => [], 'a' => ['href' => []]]);
$style = 'bakgrund:' . esc_attr($color) . ';padding:10px';
returnera '<div style="' . $style . '">' . $inner . '</div>';
}
add_shortcode('colourbox', 'my_colorbox_shortcode');
Praktiska exempel: innevarande år, knapp och datum
Jag använder små hjälpkortkoder för återkommande innehåll som det aktuella Årknappar eller listor från anpassade inläggstyper. En kortkod för året besparar mig underhållsarbete i sidfoten eller i textblock. Jag utrustar knapparna med text, URL och färg så att redaktörerna kan arbeta utan att ändra koden. För datautmatning från CPT:er begränsar jag frågan och cachar resultaten så att sidan förblir snabb. Här är tre korta utdrag som grund.
<?php
// Jahr
add_shortcode('current-year', function() {
return date('Y');
});
// Button
add_shortcode('button', function($atts) {
$atts = shortcode_atts([
'text' => "Klicka nu",
'url' => '#',
'color' => '#2d89ef',
], $atts, 'knapp');
$text = esc_html($atts['text']);
$url = esc_url($atts['url']);
$color = esc_attr($atts['colour']);
returnera '<a href="/sv/' . $url . '/" style="background:' . $color . ';padding:8px 18px;color:#fff;border-radius:4px;text-decoration:none">' . $text . '</a>';
});
Tema eller plugin? Beslutsstöd och migration
Jag inkluderar kortkoder i Tema om de påverkar layouten, och i ett plugin om jag vill fortsätta använda dem oberoende av temat. På så sätt förlorar jag inte funktioner när jag byter tema och håller arkitekturen tydlig. För dokumentationen skapar jag en översikt över alla kortkoder med parametrar så att redaktörerna snabbt kan hitta rätt syntax. När jag flyttar senare exporterar jag kortkodsfilerna och ersätter noggrant de nödvändiga sökvägarna. Följande tabell hjälper till med beslutet.
| Användning | Tema | Plugin |
|---|---|---|
| Bindning till layout | Hög (t.ex. Hero-Box) | Låg |
| Migrationsrisk | Högre med temaändring | Låg, bibehålls |
| Underhåll/Uppdateringar | Med tema release | Egen lansering, mer flexibel |
| Målgrupp | Funktioner i layouten | Innehåll/Funktioner |
Använda kortkoder i redigeringsverktyget och i blockredigeringsverktyget
Jag lägger till kortkoder i den klassiska redigeraren direkt som Text och använda kortkodsblocket i blockredigeraren. Denna separation håller innehållet tydligt och minskar fel vid kopiering. För redaktörer dokumenterar jag exempel direkt i backend, t.ex. som ett exempelblock eller en anteckning i mallen. Jag är uppmärksam på skillnader mellan olika editorer när det gäller avstånd och inline-stilar, eftersom block ibland lägger till ytterligare omslag. Om du funderar på valet av redigerare hittar du i jämförelsen Block editor vs classic användbara tips.
Prestanda: Cachelagring och rena frågor
Jag håller kortkoder snabba genom att cachelagra beräkningsintensiva delar och begränsa dataåtkomst, vilket minskar Laddningstid sänker. För återkommande problem använder jag Transients eller WP Object Cache med en meningsfull nyckel. Jag begränsar frågor med posts_per_page, ställer bara in obligatoriska fält och undviker dyra COUNT-operationer. Jag lägger till bredd/höjd och lazy loading till bildutgångar för att göra sidan synlig snabbare. För dynamiska komponenter raderar jag cacheminnet så snart innehållet ändras.
<?php
add_shortcode('latest-offers', function($atts) {
$key = 'sc_latest_offers_v1';
$html = wp_cache_get($key);
if ($html !== false) {
return $html;
}
$q = new WP_Query([
'post_type' => 'angebot',
'posts_per_page' => 5,
'no_found_rows' => true,
'fields' => 'all',
]);
ob_start();
if ($q->have_posts()) {
echo '<ul class="offers">';
while ($q->have_posts()) { $q->the_post();
echo '<li>' . esc_html(get_the_title()) . '</li>';
}
echo '</ul>';
wp_reset_postdata();
}
$html = ob_get_clean();
wp_cache_set($key, $html, '', 600);
return $html;
});
Hitta och åtgärda felkällor snabbt
Jag aktiverar Felsökning-mode och kontrollera om kortkoden är korrekt registrerad. Ofta indikerar en vit skärm eller rå text att funktionen inte laddas eller använder echo istället för return. Loggposter avslöjar oväntade datatyper, felaktiga attribut eller saknade escapes. I mallar testar jag steg för steg: först statisk text, sedan kortkoden, sedan parametrar. Om du vill gå systematiskt tillväga kan du använda guiden till WordPress felsökningsläge.
Arbeta uppdateringssäkert med barntema
Jag skapar mina egna kortkoder i Barntema om jag inte kan eller vill ändra något i föräldratemat. På så sätt behålls anpassningar under temauppdateringar och jag kan kontrollera laddningssekvensen. Viktigt: registrera barntemat korrekt, håll functions.php smalt och inkludera endast specifika filer. För strukturerade projekt separerar jag kortkoder i /inc och dokumenterar dem med inline-kommentarer. En kompakt guide tillhandahålls av Instruktioner för barnteman.
Styling, semantik och tillgänglighet
Jag tar hand om rent HTML och semantiska taggar så att skärmläsare känner igen innehållet på rätt sätt. Jag visar bara knappar som en tagg med role="button" om de verkligen är länkar, annars väljer jag riktiga knappar. Jag håller höga färgkontraster och sätter fokusstilar så att tangentbordsanvändare tydligt kan se var de befinner sig. Jag minskar antalet inline-stilar och flyttar designen till en CSS-fil med tydliga klasser. På så sätt förblir kortkoderna flexibla och tillgängliga på samma gång.
API-integration och säker integration av externa data
Jag hämtar extern data via wp_remote_get och cachar dem så att sidan inte hänger sig under API-timeouts. Jag kontrollerar svaren för statuskoder, analyserar JSON på ett kontrollerat sätt och tillåter bara de fält som verkligen krävs. I händelse av fel visar jag en mager fallback-utgång eller döljer blocket. För användarinnehåll tar jag bort farliga taggar och validerar länkar noggrant. Detta håller kortkoderna stabila, även om externa tjänster fluktuerar.
Ladda tillgångar endast när de används
Jag laddar bara CSS/JS för kortkoder om de faktiskt visas på sidan. Detta sparar förfrågningar och håller den kritiska vägen CSS liten. Jag registrerar stilar och skript centralt och enqueuear dem i callbacken eller specifikt så snart jag känner igen kortkoden i innehållet. Viktigt: skriv aldrig hård kod i sidhuvudet utan att tänka efter, utan arbeta via enqueue-API:erna.
<?php // functions.php – Registrera tillgångar add_action('wp_enqueue_scripts', function() { wp_register_style('my-shortcodes', get_template_directory_uri() . '/assets/shortcodes.css', [], '1.0');
wp_register_script('my-shortcodes', get_template_directory_uri() . '/assets/shortcodes.js', [], '1.0', true); });
// Ladda endast om det finns i innehållet add_action('wp', function() { if (is_singular() && has_shortcode(get_post_field('post_content', get_queried_object_id()), 'button')) { wp_enqueue_style('my-shortcodes');
wp_enqueue_script('my-shortcodes'); } }); // Alternativt, anropa direkt i shortcode-callback: function my_assets_example_shortcode($atts, $content = null) { wp_enqueue_style('my-shortcodes'); return '<div class="my-box">' . wp_kses_post($content) . '</div>';
}
add_shortcode('my-box', 'my_assets_example_shortcode');
Kortkoder vs. direkta funktionsanrop i mallen
Jag gör en medveten distinktion: för fasta mallmoduler föredrar jag att anropa funktionen direkt istället för att parsa en kortkod. Detta sparar overhead, ökar läsbarheten och undviker överraskande filtereffekter. Kortkoder är avsedda för redaktionellt innehåll; mallar drar nytta av tydliga funktionsanrop med tydliga parametrar.
<?php
// Istället för:
echo do_shortcode('[hälsning]');
// Bättre i mallen:
echo my_greeting_shortcode();
Nästade kortkoder och formatering
Jag tar hänsyn till nästlade kortkoder och det automatiska införandet av p- och br-taggar. Om kortkoder omsluter annat innehåll fortsätter jag att rendera det inre innehållet med do_shortcode, men tillåter endast tillåtna taggar. Jag tar bort fula p-taggar runt kortkoder med shortcode_unautop om markeringen annars skulle rivas upp.
<?php function my_wrap_shortcode($atts, $content = null) { $inner = do_shortcode($content); // tillåta kapslade kortkoder return '<div class="wrap">' . wp_kses_post($inner) . '</div>';
}
add_shortcode('wrap', 'my_wrap_shortcode');
// Valfri formateringshjälp
add_filter('the_content', 'shortcode_unautop');
Internationalisering och lokalisering
Jag ser till att kortkoderna är språkanpassade: jag översätter textsträngar med temats textdomän och använder date_i18n för datum. På så sätt fungerar modulerna i flerspråkiga miljöer och förblir konsekventa när man byter språk. Jag lokaliserar standardtexter direkt i kortkodernas callbacks och escapar dem beroende på sammanhang.
<?php
// Temat förberett för översättningar
add_action('after_setup_theme', function() {
load_theme_textdomain('my-theme', get_template_directory() . '/languages');
});
// Lokaliserad hälsning
funktion my_greeting_shortcode() {
return esc_html__('Hej, välkommen till min webbplats!', 'my-theme');
}
// Lokaliserat år
add_shortcode('aktuellt år', function() {
return esc_html(date_i18n('Y'));
});
Inaktivering av cachen, varianter och nycklar
Jag planerar cacher på ett sådant sätt att varianter är tydligt åtskilda och innehåll blir föråldrat snabbt när ändringar görs. Attribut som limit eller taxonomi ingår i nyckeln. När jag sparar relevanta inläggstyper raderar jag specifikt de berörda nycklarna. I inställningar med hög trafik förlitar jag mig på en persistent objektcache-backend och grupperar nycklar efter funktion så att jag kan tömma dem kollektivt.
<?php
add_shortcode('latest-offers', function($atts) {
$atts = shortcode_atts(['limit' => 5], $atts, 'latest-offers');
$limit = max(1, (int) $atts['limit']);
$key = 'sc_latest_offers_v1_' . $limit;
if (($html = wp_cache_get($key, 'mytheme')) !== false) {
return $html;
}
$q = new WP_Query([
'post_type' => 'angebot',
'posts_per_page' => $limit,
'no_found_rows' => true,
]);
ob_start();
if ($q->have_posts()) {
echo '<ul class="offers">';
while ($q->have_posts()) { $q->the_post();
echo '<li>' . esc_html(get_the_title()) . '</li>';
}
echo '</ul>';
wp_reset_postdata();
}
$html = ob_get_clean();
wp_cache_set($key, $html, 'mytheme', 600);
return $html;
});
// Cache invalidieren, wenn Angebote geändert werden
add_action('save_post_angebot', function() {
foreach ([1,5,10] as $limit) {
wp_cache_delete('sc_latest_offers_v1_' . $limit, 'mytheme');
}
});
Fördjupa säkerheten: sanitiser, tillåtna attribut och rel/target
Jag utökar kortkoder med förnuftiga men säkra alternativ. För länkar begränsar jag målet till _self/_blank och ställer in rel="noopener noreferrer" för nya flikar. Jag kontrollerar färger med sanitize_hex_color. Jag behandlar innehåll kontextkänsligt, för inneslutet innehåll väljer jag wp_kses_post eller en mer restriktiv tillåtelselista.
<?php
add_shortcode('button', function($atts, $content = null) {
$atts = shortcode_atts([
'text' => '',
'url' => '#',
'färg' => '#2d89ef',
'target' => '_self',
], $atts, 'knapp');
$text = $atts['text'] !== '' ? $atts['text'] : ($content ?: esc_html__('Klicka nu', 'my-theme'));
$text = esc_html($text);
$url = esc_url($atts['url']);
$color = sanitise_hex_color($atts['colour']) ?: '#2d89ef';
$target = in_array($atts['target'], ['_self','_blank'], true) ? $atts['target'] : '_self';
$rel = $target === '_blank' ? 'noopener noreferrer' : '';
$style = 'bakgrund:' . $colour . ';padding:8px 18px;color:#fff;border-radius:4px;text-decoration:none';
returnera '<a class="sc-button" href="/sv/' . $url . '/" style="' . esc_attr($style) . '" target="' . esc_attr($target) . '" rel="' . esc_attr($rel) . '">' . $text . '</a>';
});
Editor-, widget- och feed-kontexter
Jag tar hänsyn till det sammanhang där kortkoden körs. Jag tillåter uttryckligen kortkoder i klassiska textwidgets och använder kortkodsblocket i blockwidgetredigeraren. I flöden eller i sökningen avaktiverar jag särskilt komplexa kortkoder och returnerar tomma. Dessutom laddar jag bara tillgångar på enstaka sidor om kortkoden visas i innehållet.
<?php
// Klassiska widgetar: aktivera kortkoder
add_filter('widget_text', 'do_shortcode');
// Undvik dyra utdata i flöden
add_shortcode('latest-offers-feed-safe', function($atts) {
if (is_feed()) {
return '';
}
// ... vanlig utdata
});
Utfasning, migrering till block och kompatibilitet
Jag planerar framtiden för mina kortkoder: När en tagg ersätts omdirigerar jag den till den nya under en tid och meddelar ändringen i changeloggen. Om du förlitar dig på blockredigeraren kan du registrera block på serversidan med render_callback och använda samma PHP-funktion internt som kortkoden. På så sätt samexisterar båda vägarna rent tills kortkoden löper ut.
'', 'url' => '#'], $atts, 'old-button');
$text = $map['text'] ?: $content;
return do_shortcode('[button text="' . esc_attr($text) . '" url="' . esc_url($map['url']) . '"]');
});
// Senare: ta bort helt och hållet
// remove_shortcode('old-button');
Tester och kvalitetssäkring
Jag validerar kritiska kortkoder med enhetstester så att refaktoriseringar inte ger några överraskningar. I testerna kontrollerar jag att obligatoriska attribut valideras, att standardvärden anges och att utdata är korrekt escapade. För HTML-utdata väljer jag robusta påståenden (innehåller istället för exakt matchning) så att små formateringsändringar inte bryter alla tester. Jag testar även kantfall som tomt innehåll, ogiltiga färger och mycket långa texter.
assertStringContainsString('Hej', $out);
$this->assertStringContainsString('href="#"", $out);
}
public function test_button_blocked_invalid_color() {
$out = do_shortcode('[button colour="javascript:alert(1)"]');
$this->assertStringNotContainsString('javascript:', $out);
}
}
Slutligen: Min kompakta praktiska översikt
Jag registrerar kortkoder tydligt, levererar dem säkert och håller dem med Caching snabbt. För redaktionell användning dokumenterar jag exempel och säkerställer konsekventa parametrar så att alla kan använda dem med tillförsikt. Layoutrelaterade moduler hamnar i temat, innehållsrelaterade funktioner i en plugin så att webbplatsen förblir flexibel på lång sikt. Med ett barntema, felsökningsloggar och ren semantik förblir utveckling och underhåll avslappnat. Resultatet är ett wordpress shortcode-tema som ger tillförlitlig rendering, är lätt att underhålla och ger innehållsteamen verklig frihet.


