Skip to content

Sessie 13 november 2025: Users, Profielen en MailChimp

Context

Na de succesvolle Commerce setup (producten, checkout, betaling, facturen) verschuiven we focus naar gebruikersbeheer. De site is een medisch vaktijdschrift/platform waar juridische compliance belangrijk is. We moeten bij registratie al professionele gegevens verzamelen.

Architectuur Beslissing: Twee Profielen

Na analyse gekozen voor twee gescheiden profielen:

1. Customer Profiel (Privé)

Doel: Commerce transacties + professionele verificatie
Zichtbaarheid: Alleen gebruiker zelf + admins
Wanneer: Bij registratie (verplicht)

Velden: - Adresgegevens: - Adres (verplicht, address field - NL/BE/EU) - Telefoonnummer (telephone field)

  • Beroepsgegevens (Field Group):
  • Beroep (verplicht, list):
    • Therapeut
    • Diëtist
    • Leefstijlcoach
    • Arts
    • Onderzoeker
    • Student → toont "Opleiding" veld (conditional)
    • Anders, namelijk → toont tekstveld (conditional)
  • Opleiding (string, conditional bij Student)
  • Anders-veld (string, conditional bij Anders)
  • BIG-nummer (string, optioneel)
  • Lid van beroepsvereniging (string, optioneel)*
  • Bedrijfsnaam (string, optioneel - zakelijk)
  • KVK-nummer (string, optioneel - zakelijk)
  • BTW-nummer (commerce_tax_number, optioneel - zakelijk)
  • Website praktijk (link, optioneel)

  • Nieuwsbrief:

  • Nieuwsbrief ontvangen (boolean, checkbox)

*Wordt volgende week vervangen door entity_reference naar ECK Beroepsvereniging

2. Openbaar Profiel (Publiek)

Doel: Community, netwerken tussen professionals
Zichtbaarheid: Alle ingelogde gebruikers
Wanneer: Optioneel, na registratie

Velden: - Weergavenaam (string, verplicht - kan pseudoniem zijn) - Over mij (text_long, optioneel - bio) - Beroep (list, gedeeld met customer profiel) - Website (link, gedeeld met customer profiel)

Toekomstige uitbreiding: - Profielfoto (image) - Locatie/regio (geospatial of text) - Specialisaties/interesses (taxonomy)

Registratie Flow

Voor deze setup (oude site → nieuwe site migratie):

  • Users moeten zich opnieuw aanmelden
  • Voordeel: schone user database
  • Nadeel: mogelijk gebruikersverlies
  • Mitigatie: duidelijke communicatie, simpel registratieproces

Configuratie:

user.settings:
  register: visitors              # Was: visitors_admin_approval
  verify_mail: true               # Email verificatie actief
  password_strength: true         # Sterke wachtwoorden verplicht

profile.type.customer:
  registration: true              # Profiel bij registratie
  multiple: false                 # Eén profiel per user

profile.type.openbaar:
  registration: false             # Optioneel, na registratie
  multiple: false

Spam Protection:

  • Honeypot module (enabled): Onzichtbare velden voor bots
  • Email verificatie: Verplichte bevestigingsmail
  • Password strength: Drupal core validatie
  • Rate limiting: Drupal core (geen aparte config nodig)

MailChimp Integratie

Modules:

  • mailchimp 3.1.3
  • mailchimp_lists (Audiences)
  • mailchimp_signup (Forms)
  • mailchimp_events (Webhooks)
  • mailchimp_campaign

API Configuratie:

mailchimp.settings:
  api_key: '[OPGESLAGEN IN PASSWORD MANAGER]'
  use_oauth: false               # Klassieke API key methode
  domain: nieuw.voedingsgeneeskunde.nl
  test_mode: false
  webhook_hash: e64fc24e1027ae0a5c4130de188fadf5

API Key naam: "Voedingsgeneeskunde website dev en live vanaf 2025"
Locatie: MailChimp account (gedeeld voor dev + live)

Audiences:

Test (DEV): "Voedingsgeneeskunde d8dev Test" (bestaande test lijst)
Live: "Voedingsgeneeskunde Platform" (16.404 leden)

Signup Form (bestaand op DEV):

  • Naam: "Nieuwsbrief test"
  • Type: Block
  • Mode: Subscription met double opt-in
  • Merge fields: EMAIL, FNAME, MMERGE3 (test veld)

Webhooks:

DEV: 0 enabled (geen two-way sync voor testing)
Live: 6 enabled (two-way sync: unsubscribes, email changes)

Webhook URL (live):
https://voedingsgeneeskunde.nl/mailchimp/webhook

Conditional Fields

Gebruikt Conditional Fields module 4.0.0-alpha6.

Dependencies:

  1. field_student_instelling
  2. Control: field_beroep
  3. State: Zichtbaar
  4. Condition: heeft waarde "student"

  5. field_beroep_anders

  6. Control: field_beroep
  7. State: Zichtbaar
  8. Condition: heeft waarde "anders"

Configuratie locatie:
/admin/structure/conditional_fields/profile/customer

Display Configuratie

Customer Profiel - Formulier weergave:

Volgorde: 1. Adres (weight: 0) 2. Telefoonnummer (weight: 1) 3. Nieuwsbrief ontvangen (weight: 2) 4. Beroepsgegevens (Field Group - Details/Fieldset): - Beroep - Opleiding (conditional) - Anders, namelijk (conditional) - BIG-nummer - Lid van beroepsvereniging - Bedrijfsnaam - KVK-nummer - BTW-nummer - Website praktijk

Customer Profiel - Weergave:

Zichtbaar (publiek binnen profiel): - Beroep (inclusief conditional velden) - Website praktijk - Bedrijfsnaam - Lid van beroepsvereniging - Opleiding (indien student)

Verborgen (privé): - Adres (Disabled in display) - Telefoonnummer (Disabled) - BTW-nummer (Disabled) - KVK-nummer (Disabled) - BIG-nummer (Disabled) - Nieuwsbrief opt-in (Disabled - backend gebruik)

Technical Implementation

Velden aangemaakt via Drush:

# Telefoonnummer
ddrush field:create profile customer \
  --field-name=field_telefoon \
  --field-type=telephone

# Nieuwsbrief
ddrush field:create profile customer \
  --field-name=field_nieuwsbrief \
  --field-type=boolean

# Website praktijk
ddrush field:create profile customer \
  --field-name=field_website_praktijk \
  --field-type=link

# Beroep (via PHP script - complex allowed_values)
# Student instelling, Anders-veld, BIG-nummer, 
# Beroepsvereniging, Bedrijfsnaam, KVK-nummer
# Allemaal string fields

Beroep Field Storage:

FieldStorageConfig::create([
  'field_name' => 'field_beroep',
  'entity_type' => 'profile',
  'type' => 'list_string',
  'settings' => [
    'allowed_values' => [
      'therapeut' => 'Therapeut',
      'dietist' => 'Diëtist',
      'leefstijlcoach' => 'Leefstijlcoach',
      'arts' => 'Arts',
      'onderzoeker' => 'Onderzoeker',
      'student' => 'Student',
      'anders' => 'Anders, namelijk',
    ],
  ],
]);

Openbaar Profiel Type:

ProfileType::create([
  'id' => 'openbaar',
  'label' => 'Openbaar profiel',
  'display_label' => 'Openbaar profiel',
  'multiple' => false,
  'registration' => false,
]);

Shared Fields:

Beroep en Website velden delen dezelfde field storage tussen customer en openbaar profiel:

FieldConfig::create([
  'field_name' => 'field_beroep',  // Shared storage
  'entity_type' => 'profile',
  'bundle' => 'openbaar',
  'required' => false,
]);

Data Types Keuzes

Waarom string voor nummers?

KVK-nummer, BIG-nummer, telefoonnummer zijn allemaal string type, NIET integer:

  1. Leading zeros: KVK kan beginnen met 0 (bijv. 01234567)
  2. Formatting: Geen numerieke formatting gewenst
  3. Geen berekeningen: Het zijn identifiers, geen getallen
  4. Validatie: String met pattern validator is flexibeler

Integer/number fields alleen voor: - Hoeveelheden - Prijzen (decimal/float) - Scores, ratings

Domain/URL Situatie

Huidige setup: - Oude site: voedingsgeneeskunde.nl (blijft bestaan tijdens transitie) - Nieuwe live site: nieuw.voedingsgeneeskunde.nl (al in gebruik) - Development: dev.voedingsgeneeskunde.nl

Volgende week (geplande migratie): - voedingsgeneeskunde.nl → nieuwe site wordt primair domein - nieuw.voedingsgeneeskunde.nl → redirect naar hoofddomein - oud.voedingsgeneeskunde.nl → oude site (archief/fallback)

Impact op MailChimp: - API key blijft werken (niet domein-afhankelijk) - Webhook URL moet worden aangepast in MailChimp dashboard - Confirmation emails bevatten $base_url (automatisch correct na domeinwissel) - mailchimp.settings.domain moet worden aangepast in config

Beroepsverenigingen Lijst

Complete lijst voor ECK entities (volgende week op live aan te maken):

  • MBOG – Maatschappij ter Bevordering van de Orthomoleculaire Geneeskunde
  • AVIG – Artsenvereniging Integrale Geneeskunde
  • LVNT – Landelijke Vereniging Natuurgeneeskundig Therapeuten
  • VBAG – Vereniging ter Bevordering van Alternatieve Geneeswijze
  • CAT – Collectief Alternatieve Therapeuten
  • BATC – Beroepsorganisatie voor Alternatieve Therapeuten en Coaches
  • NWP – Nederlandse Werkgroep Praktizijns Natuurlijke Geneeswijzen
  • RBCZ – Register Beroepsbeoefenaren Complementaire Zorg
  • Vereniging Arts & Leefstijl
  • NVD – Nederlandse Vereniging van Diëtisten
  • BGN – Beroepsvereniging Gewichtsconsulenten Nederland
  • NAV – Nederlandse Academie van Voedingswetenschappen

Status Einde Sessie

Voltooid

  • Customer profiel velden volledig uitgebreid
  • Beroepslijst geïmplementeerd met conditionals
  • Field Groups geconfigureerd
  • Conditional Fields werkend (Student/Anders)
  • Registratie flow aangepast (zelf-registratie + email verificatie)
  • Display configuratie customer profiel (privé velden verborgen)
  • Openbaar profiel type aangemaakt met basis velden
  • MailChimp API key geconfigureerd en getest
  • Honeypot spam protection actief

Volgende Sessie

  • MailChimp ECA regel (nieuwsbrief sync bij registratie)
  • Openbaar profiel form/display configuratie afmaken
  • User dashboard views (mijn bestellingen, mijn facturen)
  • Profielfoto toevoegen aan openbaar profiel
  • Label wijzigen: "Onderwijsinstelling" → "Opleiding"
  • Field validatie (KVK 8 cijfers, BIG 11 cijfers)
  • Test registratie flow end-to-end

Voor Live Deployment (volgende week)

  • ECK Beroepsvereniging entities aanmaken op live site (12 verenigingen, zie lijst hierboven)
  • field_beroepsvereniging wijzigen van string naar entity_reference
  • MailChimp webhook URL aanpassen na domeinwissel
  • MailChimp audience wijzigen van test naar "Voedingsgeneeskunde Platform"
  • Webhooks op 6 enabled zetten (two-way sync)
  • $base_url aanpassen in settings.php
  • Config export en import naar live
  • Test volledige registratie flow op live

Belangrijke Notities

Juridische Compliance

Customer profiel verzamelt medische/professionele gegevens bij registratie voor: - Verificatie (BIG-register check mogelijk) - Content personalisatie (beroep-specifieke artikelen) - Segmentatie (MailChimp tags op basis van beroep) - Compliance met medische publicatie-eisen

Privacy (AVG/GDPR)

  • Customer profiel: privé, alleen user + admins
  • Openbaar profiel: expliciet opt-in, user controleert wat zichtbaar is
  • BTW-nummers: profile_private: true (veld setting)
  • MailChimp: double opt-in voor nieuwsbrief

Beroepsvereniging → Entity Reference

Nu: Vrij tekstveld (inconsistent)
Straks: Dropdown met officiële verenigingen

Voordelen: - Consistent, geen typefouten - Rapportage mogelijk (hoeveel NVDA-leden?) - Extra info mogelijk (website, logo, kortingscodes?) - Automatische updates als vereniging wijzigt

Migratie strategie: 1. Op live: ECK Beroepsvereniging entities aanmaken 2. Oude tekstvelden matchen met nieuwe entities (via migrate/script) 3. Veld type wijzigen: string → entity_reference 4. Old data cleanup

Checkout Gedrag

Bij checkout gebruikt Commerce het bestaande customer profiel: - Alle velden zijn al ingevuld (bij registratie gedaan) - User kan wijzigen/aanvullen indien nodig - BTW-nummer: Optioneel bij registratie, alsnog invulbaar bij checkout - Verzendadres: "Verzenden naar ander adres" checkbox toont extra adresveld

Fysieke producten (Los nummer, Uitgave, Merchandise) tonen verzendadres optie.
Digitale producten (Tickets, E-books, Abonnementen) gebruiken alleen factuuradres.

Commands Reference

Registratie instellingen wijzigen:

# Zelf-registratie aanzetten
ddrush config:set user.settings register visitors -y

# Customer profiel bij registratie
ddrush config:set profile.type.customer registration true -y

MailChimp configuratie:

# OAuth uitzetten
ddrush config:set mailchimp.settings use_oauth false -y

# API key instellen (interactief, veilig)
read -sp "API key: " KEY && \
  ddrush config:set mailchimp.settings api_key "$KEY" -y && \
  unset KEY

Velden info:

# Overzicht customer profiel velden
ddrush field:info profile customer

# Conditional fields routes
/admin/structure/conditional_fields/profile/customer

# Form display
/admin/config/people/profile-types  Klant  Formulier weergave

# Display (output)
/admin/config/people/profile-types  Klant  Weergave

Cache:

ddrush cr

Geleerde Lessen

Profile Module Particularities

  • Profile types hebben andere admin routes dan node types
  • registration: true maakt profiel beschikbaar bij user registratie
  • Shared field storage tussen profile types is mogelijk en handig
  • Display vs Form Display configuratie is cruciaal voor privacy

Conditional Fields Alpha Warning

Module is alpha (4.0.0-alpha6) maar stabiel genoeg voor productie. Geen issues ondervonden tijdens configuratie.

Field Type Keuzes Belangrijk

String vs Integer voor ID's/nummers is niet triviaal. Leading zeros en formatting vereisen string type, zelfs voor "nummers".

Twee Profielen Strategie

Scheiding tussen "transactioneel/privé" en "publiek/community" is logisch en begrijpelijk voor gebruikers. Betere UX dan één profiel met complexe privacy settings.

Volgende Stappen Detail

MailChimp ECA Regel

Event: User account created
Condition: field_nieuwsbrief = TRUE
Action: Subscribe to MailChimp list

Merge fields mapping: - EMAIL → User email - FNAME → User field (of customer profiel naam) - BEROEP → field_beroep (custom merge field in MailChimp)

Tags automatisch toevoegen: - "Nieuw account 2025" - "Beroep: {field_beroep}" - "Via website"

User Dashboard

Menu item: "Mijn account" (bij user login menu)
Route: /user/{user}

Tabs: - Overzicht (dashboard home) - Mijn bestellingen (Commerce orders view) - Mijn facturen (Commerce invoices view, PDF download) - Mijn profielen (Customer + Openbaar tabs) - Instellingen (account settings)

Views te maken: - commerce_orders_user (filtered by current user) - commerce_invoices_user (met download link) - user_activity_log (optioneel, order history summary)

Beroepsvereniging ECK

Velden voor ECK Beroepsvereniging: - Naam (title) - Afkorting (string) - Website (link) - Logo (image) - Beschrijving (text_long) - Kortingscode (string - voor toekomstige promoties) - Actief (boolean)

Resources

Drupal Documentatie: - Profile module: https://www.drupal.org/project/profile - Conditional Fields: https://www.drupal.org/project/conditional_fields - MailChimp: https://www.drupal.org/project/mailchimp

MailChimp: - API Documentation: https://mailchimp.com/developer/ - Merge fields guide: https://mailchimp.com/help/getting-started-with-merge-tags/ - Webhooks: https://mailchimp.com/developer/marketing/guides/sync-audience-data-with-webhooks/

Config Paths: - User settings: user.settings - Profile types: profile.type.{TYPE_ID} - MailChimp: mailchimp.settings - Conditional Fields: conditional_fields.*

Conclusie

Succesvolle sessie waarbij user management architectuur compleet is uitgewerkt. Keuze voor twee gescheiden profielen (privé vs publiek) biedt beste balans tussen functionaliteit, privacy en gebruiksvriendelijkheid.

MailChimp basis staat, ECA automatisering volgt volgende sessie. ECK Beroepsvereniging wordt cruciale verbetering voor data consistency.

Ready voor live deployment volgende week met duidelijke migratie checklist.