Skip to content

Refactor theme structure and update to use rtcamp/framework#689

Open
pratik-londhe4 wants to merge 20 commits into
theme-elementary-v2from
feat/theme-elementary-framework
Open

Refactor theme structure and update to use rtcamp/framework#689
pratik-londhe4 wants to merge 20 commits into
theme-elementary-v2from
feat/theme-elementary-framework

Conversation

@pratik-londhe4
Copy link
Copy Markdown

@pratik-londhe4 pratik-londhe4 commented May 21, 2026

Description

Migrates theme-elementary off its copy of the framework and onto the upstream rtcamp/wp-framework Composer package.

Also folds in a few stale-doc / stale-code follow-ons that were left over from the migration: converts the now-empty inc/helpers/custom-functions.php to a PSR-4 Helpers\Util static class, drops the Composer files autoload entry, and rewrites DEVELOPMENT.md (which still described inc/Framework/ as a real subdirectory).

Technical Details

  • Composer wiring. Added a type: vcs repository entry pointing at github.com/rtCamp/wp-framework.git and require rtcamp/wp-framework: dev-framework to composer.json. Dropped the legacy files autoload block — the whole theme is now PSR-4 with no special cases.
  • inc/Framework/ deleted in its entirety. The local copy only had AutoloaderTrait, AssetLoaderTrait, and Singleton; the missing pieces (Loader, Container, Registrable, Shareable) now come from the package along with the abstracts.
  • inc/Autoloader.php uses rtCamp\WPFramework\AutoloaderTrait (the package's graceful-failure wrapper around vendor/autoload.php).
  • inc/Main.php uses the package Singleton + Loader traits and loads the theme's services via $this->load( [ Assets::class, MediaTextInteractive::class, ThemeOptions::class ] ). No get_instance() anywhere except on Main itself.
  • Core\Assets implements Registrable and uses the framework AssetLoaderTrait.
  • Modules\BlockExtensions\MediaTextInteractive implements Registrable (previously a get_instance() singleton — now plain).
  • Modules\Settings\ThemeOptions extends AbstractSettingsPage. Uses a declarative get_fields() pattern with auto-generated Settings API sections + a generic render_field() so adding another option is a one-entry change.
  • Every use / namespace reference re-pointed from rtCamp\Theme\Elementary\Framework\… to rtCamp\WPFramework\….
  • inc/helpers/custom-functions.phpinc/Helpers/Util.php. The old file was empty (placeholder comment only). Replaced with a final static class (private __construct()) mirroring the plugin's Helpers\Util pattern — ready to host theme-wide helpers without growing the global function table or relying on the files autoload directive.
  • DEVELOPMENT.md rewritten. The previous version still described an inc/Framework/ subdirectory and a "two-layer model" rooted in it. New content reframes the layers around vendor/rtcamp/wp-framework/ vs inc/, lists the actual on-disk PSR-4 reference table, documents the Helpers/ convention, and adds a "Picking a base" table mapping feature types to the package's abstracts/interfaces.

Checklist

Acceptance criteria from the issue:

  • theme-elementary boots without fatal (fixes the broken hand-edit state)
  • No get_instance() calls remain except the bootstrap class (Main::get_instance() in functions.php)
  • inc/Framework/ directory deleted
  • No references to the old local framework namespaces remain (grep -rn "inc/Framework\|\\Framework\\" inc/ returns nothing)
  • Composer require includes rtcamp/wp-framework + type: vcs repository entry pointing at the framework repo
  • inc/Autoloader.php uses the package's AutoloaderTrait
  • Main keeps use Singleton; use Loader; — every other former singleton became a plain Registrable
  • Consumer features extend the package abstracts where applicable (ThemeOptionsAbstractSettingsPage)

Out-of-ticket cleanup landed alongside the migration:

  • inc/helpers/custom-functions.php (empty) converted to PSR-4 Helpers\Util static class; files autoload entry removed
  • DEVELOPMENT.md rewritten to drop stale inc/Framework/ references and document the current architecture

Fixes/Covers issue

Fixes #
https://github.com/rtCamp/wp-framework/issues/26

@pratik-londhe4 pratik-londhe4 marked this pull request as ready for review May 22, 2026 13:32
@pratik-londhe4 pratik-londhe4 requested a review from Copilot May 22, 2026 13:34
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates theme-elementary from a vendored in-repo framework (inc/Framework/) to the upstream rtcamp/wp-framework Composer dependency, and updates theme bootstrapping/services/docs to align with the framework’s Singleton/Loader/Registrable patterns.

Changes:

  • Replace the local framework layer with rtcamp/wp-framework via Composer and update theme bootstrap/autoloading to use upstream traits/contracts.
  • Refactor theme services to be loaded through the framework Loader (assets, block extension, and a new example settings page).
  • Update documentation and housekeeping (PSR-4 helpers class, README/DEVELOPMENT.md rewrites, workflow adjustments).

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
README.md Updates structural docs to reflect vendor/rtcamp/wp-framework + inc/ layout.
phpstan-baseline.neon Adds a new suppression for a PHPStan always-true boolean warning.
inc/Modules/Settings/ThemeOptions.php Introduces a declarative settings page built on the framework’s AbstractSettingsPage.
inc/Modules/BlockExtensions/MediaTextInteractive.php Converts to Registrable and renames hook wiring to register_hooks().
inc/Main.php Switches to framework Singleton + Loader and loads services via $this->load([...]).
inc/Helpers/Util.php Replaces empty global helpers file with a PSR-4 static utility class placeholder.
inc/helpers/custom-functions.php Removes the old non-namespaced (empty) helpers file.
inc/Framework/Traits/Singleton.php Removes local framework singleton trait (now provided by dependency).
inc/Framework/Traits/AutoloaderTrait.php Removes local autoloader trait (now provided by dependency).
inc/Framework/Traits/AssetLoaderTrait.php Removes local asset loader trait (now provided by dependency).
inc/Framework/README.md Removes framework-layer documentation (now replaced by DEVELOPMENT.md guidance).
inc/Core/Assets.php Converts assets service to Registrable and swaps to framework AssetLoaderTrait.
inc/Autoloader.php Switches to framework AutoloaderTrait and points at dependency location.
DEVELOPMENT.md Rewrites dev docs to match the new vendor/framework boundary and module patterns.
composer.lock Locks rtcamp/wp-framework and updates dependency graph accordingly.
composer.json Adds VCS repo + requires rtcamp/wp-framework, removes autoload.files.
.github/workflows/test-measure.yml Adjusts PHP lint job for VCS installs; removes the PHP unit test job.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread inc/Autoloader.php Outdated
Comment thread inc/Core/Assets.php Outdated
Comment thread phpstan-baseline.neon Outdated
Comment on lines 85 to 92
- name: Summarize skipped jobs
run: |
SKIPPED=()

[[ "${{ steps.determine-file-counts.outputs.css-count }}" -le 0 ]] && SKIPPED+=("lint-css")
[[ "${{ steps.determine-file-counts.outputs.js-count }}" -le 0 ]] && SKIPPED+=("lint-js" "unit-tests-js" "build-prod")
[[ "${{ steps.determine-file-counts.outputs.php-count }}" -le 0 ]] && SKIPPED+=("lint-php" "unit-test-php")
[[ "${{ steps.determine-file-counts.outputs.php-count }}" -le 0 ]] && SKIPPED+=("lint-php")

Comment thread inc/Main.php Outdated
Comment thread inc/Core/Assets.php Outdated
$this->setup_hooks();
public function __construct() {
$this->plugin_dir = ELEMENTARY_THEME_TEMP_DIR . '/';
$this->plugin_url = trailingslashit( get_template_directory_uri() ) . '/';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double trailing slash in plugin_url. trailingslashit() already appends a /, then you concatenate another '/'. This produces URLs like https://example.com/wp-content/themes/elementary//assets/build/... which, while browsers tolerate, can break string comparisons and caching.

Suggested change
$this->plugin_url = trailingslashit( get_template_directory_uri() ) . '/';
$this->plugin_url = trailingslashit( get_template_directory_uri() );

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment thread inc/Core/Assets.php Outdated
// Setup hooks.
$this->setup_hooks();
public function __construct() {
$this->plugin_dir = ELEMENTARY_THEME_TEMP_DIR . '/';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant trailing slash on plugin_dir. ELEMENTARY_THEME_TEMP_DIR likely already ends without a slash, but appending '/' here while AssetLoaderTrait may also add one could cause double-slash issues in file paths. Consider using trailingslashit() for consistency, or verify the trait's expectations.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, fixed

Comment thread inc/Autoloader.php Outdated

if ( ! trait_exists( 'rtCamp\Theme\Elementary\Framework\Traits\AutoloaderTrait' ) ) {
require_once ELEMENTARY_THEME_TEMP_DIR . '/inc/Framework/Traits/AutoloaderTrait.php';
if ( ! trait_exists( 'rtCamp\WPFramework\AutoloaderTrait' ) ) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manual require_once before Composer autoload defeats the purpose. If vendor/autoload.php hasn't been loaded yet (which is the whole point of this class), the trait_exists check will always be false, and you'll always hit the require_once. This hardcodes the framework's internal file path (inc/AutoloaderTrait.php), which could break if the framework restructures.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed this in upstream and updated the theme and plugin

* Derives the register_setting() args from get_fields() by stripping
* the UI-only keys.
*/
protected function get_settings(): array {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing return type annotation in PHPDoc. The get_settings() method returns array but lacks a @return PHPDoc with the array shape. While native types are declared, the array structure documentation would help consumers understand the expected format.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread inc/Core/Assets.php Outdated
// Setup hooks.
$this->setup_hooks();
public function __construct() {
$this->plugin_dir = ELEMENTARY_THEME_TEMP_DIR . '/';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also can we fix this here, the name ELEMENTARY_THEME_TEMP_DIR sounds like a temporary name

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants