Refactor Events Template Architecture#53
Refactor Events Template Architecture#53Ubayed-Bin-Sufian wants to merge 16 commits intofossasia:mainfrom
Conversation
Reviewer's GuideRefactors the events page template into a richer Events Hub with role-aware queries, reusable partials, and JS-driven admin CRUD, while adding footer editing and a sidebar news feed, plus corresponding styles, meta fields, and AJAX handlers. Sequence diagram for admin event CRUD via Events HubsequenceDiagram
actor Admin
participant Browser as Browser_WPFA_Events_JS
participant WP as WordPress_admin_ajax_php
participant Handler as Wpfaevent_Event_Handler
participant DB as WP_Database
Admin->>Browser: Click Create/Edit/Delete event
Browser->>Browser: Collect form data
Browser->>WP: POST action=wpfa_add_event/wpfa_update_event/wpfa_delete_event
WP->>Handler: Route to ajax_add_event/ajax_update_event/ajax_delete_event
Handler->>Handler: check_ajax_referer wpfa_events_ajax
Handler->>Handler: current_user_can manage_options
alt add_event
Handler->>DB: wp_insert_post post_type=wpfa_event
Handler->>DB: update_post_meta wpfa_event_start_date, wpfa_event_end_date, ...
opt featured_image uploaded
Handler->>WP: media_handle_upload featured_image
WP->>DB: Store attachment and thumbnail
Handler->>DB: set_post_thumbnail
end
Handler-->>WP: wp_send_json_success event_id
else update_event
Handler->>DB: get_post event_id
Handler->>DB: wp_update_post title, content, excerpt
Handler->>DB: update_post_meta wpfa_event_start_date, wpfa_event_time, ...
opt featured_image uploaded/removed
Handler->>WP: media_handle_upload or delete_post_thumbnail
end
Handler-->>WP: wp_send_json_success
else delete_event
Handler->>DB: get_post event_id
Handler->>DB: wp_delete_post force=true
Handler-->>WP: wp_send_json_success
end
WP-->>Browser: JSON { success, data }
alt success
Browser->>Browser: alert success message
Browser->>Browser: window.location.reload
else error
Browser->>Browser: alert error message
end
Sequence diagram for admin footer text updatesequenceDiagram
actor Admin
participant Browser as Browser_WPFA_Footer_JS
participant WP as WordPress_admin_ajax_php
participant FooterH as Wpfaevent_Footer_Handler
participant DB as WP_Options_Table
Admin->>Browser: Click Edit Footer
Browser->>Browser: Open edit-footer-modal and prefill textarea
Admin->>Browser: Submit footer form
Browser->>WP: POST action=wpfa_update_footer_text
WP->>FooterH: ajax_update_footer_text
FooterH->>FooterH: check_ajax_referer wpfa_events_ajax
FooterH->>FooterH: current_user_can manage_options
FooterH->>FooterH: sanitize_text_field footer_text
FooterH->>DB: update_option wpfa_footer_text
FooterH-->>WP: wp_send_json_success message
WP-->>Browser: JSON { success, message }
Browser->>Browser: Update #footer-text-display
Browser->>Browser: Close modal and alert success
Entity relationship diagram for wpfa_event post metaerDiagram
wp_posts {
bigint ID PK
varchar post_type
varchar post_title
text post_content
text post_excerpt
varchar post_status
}
wp_postmeta {
bigint meta_id PK
bigint post_id FK
varchar meta_key
longtext meta_value
}
wp_users {
bigint ID PK
varchar user_login
}
wpfa_event_speakers {
bigint post_id FK
bigint speaker_user_id FK
}
wp_posts ||--o{ wp_postmeta : has_meta
wp_posts ||--o{ wpfa_event_speakers : has_speakers
wp_users ||--o{ wpfa_event_speakers : is_speaker
%% Important meta keys for wpfa_event
wp_postmeta }o--|| wp_posts : belongs_to_post
%% Conceptual attributes (meta_key values) for wpfa_event
wpfa_event_meta {
string wpfa_event_start_date
string wpfa_event_end_date
string wpfa_event_time
string wpfa_event_location
string wpfa_event_lead_text
string wpfa_event_url
string wpfa_event_registration_link
string wpfa_event_cfs_link
array wpfa_event_speakers
}
wp_posts ||--|| wpfa_event_meta : uses_keys_for_wpfa_event
Class diagram for new and updated WPFA event architecture classesclassDiagram
class Wpfaevent_Public {
-string plugin_name
-string version
+__construct(plugin_name, version)
+enqueue_styles()
+enqueue_scripts()
+is_paginated_template() bool
}
class Wpfaevent_Admin {
-string plugin_name
-string version
+render_event_meta_box(post)
+save_event_meta(post_id)
}
class Wpfaevent_Meta_Event {
<<static>>
-string post_type
+register()
}
class Wpfaevent_Event_Handler {
-string plugin_name
-string version
+__construct(plugin_name, version)
+ajax_get_event()
+ajax_add_event()
+ajax_update_event()
+ajax_delete_event()
}
class Wpfaevent_Footer_Handler {
-string plugin_name
-string version
+__construct(plugin_name, version)
+ajax_update_footer_text()
}
class Wpfaevent_Plugin_Core {
-Wpfaevent_Public plugin_public
-Wpfaevent_Admin plugin_admin
+load_dependencies()
+define_admin_hooks()
}
class wpfaeventEventsConfig {
+string ajaxUrl
+string adminNonce
+bool isAdmin
+object i18n
}
class WPFA_Events {
-object config
-object elements
+init(options)
+openCreateEventModal()
+openEditEventModal(card)
+closeCreateEventModal()
+closeEditEventModal()
+filterEvents()
}
class WPFA_Footer {
-object config
-object elements
+init(options)
+openFooterModal()
+closeFooterModal()
}
class WP_Core_WP_Query {
+WP_Query(args)
}
%% Relationships
Wpfaevent_Plugin_Core --> Wpfaevent_Public : creates
Wpfaevent_Plugin_Core --> Wpfaevent_Admin : creates
Wpfaevent_Plugin_Core --> Wpfaevent_Event_Handler : registers_ajax_actions
Wpfaevent_Plugin_Core --> Wpfaevent_Footer_Handler : registers_ajax_actions
Wpfaevent_Admin --> Wpfaevent_Meta_Event : uses_register_post_meta
Wpfaevent_Public --> WP_Core_WP_Query : queries_events
wpfaeventEventsConfig <.. Wpfaevent_Public : localized_script_data
WPFA_Events ..> wpfaeventEventsConfig : reads_config
WPFA_Footer ..> wpfaeventEventsConfig : reads_config
WPFA_Events ..> Wpfaevent_Event_Handler : AJAX_calls
WPFA_Footer ..> Wpfaevent_Footer_Handler : AJAX_calls
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The footer JS is enqueued as
wpfaevent-footer.jsinWpfaevent_Public::enqueue_styles(), but the file added iswpfaevet-footer.js, so the script will 404; either rename the file or fix the enqueue handle/path. - The footer module initialization in
wpfaevet-footer.jscurrently checks forwpfaeventEventsConfigand passes that intoWPFA_Footer.init, but the localized object for the footer iswpfaeventFooterConfig; align the check and the object name so the footer config is actually used. - In the footer JS you localize
wpfaeventFooterConfigbut in the DOMContentLoaded handler you gate initialization ondocument.getElementById('edit-footer-btn')and the presence ofwpfaeventEventsConfig; this makes the footer script dependent on the events-page config and button, so consider decoupling it to work wherever the footer is rendered (e.g., check forwpfaeventFooterConfigonly).
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The footer JS is enqueued as `wpfaevent-footer.js` in `Wpfaevent_Public::enqueue_styles()`, but the file added is `wpfaevet-footer.js`, so the script will 404; either rename the file or fix the enqueue handle/path.
- The footer module initialization in `wpfaevet-footer.js` currently checks for `wpfaeventEventsConfig` and passes that into `WPFA_Footer.init`, but the localized object for the footer is `wpfaeventFooterConfig`; align the check and the object name so the footer config is actually used.
- In the footer JS you localize `wpfaeventFooterConfig` but in the DOMContentLoaded handler you gate initialization on `document.getElementById('edit-footer-btn')` and the presence of `wpfaeventEventsConfig`; this makes the footer script dependent on the events-page config and button, so consider decoupling it to work wherever the footer is rendered (e.g., check for `wpfaeventFooterConfig` only).
## Individual Comments
### Comment 1
<location> `public/js/wpfaevet-footer.js:170-171` </location>
<code_context>
+if (typeof document !== 'undefined') {
+ document.addEventListener('DOMContentLoaded', function() {
+ // Check if config exists (footer exists on all template pages)
+ const footerElement = document.getElementById('edit-footer-btn');
+ if (footerElement && typeof wpfaeventEventsConfig !== 'undefined') {
+ WPFA_Footer.init(wpfaeventEventsConfig);
+ }
</code_context>
<issue_to_address>
**issue (bug_risk):** Footer module is initialized with the wrong localized config object.
Here the footer is initialized with `wpfaeventEventsConfig`, but the PHP localization exposes `wpfaeventFooterConfig`. As a result, the footer will break on pages where only the footer config is present and will miss footer-specific i18n strings. This should instead check `typeof wpfaeventFooterConfig !== 'undefined'` and pass that object into `WPFA_Footer.init`.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
This PR refactors the Events page template into a richer “Events Hub” experience with modular partials, adds front-end admin CRUD via AJAX modals, and introduces a shared footer + “Latest News” sidebar integration.
Changes:
- Reworked
page-events.phpto render upcoming + past events, include reusable event-card/modal partials, and add client-side filtering + admin controls. - Added AJAX handlers + public JS modules for event CRUD and footer text editing, plus new event meta fields.
- Added RSS-based “Latest News” helper and a shared footer partial (with admin edit modal).
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
wpfaevent.php |
Loads the new news helper functions. |
public/templates/page-events.php |
Major rewrite: Events Hub layout, upcoming/past queries, search UI, sidebar, footer + modals. |
public/partials/footer.php |
New shared footer partial with admin-only edit UI. |
public/partials/events/event-modal.php |
New create/edit event modal markup for admin front-end CRUD. |
public/partials/events/event-card.php |
New reusable event card partial with admin action buttons and data attributes. |
public/partials/events-listing-page.php |
Removes an old proxy partial. |
public/js/wpfaevent-footer.js |
New JS module to update footer text via AJAX. |
public/js/wpfaevent-events.js |
New JS module for search + admin CRUD (create/edit/delete) via AJAX. |
public/css/wpfaevent-public.css |
Adds shared footer/modal/button styles and character counter styling. |
public/css/templates/events.css |
Adds MVP-styled layout and components for the Events page. |
public/class-wpfaevent-public.php |
Enqueues new template styles/scripts and localizes config for events/footer modules. |
includes/meta/class-wpfaevent-meta-event.php |
Registers new event meta: lead text, registration link, CFS link. |
includes/helpers/class-wpfaevent-news-functions.php |
New RSS news fetching/caching + fallback helpers. |
includes/class-wpfaevent.php |
Loads/registers new AJAX handler classes and hooks AJAX actions. |
admin/partials/ajax-handlers/class-wpfaevent-footer-handler.php |
New authenticated AJAX endpoint to update footer text option. |
admin/partials/ajax-handlers/class-wpfaevent-event-handler.php |
New authenticated AJAX endpoints for event CRUD + image upload. |
admin/class-wpfaevent-admin.php |
Extends the event meta box to include new fields (time, lead text, links). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
admin/partials/ajax-handlers/class-wpfaevent-footer-handler.php
Outdated
Show resolved
Hide resolved
admin/partials/ajax-handlers/class-wpfaevent-footer-handler.php
Outdated
Show resolved
Hide resolved
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Description
This PR refactors a hardcoded file of events template referenced below maintaining OOP and SRP principles.