Example About Theme

About This Theme

Repository Model

  • This suite repo contains the theme plus installable plugins.
  • New client repos are typically theme-focused and can exclude plugin source packages.
  • Plugin functionality is added per client by uploading plugin zips.

Theme-Only Workflow

  • Work in examples/ and example-parts/ for MLS wiring/reference implementations.
  • Keep templates/ and template-parts/ focused on runtime shared/global theme behavior only.
  • Keep reusable styling in the documented LESS ownership files and page architecture in Tailwind utilities.
  • Use reusable sections/components where possible for long-term maintainability.

Styling Strategy In This Theme

  • This theme uses the suite default intentional LESS/Tailwind hybrid.
  • LESS owns reusable visual systems: typography, buttons, menus, cards, form controls, component states, and Gutenberg-friendly semantic classes.
  • Tailwind owns page architecture: section bands, frames, grids, flex direction, responsive stacking, and major spacing.
  • Use build/less/themecore-globals.less as the shared LESS import index.
  • Keep ownership in the imported files:
  • build/less/tokens.less
  • build/less/typography.less
  • build/less/components/buttons.less
  • build/less/components/search.less
  • build/less/components/cards.less
  • build/less/layout/header.less
  • build/less/layout/footer.less
  • build/less/pages/*.less
  • Do not add page-specific compiled CSS files for normal scaffold work.
  • Do not place site header/menu CSS in template files.

Tailwind In This Theme

  • Tailwind version is 4.2.x (root toolchain).
  • Tailwind is compiled from repo-level source files:
  • build/tailwind/tailwind.css
  • build/tailwind/critical.css
  • Entry files use Tailwind v4 CSS-first syntax:
  • @import "tailwindcss" source(none);
  • @import "./theme.css";
  • @source ... directives for theme PHP/HTML/JS scanning
  • Shared design tokens live in: build/tailwind/theme.css
  • Build outputs are written to theme assets:
  • packages/asnet-core-theme/assets/css/tailwind.css
  • packages/asnet-core-theme/assets/css/critical-tailwind.css
  • Runtime loading is handled by:
  • packages/asnet-core-theme/template-parts/themecore-styles.php
  • Practical workflow:
  • Edit markup/classes in theme templates, examples, and parts.
  • Rebuild with npx gulp tailwind (or use npx gulp watch).
  • Do not hand-edit compiled CSS outputs in assets/css/.
  • Intent:
  • Use utility classes for page architecture, layout, spacing, and responsive structure.
  • Use LESS ownership files for reusable component visuals and chrome.

LESS Surfaces

  • This theme includes a front-end shared LESS entry point:
  • build/less/themecore-globals.less
  • It also includes optional LESS entry points for editor/admin UX:
  • build/less/themecore-post-editor.less
  • build/less/themecore-carbon-fields.less
  • build/less/themecore-blocks.less
  • Build output lands in packages/asnet-core-theme/assets/css/ via gulp less (or gulp styles / gulp).
  • Runtime behavior:
  • themecore-post-editor.css: enqueued on post/page edit screens.
  • themecore-carbon-fields.css: enqueued on post/page edit screens for Carbon UI polish.
  • themecore-blocks.css: enqueued only in block editor (enqueue_block_editor_assets) as an optional custom block styling surface.
  • Guidance:
  • Keep front-end component/chrome styling in the documented LESS ownership files.
  • Keep front-end layout and page architecture in Tailwind utilities.
  • Use editor/admin LESS files only for editor/admin exceptions and CMS ergonomics.

Gutenberg Policy (Client-Level In Theme)

  • Block filtering belongs in theme, not DevCore, so each client can define editorial scope.
  • Theme now enforces a starter allowlist for non-power users on post and page.
  • No capability bypass is enabled by default; allowlist applies to all users unless a client override adds bypass caps.
  • Any registered ASNET block namespace is auto-allowed in restricted editors.
  • Embed options are intentionally limited to Embed, YouTube, and Vimeo.
  • Three starter responsive patterns are provided for non-power users:
  • Image Left + Text
  • Image Right + Text
  • Feature Image + Body

MLS Block Ownership

  • MLS content blocks are plugin-owned.
  • Current vessel blocks in the inserter are registered by asnet-iyba-plugin.
  • If the IYBA plugin is inactive, those IYBA blocks are unavailable.
  • Theme policy only controls allowed/visible blocks; it does not register MLS blocks itself.

Per-Client Override Hook

  • Use filter asnet_themecore_editor_block_policy in theme to override:
  • bypass_caps
  • restricted_post_types
  • allow_asnet_namespaces
  • post_type_allowlists
  • Practical approach: keep baseline list small, then extend per-client per post type.

Build and QA Commands

  • npm install
  • gulp tailwind
  • gulp tailwind-critical
  • gulp styles
  • gulp images
  • gulp new-images
  • gulp watch
  • npm run release:theme

Script Requirements

  • Node.js 20.x LTS and npm.
  • PHP + Composer (needed for DevCore/OpenAI and plugin packaging workflows).
  • ImageMagick CLI (magick) for image conversion tasks.
  • Recommended command style across Linux/Windows:
  • npx gulp ...
  • npm run ...

Quick checks:

  • node -v
  • npm -v
  • php -v
  • composer -V
  • magick -version

If magick is missing, Tailwind/JS tasks still work, but image conversion tasks (gulp images, gulp new-images) will fail.

OS Build Policy

  • Use one OS per repo clone.
  • Do not share node_modules across Windows and WSL in one working copy.
  • Team convention:
  • Suite source repo maintenance: WSL Ubuntu.
  • New client repos created from this suite: Windows + VS Code.

If build tooling fails after switching OS, reinstall dependencies in that OS:

  • WSL:
  • rm -rf node_modules package-lock.json
  • npm install
  • Windows:
  • rmdir /s /q node_modules
  • del package-lock.json
  • npm install

ImageMagick Pipeline In This Theme

  • Source images:
  • packages/asnet-core-theme/assets/images/
  • Generated outputs:
  • packages/asnet-core-theme/assets/images-min/
  • Task behavior:
  • gulp images processes the full image set.
  • gulp new-images processes newly added/missing outputs.
  • Outputs are generated as optimized derivatives (including WebP/AVIF support in the pipeline).

Practical usage: 1. Add/replace source images in assets/images/. 2. Run npx gulp images (or npx gulp new-images during iterative work). 3. Reference generated assets from assets/images-min/ in templates/components. 4. Re-run image tasks after replacing source files.

Carbon Fields In Theme (JSON-Driven)

  • Carbon model definitions can live in theme at:
  • packages/asnet-core-theme/config/carbon/*.json
  • Loader implementation:
  • packages/asnet-core-theme/functions/carbon-json.php
  • Registration hook:
  • carbon_fields_register_fields

Practical workflow: 1. Copy packages/asnet-core-theme/config/carbon/containers.sample.json. 2. Rename to model file(s), e.g. brands.json, products.json, widgets.json. 3. Set "enabled": true for the containers you want active. 4. Rebuild/release theme and deploy.

Notes:

  • Theme-level JSON keeps client data models under developer control.
  • This avoids coupling custom content models to DevCore seed configuration.
  • calls arrays are supported for extra Carbon fluent methods when needed.
  • Fields that need dynamic options can now use options_source in JSON.
  • Supported dynamic option sources currently include:
  • carbon_rows
  • post_query
  • This enables common client patterns such as:
  • a brands CPT storing model_categories
  • multiple model CPTs loading their model_category select options from the matching brand entry
  • For the full contract and examples, see:
  • docs/THEMECORE-CARBON-DYNAMIC-OPTIONS-SPEC.md
  • packages/asnet-core-theme/config/carbon/README.md

Plugin Integration Expectations

  • Baseline project stack: asnet-core-theme + asnet-devcore-plugin.
  • MLS/client plugins are added as needed (iyba, yachtworld, yatco, cya, etc.).
  • Seed-driven plugins require client config upload and plugin reactivation.
  • DevCore exposes editable client/contact/social metadata in its Config tab and mirrors it to asnet_client_info.
  • Theme work should continue even when a plugin is not present.

Seed + Rewrite Order Of Operations

  • Activate plugin(s), upload seed files in plugin Seed tabs, then deactivate/reactivate plugin(s).
  • Activate theme last so plugin-aware example pages and menus align to what is installed/configured.
  • Until seed activation is complete, admin tabs remain limited by design (including IYBA Config) for uniform behavior across MLS plugins.
  • Visit an admin page once so theme page-sync hooks run and plugin detail-page options are updated.
  • Save permalinks once in Settings > Permalinks to force a full rewrite refresh.
  • Verify plugin rewrite options and page IDs in your rewrite/debug tooling (devcore rewrite tab is sufficient).
  • Validate canonical URLs from cards:
  • IYBA: /listings/{slug}/{id}/
  • YachtWorld: /listings/{slug}/{documentId}-{endpoint}/
  • YATCO: /listings/{slug}/{id}-6/
  • CYA: /listings/{slug}/{id}-7/

Example UI Consistency

  • IYBA, YachtWorld, and YATCO examples are intentionally kept visually and structurally similar as wiring references.
  • Card grids for search/inventory/favorites use the same responsive max density (up to 4 columns on wide screens).
  • Site chrome is centralized through template-parts/themecore-close-header.php and template-parts/site/header.php.
  • Header/menu visuals live in build/less/layout/header.less; the template should stay focused on markup and WordPress data.
  • Example page templates should orchestrate page data and include provider parts. Provider-specific UI styling and behavior should live in example-parts/, as with algolia-styles.php and algolia-script.php.

Release Notes for Handoff

  • npm run build inside a package only builds that package assets.
  • Zip artifacts are created by root release scripts, not package-local build commands.
  • Verify output files in dist/releases/ before deployment.