FaceFlow Components

Reusable business blocks with schema-driven fields, Facet templates, scoped styles, and optional runtime behavior.

Documentatie voor componentontwikkelaars

Componenten zijn schema-gestuurde website-secties die via FaceFlow worden gerenderd.

Voor technische gebruikers zijn componenten het kerncontract voor herbruikbare secties in het systeem. Ze combineren velddefinities, Facet-templateoutput, optionele styling, client-side gedrag en scope-bewust hergebruik.

Kernverantwoordelijkheid

Een component is verantwoordelijk voor:

  • het definiëren van een herbruikbaar sectiecontract
  • het beschikbaar maken van een gecontroleerd authoring-schema
  • het renderen van output via Facet
  • optioneel koppelen van scope-bewuste stijlen en gedrag
  • ondersteuning van hergebruik op pagina-, layout- of site-niveau

Componenten moeten herhaalbare sectieproblemen oplossen. Ze moeten geen losse containers worden voor willekeurige paginaspecifieke opmaak.

Model voor componentdefinitie

Een typische componentdefinitie omvat:

{
  "name": "contact-section",
  "title": "Contact Section",
  "version": "1.0.0",
  "type": "component",
  "category": "contact",
  "defaultScope": "page",
  "description": "Contact section with CTA and embedded form support",
  "fields": [
    { "name": "title", "label": "Title", "type": "text" },
    { "name": "summary", "label": "Summary", "type": "textarea" },
    { "name": "contactForm", "label": "Form", "type": "formSelect" }
  ],
  "html": "<section><h2>{{ title }}</h2><p>{{ summary }}</p><div data-form-embed=\"{contactForm}\"></div></section>",
  "style": ".contact-section { padding: 4rem 0; }",
  "script": "/* optional behavior */"
}

Dit model maakt het mogelijk dat een component functioneert als een beheerd sectiecontract in plaats van een los fragment gekopieerde code.

Kernmetadata

Belangrijke metadata-velden zijn onder meer:

  • name
  • title
  • version
  • type
  • category
  • defaultScope
  • description

Richtlijnen:

  • houd name stabiel na release
  • gebruik title voor duidelijkheid in de editor
  • werk version doelbewust bij wanneer het schema of het rendergedrag verandert
  • kies defaultScope op basis van verwacht hergebruik, niet op basis van gemak

Veldschema

Het veldschema bepaalt wat auteurs kunnen wijzigen zonder de structuur van de sectie te veranderen.

Ondersteunde top-level veldtypen zijn onder meer:

  • text
  • textarea
  • number
  • url
  • date
  • image
  • images
  • file
  • select
  • checkbox
  • richtext
  • htmlcode
  • map
  • repeater
  • formSelect
  • reviewSelect

Aanvullende subveldtypen kunnen binnen repeater worden gebruikt, waaronder:

  • color
  • email
  • tel
  • range

Voorbeeld:

{
  "name": "faqItems",
  "label": "FAQ Items",
  "type": "repeater",
  "fields": [
    { "name": "question", "type": "text" },
    { "name": "answer", "type": "textarea" }
  ]
}

Kies veldtypen op basis van de inhoudsintentie, niet op basis van gemak. Een url moet een URL blijven. Een herhaald kaartenset moet een repeater zijn, geen meerdere niet-gerelateerde tekstvelden.

Zie de volledige veldreferentie:

Sjabloonmodel

Het html-gedeelte van een component wordt gerenderd via Facet.

Dat betekent dat sjablonen kunnen gebruiken:

  • velduitvoer
  • condities
  • lussen
  • filters
  • pagina-bewuste context
  • herbruikbare Variabelen

Voorbeeld:

<section class="hero-section">
  <div class="container">
    <h1>{{ title }}</h1>

    {{#if summary}}
      <p>{{ summary }}</p>
    {{/if}}

    {{#if ctaUrl}}
      <a href="{{ ctaUrl }}" class="btn-primary">{{ ctaLabel }}</a>
    {{/if}}
  </div>
</section>

Of met een repeater:

<div class="faq-list">
  {{#each faqItems as="item"}}
    <article class="faq-item">
      <h3>{{ item.question }}</h3>
      <p>{{ item.answer }}</p>
    </article>
  {{/each}}
</div>

Voor syntaxisdetails:

Scopemodel

Componenten kunnen bestaan op drie hergebruiksniveaus:

  • site
  • layout
  • page

Conceptueel:

site scope   -> reusable across the broader site
layout scope -> shared inside one page family
page scope   -> local to one page

Scope bepaalt zowel zichtbaarheid als de impact van wijzigingen. Als een component verandert op site-scope, is dat een brede architecturale wijziging, geen lokale aanpassing.

Voor het bredere model:

Rendergedrag

Tijdens het renderen lost FaceFlow de componentinstantie op door het combineren van:

  • de componentdefinitie
  • opgeslagen veldwaarden
  • de huidige rendercontext
  • gerelateerde runtime-services zoals media, Variabelen, Formulieren en Reviews

Conceptueel:

component definition
  + saved field values
  + runtime context
  -> Facet render
  -> final section output

Dit is het punt waarop veldgegevens runtime-markup worden.

Stijlen en gedrag

Componenten kunnen optioneel stijlen en optioneel gedrag toevoegen.

Voorbeeld:

.pricing-card {
  border-radius: 1rem;
  padding: 2rem;
}
document.querySelectorAll('.faq-item button').forEach((button) => {
  button.addEventListener('click', () => {
    button.closest('.faq-item').classList.toggle('is-open');
  });
});

Gebruik dit spaarzaam. Het gedrag van de meeste secties moet eenvoudig, voorspelbaar en gemakkelijk te onderhouden blijven.

Formulieren en reviews binnen componenten

Twee veldtypen zijn vooral belangrijk voor interactieve secties:

  • formSelect
  • reviewSelect

Deze stellen componenten in staat bedrijfsworkflows in te sluiten zonder één specifiek model hard te coderen.

Typische markers:

<div data-form-embed="{contactForm}"></div>
<div data-review-embed="{serviceReview}"></div>

Dit houdt de sectie herbruikbaar terwijl het geselecteerde formulier- of reviewmodel kan worden gewijzigd tijdens het bewerken door auteurs.

Voorbeeldpatronen voor componenten

Basic content section:

fields:
  title
  summary
template:
  heading + paragraph

FAQ section:

fields:
  faqItems repeater
template:
  each item -> question + answer

Lead capture section:

fields:
  title
  summary
  contactForm (formSelect)
template:
  copy + data-form-embed marker

Technische beoordelingschecklist

  • Lost de component één herhaalbaar sectieprobleem op?
  • Is het veldschema duidelijk en doelbewust?
  • Is het sjabloon leesbaar en stabiel?
  • Is de gekozen scope correct voor het verwachte hergebruik?
  • Zou een toekomstige redacteur begrijpen hoe het te gebruiken op basis van alleen het veldcontract?

Anti-patronen

Vermijd:

  • het overladen van één component met niet-gerelateerde gebruiksscenario's
  • het toevoegen van paginaspecifieke bedrijfslogica die buiten het sectiecontract zou moeten blijven
  • het gebruik van htmlcode wanneer een gestructureerd veldmodel veiliger zou zijn
  • de scope verruimen alleen omdat de sectie mogelijk ooit hergebruikt wordt
  • velden hernoemen nadat er al content aan gekoppeld is

Wanneer een component opgesplitst moet worden

Splits een component wanneer:

  • het veldschema te breed is geworden
  • meerdere lay-outs of pagina-contexten conflicterende versies nodig hebben
  • het sjabloon vol zit met uitzonderingen en eenmalige vertakkingen
  • redacteuren niet meer begrijpen wat de sectie zou moeten doen

Als het contract onduidelijk raakt, wordt hergebruik meestal minder waardevol.

Gerelateerd