Baby in Brazil CTA module

Developer Documentation

This document is the primary technical reference for mod_bib_cta. It explains how the Joomla module is wired, which files own which responsibilities, what each PHP method does, how administrator presets work, and what must be checked before distribution or Joomla Extensions Directory submission.

Joomla site module PHP 8+ GPL-2.0-or-later CSS Grid Template override friendly JED preparation docs included

Why this module exists

The original CTA was a static bottom block inside the Baby in Brazil gallery page. It had strong visual design, but it was tied to a single page, a gallery-* CSS namespace and hard-coded content. The module converts that static block into a reusable Joomla extension.

For content managers

Manage title, text, image, alt text, advantages, CTA buttons, grid columns and visual style without editing PHP or HTML.

For developers

Extend layouts, partials, icons, presets and CSS variables without copying whole CTA sections into template overrides.

For distribution

Keep the module installable, documented, licensed and prepared for future public distribution requirements.

Architecture

LayerFilesResponsibility
Manifestmod_bib_cta.xmlDeclares module metadata, files, media assets, language packs, fieldsets and administrator fields.
DI providerservices/provider.phpRegisters the module dispatcher with Joomla dependency injection.
Dispatchersrc/Dispatcher/Dispatcher.phpNormalises layout selection and prepares display data before Joomla includes the selected module template.
Helpersrc/Helper/CtaHelper.phpCentral validation, normalisation, presets, CSS variables, escaping and icon rendering.
Admin fieldsrc/Field/FeaturepresetField.phpRenders preset action buttons and injects admin preset payload/JavaScript.
Main templatestmpl/*.phpDefine high-level layout variants: default, compact, centered and dark.
Partial layoutslayouts/cta/*.phpReusable render fragments for media, content, features, actions and decoration.
Assetsmedia/css/cta.css
media/js/admin-feature-presets.js
media/joomla.asset.json
Frontend styling and administrator preset behavior.

Architecture decisions

The package now includes Architecture Decision Records (ADRs). ADRs document why the module uses administrator-generated feature presets, CSS Grid, partial layouts, inline SVG icons, helper-level data normalisation and a JED-preparation strategy without fake update URLs.

Canonical Markdown records

The canonical decision records live in Markdown so they remain readable in repositories and code review tools.

docs/architecture-decisions/

Decision areaADRReason
PresetsADR-001Preset rows are generated into saved subform data instead of hidden frontend logic.
Frontend layoutADR-002, ADR-008The CTA avoids Bootstrap as a hard dependency and exposes CSS custom properties as the theme API.
Rendering architectureADR-003, ADR-006Main layouts, partial layouts and the helper data contract keep templates small and override-friendly.
Icons and semanticsADR-004, ADR-011Inline SVG and controlled section semantics reduce dependency and accessibility risk.
DistributionADR-005, ADR-007, ADR-009, ADR-010The module remains lightweight, documented, admin-reliable and ready for future distribution work.

Render lifecycle

1. Joomla loads modulemanifest + params
2. Provider registers dispatcherDI container
3. Dispatcher normalises layoutdefault/custom
4. Helper builds CTA arrayvalidated data
5. tmpl renders shellvariant layout
6. partial layouts render piecesmedia/content/buttons

Template files should not parse raw module params. They receive a normalised $cta array and pass it to smaller layouts.

CTA data contract

The $cta array is produced by CtaHelper::getCtaData(). Keep this structure stable when extending the module; templates and partial layouts depend on it.

$cta = [
  'id' => 'mod-bib-cta-123',
  'moduleId' => 123,
  'preset' => 'birth',
  'variant' => 'default',
  'ariaLabel' => 'Planning to give birth in Brazil',
  'eyebrow' => '',
  'title' => 'Planning to give birth in Brazil?',
  'headingLevel' => 'h2',
  'text' => 'We are here to make your journey safe...',
  'media' => [
    'src' => 'images/cta.jpg',
    'alt' => 'Pregnant couple standing near the water',
    'position' => 'left',
    'fit' => 'cover',
    'width' => 320,
    'minHeight' => 224,
  ],
  'features' => [
    ['enabled' => true, 'icon' => 'check', 'title' => 'Full Support', 'text' => 'Before & During', 'url' => ''],
  ],
  'actions' => [
    ['enabled' => true, 'label' => 'Contact us', 'url' => 'https://...', 'style' => 'primary'],
  ],
  'grid' => [
    'mode' => 'exact',
    'columns' => ['mobile' => 1, 'tablet' => 2, 'desktop' => 4, 'wide' => 4],
  ],
];

PHP API reference

services/provider.php::register(Container $container) DI

Registers the module dispatcher factory. Change this only when changing the dispatcher class or adding new services.

Dispatcher::getLayoutData(): array render

Calls the parent dispatcher, normalises the layout param, loads CSS assets and injects $cta into the layout data.

CtaHelper::normaliseLayoutParam(Registry $params): void

Converts the readable administrator layout value into the effective Joomla layout. Supports _custom and sanitises custom layout names.

CtaHelper::getCtaData(Registry $params, object $module, object $app): array

Main data builder. Reads params, applies defaults, normalises media/features/actions/grid/design and returns the display contract.

CtaHelper::loadAssets(Registry $params, object $app): void

Registers and loads mod_bib_cta.cta through Joomla Web Asset Manager when load_css is enabled.

CtaHelper::getRootClasses(array $cta, array $extra = []): string

Builds root CSS classes such as bib-cta--media-left, bib-cta--features-auto and bib-cta--dark.

CtaHelper::getRootStyle(array $cta): string

Creates safe inline CSS variables for per-instance grid columns, media width, media height, gaps and container width.

CtaHelper::classNames(array $classes): string

Small utility for conditional class lists. Accepts keyed booleans and numeric class values.

CtaHelper::escape(?string $value): string

Escapes text for HTML output. Use it in templates unless the value is already intentionally rendered as safe HTML.

CtaHelper::escapeUrl(?string $value): string

Sanitises URLs before output. Internal anchors, relative URLs and external URLs are supported.

CtaHelper::isExternalUrl(string $url): bool

Detects whether a URL points outside the current site. Used for link behavior and rel/target decisions.

CtaHelper::renderIcon(string $name): string

Returns inline SVG markup for supported icon identifiers. Keep icon options in forms and preset data synchronized with this method.

CtaHelper::getPresetDefaults(string $preset): array

Frontend defaults for the whole CTA. Used when content fields are empty.

CtaHelper::getAdminContentPresetDefaults(string $preset): array

Payload for the administrator JavaScript that fills content fields when a content preset is applied.

CtaHelper::getFeaturePresetDefaults(string $preset): array

Returns repeatable feature rows for a feature preset. These are inserted into the Joomla subform as real editable rows.

CtaHelper::getFeaturePresetKeys(): array

List of valid feature preset identifiers used by the admin field and validation logic.

FeaturepresetField::getInput(): string admin

Renders the three feature preset buttons: append, replace and clear. It also prints JSON options and a direct fallback script tag.

Layouts and overrides

Main templates

tmpl/default.php, compact.php, centered.php and dark.php decide the high-level shell and modifier classes.

Partial layouts

layouts/cta/*.php render reusable pieces. The main templates should call these partials rather than duplicating markup.

FilePurposeChange when...
layouts/cta/media.phpImage or background media markup.Need video support, picture sources or custom image wrapper.
layouts/cta/content.phpEyebrow, title, text, features and actions composition.Need different content order.
layouts/cta/features.phpFeature grid wrapper.Need a different list/grid semantic structure.
layouts/cta/feature.phpOne feature item.Need custom icons, microcopy or link wrapping.
layouts/cta/actions.phpButton group wrapper.Need different button grouping.
layouts/cta/action.phpOne action button/link.Need tracking attributes, analytics hooks or custom rel rules.
layouts/cta/decoration.phpDecorative line art.Need another decorative SVG set.

Administrator preset UI

Feature presets intentionally use explicit actions. The select chooses a source; the buttons decide what happens.

Append

Adds selected preset rows after existing feature rows. Existing rows are preserved.

Replace

Asks for confirmation when rows already exist, then clears the subform and inserts selected preset rows.

Clear

Asks for confirmation and removes all feature rows.

The frontend renders only saved repeatable rows. Presets are not dynamic frontend data sources; they are administrator data-entry accelerators.

CSS API

The module is styled with a stable bib-cta namespace and per-instance CSS custom properties.

VariablePurpose
--bib-cta-media-widthLeft/right media column width.
--bib-cta-media-min-heightMinimum media/card height.
--bib-cta-feature-cols-mobileFeature columns under tablet breakpoint.
--bib-cta-feature-cols-tabletFeature columns from 768px.
--bib-cta-feature-cols-desktopFeature columns from 992px.
--bib-cta-feature-cols-wideFeature columns from 1200px.
--bib-cta-feature-min-widthMinimum item width for auto-fit feature grid mode.
--bib-cta-content-gapVertical content spacing.
--bib-cta-features-gapFeature grid gap.

Presets

Presets currently include birth, services, doctors, hospitals, documents, legal, concierge, apartments, family, newborn, gallery and contact.

When adding a new preset, update all of the following:

  • mod_bib_cta.xml — content and feature preset selects.
  • CtaHelper::getPresetDefaults() — frontend fallback defaults.
  • CtaHelper::getAdminContentPresetDefaults() — admin content-fill payload.
  • CtaHelper::getFeaturePresetDefaults() — feature rows for insertion.
  • Language files — human labels and descriptions.
  • HTML documentation and examples.

Icons

Feature icons and action icons are defined by string identifiers, not by arbitrary SVG input. This keeps admin data safe and predictable.

TypeSupported identifiersSource of truth
Feature iconscheck, heart, shield, doctor, hospital, document, home, apartment, family, baby, calendar, scale, suitcase, map, star, noneforms/feature.xml + CtaHelper::renderIcon()
Action iconswhatsapp, arrow, phone, mail, noneforms/action.xml + CtaHelper::renderIcon()

JED readiness

This package includes a JED preparation checklist and update-server template. Before a public JED submission, the developer still needs to publish real project URLs, documentation URL, demo URL, support URL and update XML/download URL.

Important: do not add a placeholder update server URL to the production manifest. JED requires update-system support for new listings, but a broken update URL is worse than a documented placeholder. Add the real URL only when the update XML is published.
  • GPL-compatible license file is included as LICENSE.txt.
  • No encoded PHP, hidden backlinks or call-home requirement.
  • Documentation and examples are included in the package.
  • Distribution/update templates are included under dist/update-server/.
  • JED submission notes are available in docs/JED_SUBMISSION_GUIDE.html.

Maintenance checklist

  • Run PHP syntax checks for all .php files.
  • Validate XML manifest and subform XML files.
  • Validate media/joomla.asset.json.
  • Run a JavaScript syntax check for admin-feature-presets.js.
  • Install the ZIP on a clean Joomla site before tagging a release.
  • Test all four layouts and all feature preset actions.
  • Update CHANGELOG.md, HTML docs and legacy Markdown docs when behavior changes.