Relativt Formulär releasesself-updates
Ett formulärplugin för Wordpress
by Relativt · github.com/relativtwebb/relativt-formular · website
Install
The author publishes release zips, so WP-CLI can install straight from GitHub:
wp plugin install https://github.com/relativtwebb/relativt-formular/releases/download/v1.2.0/relativt-formular-1.2.0.zipShips its own WordPress updater (built-in updater), so new versions show up under Dashboard → Updates.
Readme
Relativt Formulär
Formulärmotor för WordPress. Bygg formulär i wp-admin, varje formulär får en egen shortcode.
Byggd för byråarbete: samma motor på flera kundsajter, formulär som kan flyttas mellan projekt, och en kund som klarar att ändra i sina egna fält utan att höra av sig.
Vad den gör
- Formulärbyggare i wp-admin. Fält läggs till, döps om och sorteras genom att dra. Varje formulär får en shortcode.
- Villkorliga fält som utvärderas på servern. Ett fält som inte ska synas renderas dolt direkt i HTML:en — det behöver alltså inte JavaScript för att göra rätt, och en besökare med skript avstängt ser samma formulär som alla andra.
- Mottagarregler. Skicka till olika adresser beroende på vad besökaren svarat. Regler får skrivas med antingen etiketten eller det tekniska värdet — båda träffar.
- Validering av e-post, telefon och URL, spegelvänd mellan PHP och JavaScript så klienten och servern aldrig är oense. Svenska nummer normaliseras till ett format, internationella släpps igenom. URL:er normaliseras med
https://om schemat saknas, så länken alltid går att klicka på i mailet. - Spamskydd utan CAPTCHA: honungsfälla, HMAC-signerad tidsstämpel med minsta tid, frekvensspärr per IP och länkspärr i textrutor.
- UTM-attribution via förstapartskaka, så att inskicket bär med sig vilken kampanj besökaren kom ifrån. Finns Relativt Cookie Consent på sajten skrivs kakan först när besökaren samtyckt – se Kampanjkakan och samtycke.
- Inskickslagring med konfigurerbar gallring och CSV-export.
- Export och import av formulärdefinitioner som JSON.
Krav
- WordPress 6.0 eller senare
- PHP 8.0 eller senare
- Advanced Custom Fields Pro — formulärbyggaren är byggd på repeater-fältet, som bara finns i Pro
Saknas ACF Pro startar motorn ändå, så att posttyper, sparade formulär och inskick förblir åtkomliga, men byggaren visas inte och ett tydligt meddelande förklarar varför.
Installation
Ladda ner senaste zip-filen under Releases, installera under Insticksprogram → Lägg till → Ladda upp, aktivera.
Uppdateringar dyker sedan upp som vanligt under Insticksprogram så fort en ny release taggas här.
Användning
Skapa ett formulär under Formulär → Skapa nytt, bygg fälten, publicera. Kopiera shortcoden:
[relativt_formular id="123"]
Förvälja ett värde per sida
Alla shortcode-attribut som matchar en fältnyckel blir förvalt värde. Ligger samma formulär på två sidor kan de alltså börja i olika lägen:
[relativt_formular id="123" jag_ar="foretag"]
[relativt_formular id="123" jag_ar="kandidat"]
Villkorliga fält rättar sig efter förvalet redan vid renderingen.
Shortcoden tar också ett class-attribut som lägger egna klasser på formulärets rot – se Olika utseende per formulär.
Tack-sida i stället för tack-rutan
Fyll i Tack-sida (URL) under formulärets flik Texter – t.ex. /tack/ – så skickas besökaren dit efter lyckat inskick, i stället för att tack-rutan visas. Under Formulär → Standardvärden kan en gemensam tack-sida sättas för hela sajten; formulärets eget värde vinner alltid.
Det här är rätt upplägg för konverteringsspårning: gör tack-sidan till mål i GA4 eller Google Ads, så behövs ingen event-koppling alls. Eventet relativt-form:success sänds visserligen även vid omdirigering (se Event), men en event-baserad spårning hinner sällan iväg innan sidbytet – på sajter med tack-sida hör spårningen hemma på själva tack-sidan.
Styla formuläret
Motorn levererar neutral markup, och pluginets CSS är ett golv – inte ett tak. Ingen utseende-regel använder !important och inga typografiska tyckanden (versaler, letter-spacing) ligger i vägen: formuläret ärver sajtens typografi, och sajtens CSS vinner med vanlig specificitet. De enda !important som finns är funktionsregler som aldrig ska stylas – honungsfällans döljning, villkorsdolda fält och builder-läget.
Det finns tre nivåer, från minst till mest arbete. Gemensamt för alla: redigera aldrig pluginets egna filer. De skrivs över vid varje uppdatering, så en färg som ändrats direkt i assets/css/relativt-formular.css försvinner nästa gång en release rullas ut.
Nivå 1: skriv över variablerna (räcker nästan alltid)
Allt utseende – färger, luft, rundning, storlekar – styrs av CSS-variabler på .relativt-form. Skriv över dem från sajtens egen CSS (Oxygens stylesheet, child-temat, eller Utseende → Anpassa → Ytterligare CSS). Den dubblade klassen gör att sajtens värden alltid vinner över pluginets standard, oavsett i vilken ordning filerna råkar laddas:
.relativt-form.relativt-form {
--xf-accent: #0a3d62; /* knappens bakgrund */
--xf-accent-text: #ffffff; /* knappens text och ikon */
--xf-field-bg: #f0f4f8; /* fältens bakgrund */
--xf-radius: 8px; /* rundning på fält och knapp */
}
Typsnittet behöver aldrig sättas – formuläret ärver alltid sajtens (font-family: inherit rakt igenom).
| Variabel | Standard | Styr |
|---|---|---|
--xf-gap |
20px |
avstånd mellan kolumner, val-knappar |
--xf-gap-row |
22px |
avstånd mellan rader |
--xf-radius |
2px |
rundning på fält och knapp |
--xf-field-bg |
#f5f5f4 |
fältens bakgrund |
--xf-field-bg-focus |
#efeeec |
fältens bakgrund vid hover/fokus |
--xf-field-pad-y / --xf-field-pad-x |
16px / 18px |
fältens inre luft |
--xf-text |
#2b2a28 |
text i fälten |
--xf-placeholder |
#b6b4b0 |
platshållartext |
--xf-label |
#2b2a28 |
etiketternas färg |
--xf-label-size |
13px |
etiketternas storlek |
--xf-input-size |
16px |
textstorlek i fälten och på knappen |
--xf-active-bg / --xf-active-text |
#2b2a28 / #fff |
vald val-knapp |
--xf-accent / --xf-accent-text |
#2b2a28 / #fff |
skicka-knappen |
--xf-icon-size |
22px |
pilikonen i knappen |
--xf-error |
#b32d2e |
felmeddelanden |
--xf-focus-ring |
#2b2a28 |
fokusram |
Typografin är medvetet neutral – ingen text-transform, ingen letter-spacing. Vill sajten ha versala etiketter läggs det till på samma sätt: .relativt-form.relativt-form .xf-label { text-transform: uppercase; letter-spacing: .08em; }. Skicka-knappen är innehållsbred på desktop och full bredd under 768px; ska den alltid vara full bredd: .relativt-form.relativt-form .xf-submit { width: 100%; }. Brytpunkten (768px) är däremot ingen variabel – CSS kan inte läsa variabler i media-frågor.
Olika utseende per formulär
Grunden sätts en gång; en variant skriver bara över de variabler som skiljer. Tre sätt att peka ut vilket formulär som avviker:
Per formulär, via id. Roten bär alltid formulärets id som data-xf-form, så ett enskilt formulär kan stylas utan något förarbete:
.relativt-form[data-xf-form="123"] { --xf-accent: #7a1f1f; }
Per placering eller som namngiven variant, via shortcoden. class-attributet lägger egna klasser på roten – samma formulär kan se olika ut på två sidor, och varianten följer med om formuläret exporteras till en annan sajt (till skillnad från id:t, som blir nytt vid import):
[relativt_formular id="123" class="form--mork"]
.relativt-form.form--mork {
--xf-field-bg: #2b2a28;
--xf-text: #ffffff;
--xf-placeholder: #8b8985;
}
Per formulär, i knappfiltren. Filtren får formulärets id som andra argument:
add_filter( 'relativt_form_submit_class', fn( $c, $form_id ) =>
123 === $form_id ? trim( "$c btn-secondary" ) : $c, 10, 2 );
Nivå 2: låt knappen ärva temats utseende
På en sidbyggarsajt vill man ofta att skicka-knappen ska se ut och animeras exakt som temats övriga knappar. Skjut in temats klasser via filtren (exempel under Filter nedan). Krockar pluginets egen knappstyling med temats – t.ex. paddingen eller bakgrunden – skrivs den över från sajtens CSS med dubblad klass, i stället för att röra pluginfilen:
.relativt-form .xf-submit.xf-submit { padding: 14px 24px; background: none; }
Nivå 3: stäng av pluginets CSS och styla allt själv
add_filter( 'relativt_form_enqueue_css', '__return_false' );
Då levererar pluginet bara markup, och sajten stylar mot klasserna: .xf-grid, .xf-field (--full/--half), .xf-label, .xf-input, .xf-textarea, .xf-select, .xf-buttons med .xf-choice-label, .xf-radios, .xf-checks/.xf-check, .xf-help, .xf-error, .xf-form-error, .xf-actions/.xf-submit, .xf-consent, .xf-thanks.
Tre saker MÅSTE sajtens CSS då ta ansvar för, eftersom de annars låg i stilmallen som stängdes av:
- Honungsfällan.
.xf-hpmåste flyttas ut ur synfältet (position absolut utanför skärmen – intedisplay: none, en del bottar hoppar över helt dolda fält). Syns den fyller riktiga besökare i den, och deras inskick tystas som spam. - Villkorsdolda fält. Sätter sajten
displaypå.xf-fieldslår det ut webbläsarens inbyggda döljning av[hidden]– lägg till.xf-field[hidden] { display: none !important; }, annars syns fält som villkoren skulle dölja. - Tack-rutan och formuläret. Samma sak där:
.xf-form[hidden], .xf-thanks[hidden] { display: none !important; }.
Filter
Motorn levererar neutral markup som fungerar i vilket tema som helst. Vill sajten att knappen ska ärva sitt eget utseende skjuter den in sina klasser:
// Oxygen: temats knappanimation letar efter just de här klasserna.
add_filter( 'relativt_form_submit_class', fn( $c ) => trim( "$c btn" ) );
add_filter( 'relativt_form_submit_text_class', fn( $c ) => trim( "$c ct-text-block" ) );
add_filter( 'relativt_form_submit_icon_class', fn( $c ) => trim( "$c ct-fancy-icon" ) );
| Filter | Standard | Gör |
|---|---|---|
relativt_form_enqueue_css |
true |
Sätt false om sajten stylar formuläret själv |
relativt_form_always_enqueue |
true |
Sätt false för att bara ladda på sidor som faktiskt renderar shortcoden |
relativt_form_submit_class |
'' |
Extra klasser på knappen |
relativt_form_submit_text_class |
'' |
Extra klasser på knapptexten |
relativt_form_submit_icon_class |
'' |
Extra klasser på ikonen |
relativt_form_submit_icon |
pil höger | Byt ikonens SVG, eller returnera '' för ingen ikon |
relativt_form_messages |
svenska texter | Byt besökartexterna (felmeddelanden m.m.). Samma lista driver PHP och JS |
relativt_form_max_links |
3 |
Max antal länkar i en textruta innan inskicket avvisas. 0 stänger av |
relativt_form_utm_cookie |
'auto' |
Kampanjkakans samtyckesläge: auto, always eller never |
relativt_form_client_ip |
REMOTE_ADDR |
Peka ut besökarens riktiga IP bakom proxy/CDN |
Om relativt_form_client_ip: bakom Cloudflare eller annan proxy är REMOTE_ADDR proxyns adress – då delar alla besökare samma frekvensspärr (fem inskick per tio minuter för hela sajten) och IP-loggen blir meningslös. På en Cloudflare-sajt:
add_filter( 'relativt_form_client_ip', fn( $ip ) => $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $ip );
Filtrera aldrig in X-Forwarded-For rakt av på en sajt utan betrodd proxy – den headern kan vem som helst skicka, och då väljer spammaren sin egen frekvensspärr.
Om relativt_form_messages: för en engelskspråkig kundsajt räcker det att byta texterna – inga språkfiler:
add_filter( 'relativt_form_messages', fn( $m ) => array_merge( $m, [
'required' => 'This field is required.',
'email' => 'Please check the email address.',
] ) );
Om always_enqueue: standard är att ladda överallt. Renderas formuläret i en modal som byggs i sidfoten — vilket är fallet i de flesta sidbyggare — hinner en villkorlig laddning inte med, och stilmallen skulle hamna efter sidan ritats. Vet sajten att formuläret bara finns i innehållet går det att stänga av.
Kampanjkakan och samtycke
Attributionen sparas i förstapartskakan xf_src (90 dagar): UTM-parametrar, gclid/fbclid, landningssida och hänvisande sida. Den är inte nödvändig för att formuläret ska fungera, så den lyder under samtyckesreglerna – ta med den i sajtens cookie-policy.
Läget styrs av filtret relativt_form_utm_cookie:
auto(standard). Är Relativt Cookie Consent aktivt på sajten skrivs kakan först när besökaren godkänt statistik eller marknadsföring, tas bort om samtycket dras tillbaka, och skrivs i efterhand om samtycket kommer senare på sidan (motorn lyssnar pårcc_consent_updated). Utan samtyckesverktyg skrivs kakan direkt – då är det sajtens ansvar att dokumentera den.always. Skriv alltid. För sajter som hanterar samtycket på annat håll, t.ex. genom att blockera skriptet tills samtycke finns.never. Skriv aldrig. Attributionen lever då bara i minnet, så den följer med inskick från landningssidan men inte mellan sidladdningar.
Innan samtycket är avgjort hålls attributionen i minnet: landar besökaren på kampanjsidan och skickar formuläret där följer kampanjen med i inskicket även utan kaka.
Event
Vid lyckat inskick sänds ett event på document, så spårning kan hängas på utan att bakas in i motorn:
document.addEventListener('relativt-form:success', function (e) {
// e.detail.formId — formulärets id
// e.detail.root — formulärets rot-element
});
Flytta ett formulär mellan sajter
Formulär → hovra över formuläret → Exportera JSON. På den nya sajten: Formulär → Importera.
Formuläret skapas som utkast med en ny shortcode. Ingenting skrivs över.
Importen läser aldrig in fältnamn rakt av — allt passerar en vitlista, och det som inte står i den kastas. Exporten innehåller bara definitionen, aldrig inskicken: de är personuppgifter och hör hemma i CSV-exporten.
Kontrollera alltid mottagaradresserna efter en import. De följer med från sajten filen kom ifrån.
Read the full README on GitHub →
Releases
| Tag | Published | Asset | Downloads |
|---|---|---|---|
| v1.2.0 | Sep 9, 2026 | relativt-formular-1.2.0.zip | 3 |
| v1.1.3 | Sep 3, 2026 | relativt-formular-1.1.3.zip | 3 |
| v1.1.2 | Sep 2, 2026 | relativt-formular-1.1.2.zip | 1 |
| v1.1.1 | Sep 2, 2026 | relativt-formular-1.1.1.zip | 2 |
| v1.1.0 | Aug 31, 2026 | relativt-formular-1.1.0.zip | 2 |
| v1.0.0 | Aug 27, 2026 | relativt-formular-1.0.0.zip | 1 |