Posted in

Hvordan lage en tilpasset widget i WordPress

Norwegian developer builds a custom wordpress widget using gutenberg and php

En liten boks i sidepanelet kan gjøre stor forskjell. En prisboks, et søk med filtre, et kart, en CTA – ofte finnes det ikke en ferdig widget som gjør akkurat det som trengs. Denne guiden viser hvordan lage en tilpasset widget i WordPress – både på den klassiske måten med WP_Widget og den moderne, blokkbaserte veien via Gutenberg. Den tar for seg oppsett, sikkerhet, styling, ytelse og vedlikehold, slik at resultatet blir stabilt, raskt og fremtidsvennlig.

Hovedpoeng

  • For å lage en tilpasset widget i WordPress, velg blokkbasert Gutenberg for nye prosjekter (npx @wordpress/create-block), men støtt gjerne klassisk WP_Widget for bakoverkompatibilitet.
  • Legg funksjonaliteten i et eget plugin – ikke i et barnetema – slik at widgeten overlever temabytte, kan aktiveres uavhengig og versjoneres.
  • Bygg logikken riktig: implementer widget(), form() og update() i WP_Widget, eller bruk render_callback for dynamisk server-side innhold i blokker.
  • Prioritér sikkerhet og ytelse: sanitér inndata, escap utdata, last CSS/JS kun når widgeten er i bruk (is_active_widget eller block.json), og cache dyre kall.
  • Test og vedlikehold den tilpassede widgeten i WordPress med WP_DEBUG og Query Monitor, følg WCAG og semantikk, versjoner med SemVer og håndter edge cases før produksjon.

Forstå Widgets I Dag: Klassiske Vs. Blokkbaserte

Norwegian developer adds custom block in wordpress alongside classic widget panel.

Klassiske widgets har i årevis vært drevet av WP_Widget-klassen og administrert via det gamle widgetpanelet. Fra og med WordPress 5.8 ble widget-områdene blokkbaserte, slik at man kan bruke Gutenberg-blokker i sidefelt og bunntekst. Likevel er klassiske widgets fortsatt støttet for bakoverkompatibilitet, noe som gjør at begge metodene kan leve side om side.

Når Bør Du Lage En Egen Widget?

  • Når ingen eksisterende plugin eller blokk tilbyr funksjonaliteten eller utseendet du trenger.
  • Når designet krever spesiallogikk (API-kall, kondisjonell visning, personalisering) som ikke finnes som standardblokk.
  • Når innholdet må kunne legges inn i et widget-område (ikke nødvendigvis i en side/post), men likevel være redigerbart fra admin.

Et godt tommelfingerregler: Hvis funksjonen er «site-wide» og uavhengig av tema, er en egen widget i et plugin som oftest riktig.

Kompatibilitet Fra WordPress 5.8 Og Oppover

  • Widget-områder bruker blokker som standard, men klassiske widgets fungerer fortsatt.
  • Eksisterende WP_Widget-baserte plugins vil fortsette å virke, men nye prosjekter bør vurderes blokk-først for fremtidssikkerhet.
  • Det er fullt mulig å tilby begge deler: en klassisk widget for eldre oppsett og en blokk for moderne nettsteder.

Forutsetninger Og Oppsett Av Miljø

Norwegian workspace showing wordpress and code editor for custom widget setup.

For å bygge en tilpasset widget trengs et fungerende WordPress-miljø (lokalt eller på en testserver), grunnleggende PHP-kunnskap, og mulighet til å redigere filer tryggt.

Verktøy, Krav Og Anbefalt Mappestruktur

  • Kodeeditor: VS Code, PhpStorm eller lignende.
  • PHP 7.4+ anbefales (følg kravene til din WP-versjon), samt Composer/Node hvis du lager blokker.
  • Nettleserutvidelser/pluginer for feilsøking (Query Monitor) og WP_DEBUG aktivert i utvikling.

Anbefalt plugin-struktur for klassisk eller hybrid løsning:

/wp-content/plugins/min-widget/

  • min-widget.php
  • /assets/
  • style.css
  • script.js

Eget Plugin Vs. Barnetema

  • Plugin: Funksjonaliteten lever videre ved temabytte, kan aktiveres/deaktiveres uavhengig og versjoneres.
  • Barnetema: Mister widgeten hvis tema byttes. Til ren funksjonalitet anbefales plugin-løsning.

Metode 1: Klassisk Widget Med WP_Widget

Den klassiske metoden er fremdeles robust, spesielt når du vil ha full kontroll og enkel kondisjonell lasting.

Opprette Plugin-Skjelett Og Registrere Widget

Opprett filen /wp-content/plugins/min-widget/min-widget.php med plugin-header og registrering:


<?php

/**
* Plugin Name: Min Widget
* Description: En enkel, tilpasset klassisk widget.
* Version: 1.0.0
* Author: Ditt Navn
* Text Domain: min-widget
*/


if (.defined('ABSPATH')) exit: // Sikkerhetsvakt


class Min_Widget extends WP_Widget {

public function __construct() {

parent::__construct(

'min_widget',

__('Min Widget', 'min-widget'),

['description' => __('En demonstrasjonswidget', 'min-widget')]

):

}


public function widget($args, $instance) {

echo $args['before_widget']:


$title = isset($instance['title']) ? $instance['title'] : '':

if (.empty($title)) {

echo $args['before_title'] . apply_filters('widget_title', esc_html($title)) . $args['after_title']:

}


// Selve innholdet

echo '<div class="min-widget">' . esc_html__('Innhold her', 'min-widget') . '</div>':


echo $args['after_widget']:

}


public function form($instance) {

$title = isset($instance['title']) ? $instance['title'] : '':

$field_id = $this->get_field_id('title'):

$field_name = $this->get_field_name('title'):

?>

<p>

<label for="<?php echo esc_attr($field_id): ?>"><?php esc_html_e('Tittel:', 'min-widget'): ?></label>

<input class="widefat" id="<?php echo esc_attr($field_id): ?>" name="<?php echo esc_attr($field_name): ?>" type="text" value="<?php echo esc_attr($title): ?>" />

</p>

<?php

}


public function update($new_instance, $old_instance) {

$instance = []:

$instance['title'] = isset($new_instance['title']) ? sanitize_text_field($new_instance['title']) : '':

return $instance:

}

}


add_action('widgets_init', function(){

register_widget('Min_Widget'):

}):

Aktiver pluginet i WordPress og legg widgeten til et widget-område.

Implementere widget(), form() Og update()

  • widget(): Lager front-end HTML. Bruk $args[‘before_widget’]/$args[‘after_widget’] og tittelmarkørene for korrekt tema-innramming.
  • form(): Viser felter i admin for hver instance. Husk unike ID-/name-attributter via get_field_id()/get_field_name().
  • update(): Valider og sanitér data før lagring. F.eks. sanitize_text_field for tekst.

Tips for flere felter: utvid $instance med egne nøkler (f.eks. «subtitle», «show_icon») og speil dem i form() og widget().

Sanitizing, Sikkerhet Og Oversettbarhet

  • Sanitér inndata i update() (sanitize_text_field, sanitize_url osv.).
  • Escap utdata i widget() (esc_html, esc_attr, wp_kses_post for begrenset HTML).
  • Oversettbare strenger med __(), _e() og et konsistent text domain.
  • Sikkerhet: Beskytt direkte filtilgang med if (.defined(‘ABSPATH’)) exit: og stol på WordPress’ egne capabilities for widget-lagring. Unngå å kjøre kostbare kall synkront: bruk caching eller transients ved behov.

Metode 2: Blokkbasert Widget Med Gutenberg

Blokkbaserte widgets gjør at samme blokk kan brukes i innhold og i widget-områder. Dette er anbefalt retning for nye prosjekter.

Opprette En Blokk Med @wordpress/create-block

Kjør i rotmappen (eller i /wp-content/plugins/):


npx @wordpress/create-block min-widget

Veiviseren oppretter et ferdig plugin med block.json, src/, build/ og nødvendige skript. Aktiver pluginet i admin og du får en ny blokk som også kan settes inn i «Utseende → Widgets».

Tilpass block.json (navn, beskrivelse, kategori) og rediger src/edit.js for redigeringsopplevelsen. Du kan legge inn attributter for tittel/innhold og bruke InspectorControls for paneler i sidebaren.

Dynamisk Rendering Og Bruk I Widget-Områder

Trenger blokken server-side innhold (API, brukerspesifikt, cache)? Bruk dynamisk rendering i PHP:


// I min-widget.php eller en inkluderingsfil

add_action('init', function() {

register_block_type(__DIR__ . '/build', [

'render_callback' => function($attributes, $content) {

$title = isset($attributes['title']) ? sanitize_text_field($attributes['title']) : '':

ob_start():

?>

<section class="min-widget-block" aria-label="<?php echo esc_attr($title ?: __('Widget', 'min-widget')): ?>">

<?php if ($title) : ?>

<h3><?php echo esc_html($title): ?></h3>

<?php endif: ?>

<div><?php echo wp_kses_post($content ?: __('Innhold her', 'min-widget')): ?></div>

</section>

<?php

return ob_get_clean():

}

]):

}):

Når denne blokken legges i et widget-område, rendres den på forsiden. Fordelen er samme redigeringsopplevelse på tvers av sider, innlegg og widget-områder. Bruk block.json-feltene «style» og «editorScript» for å få WordPress til å laste byggede ressurser kun når blokken brukes.

Styling, Skript, Tilgjengelighet Og Ytelse

Det er fristende å laste tunge CSS-rammeverk, men widgets bør være lette og raske.

Enqueue Bare Når Widgeten Er I Bruk

For klassiske widgets kan du enqueue i selve widget()-metoden, slik at stil/skript lastes kun når instansen faktisk vises:


public function widget($args, $instance) {

wp_enqueue_style('min-widget-style', plugins_url('assets/style.css', __FILE__), [], '1.0.0'):

// eventuelt wp_enqueue_script(...)

echo $args['before_widget']:

// ...

echo $args['after_widget']:

}

Alternativt, i wp_enqueue_scripts med betingelse:


add_action('wp_enqueue_scripts', function() {

if (is_active_widget(false, false, 'min_widget', true)) {

wp_enqueue_style('min-widget-style', plugins_url('assets/style.css', __FILE__), [], '1.0.0'):

}

}):

For blokker håndteres mye via block.json. Legg «style» til kompilerte CSS-filer: WordPress laster dem når blokken er i bruk.

Semantikk, Tilgjengelighet Og Lettvekts-CSS

  • Bruk semantiske elementer (section, h2–h4, nav, ul/li) og aria-label ved behov.
  • Kontrast og fokusstiler: Følg WCAG. Ikke fjern outline uten å erstatte den.
  • Animér forsiktig, og minifiser CSS. Unngå CSS som påvirker elementer utenfor widgetens container.
  • Test med tastaturnavigasjon og skjermleser der det er relevant.

Testing, Feilsøking Og Vedlikehold

Putt tid i stabilitet – det sparer timesvis senere.

WP_DEBUG, Logg Og Query Monitor

I wp-config.php under utvikling:


define('WP_DEBUG', true):

define('WP_DEBUG_LOG', true):

define('SCRIPT_DEBUG', true):

Se /wp-content/debug.log for PHP-varsler. Installer Query Monitor for å se hooks, SQL, deprecations og HTTP-kall i sanntid. Test i både blokk- og klassisk widgetgrensesnitt hvis nettstedet støtter begge.

Versjonering, Edge Cases Og Vedlikehold

  • Versjonér pluginet (SemVer) og dokumenter endringer i readme.
  • Test mot nye WordPress-versjoner før du oppdaterer produksjon.
  • Håndter edge cases: tom tittel, lange strenger, flere instanser i samme sidefelt, mangel på data (API-feil). Bruk caching/transients for dyre kall.
  • Behold bakoverkompatibilitet når mulig, og marker tydelig når minimumskrav endres.

Konklusjon

Det finnes to gode veier til en tilpasset widget i WordPress: den klassiske WP_Widget-metoden og den blokkbaserte Gutenberg-tilnærmingen. Begge kan leve parallelt, men for nye prosjekter er blokk-først som regel best – det gir en mer konsistent redigering og enklere gjenbruk. Uansett valg: legg funksjonaliteten i et plugin, sanitér og escap alt, last bare det som trengs, og test jevnlig. Da får nettstedet en widget som både ser riktig ut, yter godt og tåler fremtidige oppdateringer.

Ofte stilte spørsmål: Hvordan lage en tilpasset widget i WordPress

Hva er forskjellen mellom klassiske og blokkbaserte widgets i WordPress?

Klassiske widgets bygger på WP_Widget og administreres i det gamle widgetpanelet. Siden WordPress 5.8 er widget-områder blokkbaserte og bruker Gutenberg-blokker, men klassiske widgets støttes fortsatt for bakoverkompatibilitet. For nye prosjekter anbefales en blokk-først tilnærming, men du kan tilby begge for maksimal kompatibilitet.

Når bør jeg lage en tilpasset widget i WordPress i stedet for å bruke en ferdig løsning?

Lag en tilpasset widget i WordPress når ingen eksisterende plugin eller blokk dekker funksjon eller design, når du trenger spesiallogikk som API-kall, kondisjonell visning eller personalisering, eller når innholdet må ligge i et widget-område. For site-wide funksjon anbefales et eget plugin fremfor barnetema.

Hvordan lage en tilpasset widget i WordPress med WP_Widget?

Opprett et plugin (/wp-content/plugins/min-widget/), registrer klassen via register_widget, og implementer widget() for front-end HTML, form() for adminfelter og update() for validering og sanitering. Beskytt filer med ABSPATH-sjekk, escap utdata, aktiver pluginet og legg widgeten i et widget-område. Husk oversettbare strenger og versjonering.

Hvordan lager jeg en blokkbasert widget med Gutenberg?

Kjør npx @wordpress/create-block for å generere et plugin med block.json og src-filer. Tilpass edit-opplevelsen, og bruk register_block_type med render_callback ved dynamisk/brukerspesifikt innhold. Blokken kan brukes i Utseende → Widgets og sider. Definer style/editorScript i block.json, så lastes ressurser kun når blokken brukes.

Påvirker en tilpasset widget i WordPress Core Web Vitals, og hvordan optimaliserer jeg?

Ja. Hold CSS/JS lett og last dem bare når widgeten vises (is_active_widget eller block.json). Unngå render‑blocking, defer/inline kritisk CSS, og lazy‑load media. Cache dyre kall med transients/objektcache og vurder serverside‑rendering. Test med Lighthouse og Query Monitor for å finne flaskehalser.

Fungerer tilpassede widgets med sidebyggere og Full Site Editing?

Som regel, ja. WP_Widget‑baserte widgets vises i temaets widget‑områder, mens blokkbaserte widgets fungerer i både klassiske og blokktema samt Site Editor. Sidebyggere har egne «widgets», men kan ofte sameksistere. Test stilkollisjoner, navngi CSS‑klasser avgrenset, og prioriter blokker for FSE‑miljøer. Kontroller ytelse etter aktivering.