MIST Featured Resource Block
WordPress plugin for Mirasee assignment: custom post type, Elementor widget, and API sync.
by Salman Ahmed · github.com/salmanahmed47/mist-featured-resource-block
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/salmanahmed47/mist-featured-resource-block/archive/refs/heads/main.zipThis plugin was built as part of the Mirasee web developer assignment.
It adds a “Resources” custom post type, an Elementor widget to display a featured resource, and a background sync process that imports resources from an external API into WordPress.
1. Features Overview
Custom Post Type: Resources
- Post type:
mist_resource - Supports:
- Title
- Excerpt
- Featured Image
- Custom meta field:
- Resource URL (
_mist_resource_url)
- Resource URL (
- Resource URL is editable via a meta box on the Resource edit screen and is:
- Sanitized on save (
esc_url_raw) - Escaped on output (
esc_url)
- Sanitized on save (
Elementor Widget: Featured Resource Block
Widget name in Elementor: “Featured Resource Block”
Widget slug: mist_featured_resource
The widget allows a content editor to drop a single featured Resource onto any Elementor-powered page.
Controls:
-
Select Resource
- Dropdown of published
mist_resourceposts (up to 50, ordered by title). - Required for the widget to render the full block.
- Dropdown of published
-
Layout Style
Card– image + content blockMinimal– text-focused layout without image, styled as a compact highlight
-
Button Text
- Customizable CTA label for the link button (e.g. “Learn more”).
-
Gradient Background
- Switcher: on/off
- Adds a gradient utility class that changes the background styling.
-
Image Size
thumbnail,medium,large,full- Passed directly to
get_the_post_thumbnail()for the selected Resource.
Frontend behavior:
- Fetches the selected Resource:
- Title
- Excerpt (falls back to trimmed content if no excerpt exists)
- Featured image (if available)
- Resource URL from post meta
- Renders a responsive block with:
- Optional image (in
cardlayout) - Title
- Excerpt
- Button linking to the Resource URL (opens in a new tab,
rel="noopener noreferrer")
- Optional image (in
Basic styling is included inline (for the purposes of the assignment) to demonstrate visual structure:
- Rounded borders, spacing, and button styles for the card layout
- Simpler, left-border style for the minimal layout
- A gradient modifier class when the Gradient Background toggle is enabled
Settings Page: Resource Sync
A settings page is added under:
Settings → Resource Sync
This page uses the WordPress Settings API and provides:
-
API Key
- Stored as option:
mist_frb_api_key - Sanitized with
sanitize_text_field - Currently optional for the provided mock API, but wired into the request headers so it can be used with real authenticated endpoints.
- Stored as option:
-
Enable Sync
- Stored as option:
mist_frb_enable_sync - Sanitized into a boolean
- Controls whether the background sync runs.
- Stored as option:
When Enable Sync is turned off, the sync job exits early and does not affect anything.
Background Sync: Cron + API + Transients
The sync process is implemented in MIST_FRB_Sync:
- Custom cron interval:
mist_frb_15min→ 15-minute schedule registered viacron_schedules
- Cron hook:
- Event name:
mist_frb_sync_event - On plugin activation, an event is scheduled using a core interval (
hourly) so scheduling always succeeds, regardless of custom intervals.
- Event name:
- API endpoint:
- Defined as a class constant
API_ENDPOINT - For the assignment, this is set to the provided mock URL
- Defined as a class constant
- Caching:
- Raw API response is cached in a transient (
mist_frb_api_cache) for 5 minutes - Reduces external calls and keeps the sync efficient
- Raw API response is cached in a transient (
- Error handling:
- Uses
wp_remote_get()and checks:is_wp_error()- HTTP response code (expects
200)
- Invalid or unexpected responses are handled gracefully:
- No impact on frontend
- Errors are logged via
error_logfor debugging (no notices shown to users/Admins)
- Uses
Sync logic:
- Check if Enable Sync is turned on in settings.
- Fetch data from the API (or from transient if cached).
- For each item in the decoded JSON:
- Extract:
titleurl- Optional
excerpt - Optional
id(external identifier)
- Find matching Resource post by:
- External ID meta (
_mist_resource_external_id), or - Exact title match, as a fallback
- External ID meta (
- Insert or update a
mist_resourcepost accordingly. - Save:
_mist_resource_url(the link used by the Elementor widget)_mist_resource_external_id(for future matching)_mist_resource_raw(JSON-encoded copy of the original item for inspection)
- Extract:
The code is written defensively: if the API is down, returns an empty body, or the JSON shape is not as expected, the sync simply does nothing and exits without breaking the site.
2. Installation & Setup
-
Copy the plugin
- Place the
mist-featured-resource-blockdirectory inside:wp-content/plugins/
- Place the
-
Activate the plugin
- Go to Plugins → Installed Plugins
- Activate “MIST Featured Resource Block”
-
Create Resources
- Go to Resources → Add New
- Fill in:
- Title
- Excerpt
- Featured Image
- Resource URL in the meta box
-
Configure Sync (optional / assignment-specific)
- Go to Settings → Resource Sync
- Enter an API key (if required by the endpoint; optional for the provided mock)
- Check Enable Sync
- Save changes
-
Use the Elementor widget
- Edit a page with Elementor
- Search for “Featured Resource Block”
- Drag the widget into the layout
- In the widget settings:
- Select a Resource
- Choose layout style
- Set button text, gradient background, and image size
- Save and preview the page
3. Development Notes & Debugging
Cron & Sync
- On plugin activation:
- An event
mist_frb_sync_eventis scheduled using thehourlyinterval.
- An event
- At runtime:
- A custom 15-minute schedule (
mist_frb_15min) is registered, and can be used to adjust the interval if needed.
- A custom 15-minute schedule (
- For local development:
- Tools like WP Crontrol can be used to:
- Inspect the scheduled event
- Run
mist_frb_sync_eventmanually
- A small debug hook (
?mist_sync_debug=1) can be used in dev environments to run the sync on demand and print basic diagnostic information (API data count, status, etc.).- This is kept clearly separated and can be removed or disabled for production.
- Tools like WP Crontrol can be used to:
API Behavior
- When the provided mock endpoint returns a non-200 response (e.g. 404) or an unexpected JSON shape:
- The sync safely returns an empty array.
- No Resources are imported or modified.
- The site continues to function without errors.
- The plugin’s behavior is intentionally graceful under failure: external API issues never break the WordPress admin or frontend.
4. Limitations (by design for the assignment)
- No UI is provided to:
- Manually trigger sync from the admin interface.
- View sync logs within the dashboard.
- The sync is one-way:
- It creates/updates Resources based on the external data.
- It does not handle deletion of Resources that disappear from the API.
- Image handling:
- The sync does not download/attach remote images.
- Featured images must be set manually on Resources (or extended later).
5. Possible Improvements with More Time
If this were extended beyond the assignment, the following enhancements would be natural next steps:
-
Manual Sync Button
- Add a “Sync Now” button to the Resource Sync settings page.
- Show the timestamp and status of the last successful sync.
-
Better Status & Logging UI
- Store and display last sync result (success/fail + message) in the admin.
- Offer a lightweight log view for non-technical users.
-
Image Import
- If the API provided image URLs, download those and set them as featured images automatically.
-
More Flexible Widget Styling
- Expose colors, typography, spacing, and icon options via Elementor controls.
- Move CSS into a dedicated stylesheet instead of inline `