WP Manifestindependent plugin directory
manifest / developer / modularity-custom-modules

Modularity Custom Modules

A simple WordPress plugin for adding custom Modularity modules to the Municipio theme.

by Linu George · github.com/georgelinu/modularity-custom-modules · website

1stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/georgelinu/modularity-custom-modules/archive/refs/heads/main.zip

A simple WordPress plugin for adding custom Modularity modules to the Municipio theme.


Description

To create custom modularity-modules for Municipio. This plugin is a template to create custom modules. The modules are auto-discovered by placing them in the /modules/ folder, and the ACF fields are auto-discovered by placing them in the /acf-fields/php/ and /acf-fields/json/ folder. The blade views are auto-discovered by placing them in the /modules/ModuleName/views/ folder.


Requirements

  • WordPress 6.0+
  • Municipio 5.0+
  • Modularity plugin (bundled in Municipio, or install standalone)
  • Advanced Custom Fields PRO

Note: This plugin will not work without all of the above active. It silently does nothing if Modularity or ACF PRO is missing.


Installation

  1. Download or clone this plugin into your WordPress plugins directory:
    wp-content/plugins/
  2. Log in to WordPress admin and go to Plugins → Installed Plugins.
  3. Activate Modularity Custom Modules.
  4. Enable the required modules in "Modularity Options".
  5. Go to any page that uses Modularity and click Add Module — you should now see the custom Blocks listed as an available module.

File Structure for the plugin

modularity-custom-modules/
│
├── modularity-custom-modules.php    ← Plugin root file.
│
├── assets/
│   ├── css/
│   │   ├── style.css                ← Shared styles applied to every module.
│   │   └── HeadingModule.css        ← Module-specific styles (one file per module).
│   └── js/
│       ├── main.js                  ← Shared JS loaded on every page.
│       └── HeadingModule.js         ← Module-specific JS (one file per module).
│
├── acf-fields/
│   ├── json/
│   │   └── HeadingModule.json       ← One file per module (filename must match the module name).
│   └── php/
│       └── HeadingModule.php        ← One file per module (filename must match the module name).
│
└── modules/
    └── HeadingModule/               ← One folder per module.
        ├── HeadingModule.php        ← Module class:
        │                              - Defines slug, name, and description.
        │                              - Enqueues module assets.
        │                              - Passes data to the view.
        └── views/
            └── heading-module.blade.php  ← Blade template for rendering.

How to Add a New Module

Follow these steps every time you want a new module:

  1. Create a folder: modules/YourModule/
  2. Add class file: modules/YourModule/YourModule.php
  3. Add blade view: modules/YourModule/views/your-module.blade.php
  4. Add ACF PHP: acf-fields/php/YourModule.php (export from WP Admin)
  5. Add ACF JSON: acf-fields/json/YourModule.json (export from WP Admin)

Step 1 — Create the folder and files

modules/
└── MyModule/
    ├── MyModule.php
    └── views/
        └── my-module.blade.php

Step 2 — Create the module class

Copy modules/HeadingModule/HeadingModule.php into your new folder and rename the class. Then update:

What to change

  • Namespace (ModularityCustomModules\Modules\MyModule)
  • Class name (MyModule)
  • Slug ($slug : A unique slug, e.g. mcm-my-module)
  • Name ($this->nameSingular / $this->namePlural : Human-readable names, e.g. My Module / My Modules)
  • Description ($this->description)
  • Template return value (template() : 'my-module.blade.php')

Step 3 — Create the view

Copy modules/HeadingModule/views/heading-module.blade.php into modules/MyModule/views/my-module.blade.php and update the HTML/variables to match your module.

Step 4 — Register ACF fields (PHP) for a module

  1. Create the field group using ACF.
  2. Export the field group to PHP (using ACF's export tool).
  3. Place the exported PHP file in acf-fields/php/YourModule.php

Note: The filename must match the module-name.

Step 4 — Register ACF fields (JSON) for a module

  1. Create the field group in WP Admin using ACF.
  2. Export the field group to JSON (using ACF's export tool).
  3. Place the exported JSON file in acf-fields/json/YourModule.json

Note: The filename must match the module-name.

That's it — Modularity will automatically detect the new module.


ACF Fields Reference

Fields are defined in the registerAcfFields() method of each module class.

Note: Full ACF field type reference: Advanced Custom Fields

Reading field values in data()

See the below examples on how to get values from ACF.

// 1. Simple field value.
$data['my_field'] = get_field('mcm_my_module_my_field', $post->ID) ?: '';

// 2. Image field value (returns an array).
$image = get_field('mcm_my_module_image', $post->ID);
$data['image_url'] = $image['url'] ?? '';
$data['image_alt'] = $image['alt'] ?? '';

// 3. Repeater field value(returns an array of rows).
$data['items'] = get_field('mcm_my_module_items', $post->ID) ?: [];

Outputting values in the Blade view

See the below examples on how to render the UI.

{{-- Plain text (HTML escaped — safe) --}}
{{ $my_field }}

{{-- HTML content from WYSIWYG (not escaped — trusted admin content) --}}
{!! $content !!}

{{-- Conditional output --}}
@if (!empty($title))
    <h2>{{ $title }}</h2>
@endif

{{-- Looping a repeater --}}
@foreach ($items as $item)
    <p>{{ $item['label'] }}</p>
@endforeach

CSS & JS

  • Shared styles (applied to every module): assets/css/style.css
  • Module-specific styles: assets/css/MyModule.css (enqueued in the module's style() method)
  • Shared JS (loaded on every page): assets/js/main.js
  • Module-specific JS: assets/js/MyModule.js (enqueued in the module's script() method)

Module Icon Names

Icons come from the Google Material Icons set used by Municipio. Browse all available icons at: Google Icons

Use the icon's name in snake_case as the $moduleIcon value in your module class. Examples: text_fields, image, info, contact_page, list, article.


Naming Conventions Used

To avoid conflicts with other plugins, this plugin uses the mcm_ prefix consistently:

Examples PHP namespace: ModularityCustomModules\Modules\ModuleName Post type: mod-{module-name}, mod-text-block ACF group key: group_mcm_{module_name}, group_mcm_text_block ACF field key: field_mcm_{module}_{field}, field_mcm_text_block_title ACF field name: mcm_{module}_{field}, mcm_text_block_title CSS class on wrapper: modularity-{module-name}, modularity-text-block


Troubleshooting

If Module doesn't appear in the Modularity module

  • Make sure all the connected plugins are active.
  • Check that your module class file has no PHP syntax errors.

ACF fields don't appear on the module edit screen

  • Make sure ACF PRO is active.
  • Check the location rule in your ACF PHP file — the value must exactly match your module's $slug prefixed with mod- (e.g. mod-mcm-heading).

The view isn't rendering/blank output

  • Confirm the path returned by template() matches the actual file path relative to the plugin root.
  • Check for PHP/Blade syntax errors in the view file.

For enquiry about the plugin, please contact at Linu George


Changelog

1.0.0

  • Initial release with auto-discovery for modules, ACF fields, and Blade views.

License

MIT — free to use, modify, and share.