Skip to content

release: theme-elementary v2 - #692

Draft
aryanjasala wants to merge 144 commits into
mainfrom
theme-elementary-v2
Draft

release: theme-elementary v2#692
aryanjasala wants to merge 144 commits into
mainfrom
theme-elementary-v2

Conversation

@aryanjasala

@aryanjasala aryanjasala commented May 26, 2026

Copy link
Copy Markdown
Member

Rollup PR tracking theme-elementary v2. Merges accumulated work
from theme-elementary-v2 into main once all child PRs land.

Draft — kept open as integration target for the v2 work stream.
Do not merge until the project work is completed.

bhavz-10 and others added 30 commits March 31, 2026 10:32
Refactor: PSR-4 PHP Structure Migration
Update style.css to remove @ tags and make the Description more descriptive. Make other changes based on return types and description.
…strict-types-docblock-cleanup

PHP 8.2 Compatibility, Strict Types & Docblock Cleanup
* chore: Update output messages in CI workflow to include repository name and replace `::set-output ` with `$GITHUB_OUTPUT`

* chore: Enhance CI workflow by adding node version retrieval and caching for node_modules

* chore: Remove GHA workflow count from job triggers and outputs

* chore: Update IGNORE_PATH_REGEX to also allow .github/actions through

* chore: Fix regex

* fix: Correct typo in external dependencies comment

* fix: Add missing newline at end of README.md

* fix: Update cache condition for Node dependencies installation
Reorganize the theme's frontend source into a top-level src/ directory
with context-based subdirectories (frontend/, admin/, editor/) that
webpack discovers automatically via readAllFileEntries. This separates
source from compiled output (assets/build/) and removes the need for
manual webpack entry configuration.

- Move CSS and JS source files into src/{css,js}/frontend/
- Add placeholder directories for admin, editor, shared, globals, mixins
- Update readAllFileEntries to scan context subdirectories automatically
- Integrate font copying and SVGO optimization into the webpack pipeline
- Update lint scripts to target src/
- Remove unused cross-env dependency, add copy-webpack-plugin and svgo
- Update README.md and docs to reflect new structure
aryanjasala and others added 15 commits June 4, 2026 18:07
)

Convert the asset-loading mixin into a concrete, injectable class so it
has an instance identity that can be passed around and shared.
Core/Components extends framework ComponentLoader, resolves shared
Assets from container. Override hierarchy child → parent → plugin
falls out of framework — no theme-side path config.
- Util::component() / get_component() back wrappers w/ shared loader
- Core/Assets marked Shareable; registered in Main
- functions.php namespaced; constants via constants(); drop
  custom-functions.php require
- Components: button + card (card nests button via Util::component)
- webpack config + jest tests for components pipeline
Skeleton consumes shared review rules from rtcamp/wp-framework via
npm run sync-ai (chained from npm run init). No Composer hooks →
no install-order coupling.
…er (#709)

Core/Templates extends TemplateLoader, shared via container —
mirrors Core/Components. Theme ships PHP template parts a child
theme overrides; package layer collapses into theme override layer
automatically (child theme > parent theme).
…Encryptor (#713)

Wire theme into instance-based Encryptor — same consumer pattern
as Assets / Components / Templates: context-owned Core service
shared via container, Util wrappers as call surface.
Theme webpack only declared entries for src/css/ + src/js/
{frontend,admin,editor}. src/blocks/ was never compiled —
wp-scripts' inherited CopyPlugin silently copied block.json /
render.php into assets/build/js/blocks/, no edit.js / view.js /
index.js compiled, no *.asset.php emitted.
Replace the bespoke bin/init.js with a thin wrapper that hands bin/scaffold.config.js to the rtcamp/wp-framework scaffold engine.

The config fixes the previously-unrenamed PHP namespace (rtCamp\Theme\Elementary, in both source files and composer.json) and persists identity to .wp-scaffold.json. Add @rtcamp/wp-tooling as a dev dependency and point prepare at sync-ai (dropping the npm-install auto-trigger of init).
Add test matrix for the PHPUnit tests
Add featuresDir + an empty features array so the theme supports manage mode, with a commented Tailwind feature example showing the shape. The Tailwind webpack wiring lands with the Tailwind effort.
Declare the placeholder as a full identity (name + explicit namespace/package) plus namespace()/package() templates, replacing the hand-written extraTokens. Lets the shared engine edit any identity field and rename an already-initialized theme from .wp-scaffold.json.
Replace details() with a fields list (key + label) so the review table and the editor stay in sync. Theme shows all eight fields, including CSS Prefix.
Replace literal handle strings with HANDLE_PREFIX override +
$this->handle( name ) calls. Normalises two off-pattern handles
(core-navigation, elementary-browser-sync) to elementary-theme-
namespace. Nothing depends on old strings — only Assets.php
registered/enqueued them.
@Adi-ty
Adi-ty force-pushed the theme-elementary-v2 branch from 940fb3d to a18a8b0 Compare June 23, 2026 17:25
Adi-ty and others added 14 commits June 24, 2026 05:00
Wire framework FeatureSelector + AbstractFeature into theme. Gate
experimental modules behind opt-in toggles.

- inc/Core/FeatureRegistry.php: extends FeatureSelector, Shareable;
  elementary context; registers author-bio + media-text-interactive
- inc/Abstracts/AbstractThemeFeature.php: extends AbstractFeature;
  wires shared FeatureRegistry once; concrete features extend this
- inc/Modules/Settings/FeaturesSettingsPage.php: extends
  FeatureSelectorSettingsPage; theme-specific titles
- inc/Modules/Shortcodes/AuthorBio.php: extends AbstractThemeFeature
  (was Registrable); gated behind author-bio flag
- inc/Modules/BlockExtensions/MediaTextInteractive.php: same — gated
  behind media-text-interactive
- inc/Helpers/Util.php: is_feature_enabled() hook-time accessor
- Main: register FeatureRegistry + FeaturesSettingsPage
- composer: bump framework to feature-selector main tip
- Tests: registry wiring, key derivation, flag lifecycle, instance
  parity, settings page, gated modules
* feat: wire the Tailwind theme-token webpack plugin when present

Gates GenerateTailwindThemePlugin (from @rtcamp/wp-tooling) on the entry
file src/css/frontend/tailwind.css, guard-requiring wp-tooling so the build
still works when it is absent. Dormant until the Tailwind feature creates
the entry.

* feat(scaffold): add Tailwind CSS opt-in feature

Toggleable in manage mode: copies the entry CSS + PostCSS config and adds
the tailwindcss / @tailwindcss/postcss devDeps; detected via the entry
file. The build side lives in webpack.config.js.

* docs(tailwind): fix stale default-enablement comments

functions.php now defaults ELEMENTARY_THEME_ENABLE_TAILWIND to false (the
scaffold feature flips it); the webpack token plugin is still entry-file gated
at build time, and the wp-tooling catch only skips that plugin, not Tailwind
compilation.

* fix(tailwind): consume @rtcamp/tailwind-config and gate enqueue at runtime

* feat: toggle HMR (BrowserSync) via ENABLE_HMR (#719)

* feat(scaffold): add HMR enable/disable feature

HMR (BrowserSync live reload) is now a toggleable feature, gated on a
single ENABLE_HMR flag in .env.local that both the build and PHP read:

- webpack only starts the BrowserSync server when ENABLE_HMR is not off
- Assets.php only enqueues the client under the same flag
- the scaffold feature flips ENABLE_HMR in .env.local on enable/disable

Default is on, so existing setups are unaffected. browser-sync deps stay
installed (they are dev-only), so the toggle is a fast local switch.
DISABLE_BS still works for the finer client-only case. Toggle from
`npm run init` (manage mode) or by editing .env.local directly.

* test(hmr): cover ENABLE_HMR master switch and DISABLE_BS override

Mirror the plugin skeleton's AssetsHmrTest so the theme's HMR feature has
the same coverage. Exercises the two private env-flag helpers in Assets via
a fresh instance per case (each re-reads .env.local):

- is_hmr_enabled(): defaults on when ENABLE_HMR is absent, off for
  0/false/no/off (case-insensitive), on for 1/true/yes/on
- is_browser_sync_disabled(): independent of HMR; off by default, on for
  truthy DISABLE_BS

Backs up and restores any real .env.local so the developer's file is left
untouched.

* test(hmr): isolate env reads from the real .env.local

* feat(scaffold): mark example sets for selective removal (#720)

Mark the demo modules (media-text block extension, theme options, author bio), example components and page-creation pattern with grouped wp:example markers so init can drop selected sets while keeping the rest. The three Main.php modules use keyed markers to scope their shared regions.

---------

Co-authored-by: Aditya Singh <adityasinghboss1234@gmail.com>

---------

Co-authored-by: Aditya Singh <adityasinghboss1234@gmail.com>
* feat: add AI skills, Logger service, and graphify knowledge graph

Port the AI-tooling layer from the features-plugin-skeleton, reworded for
this theme: init/scaffold/setup skills + Copilot prompts, graphify scripts
and committed graph, and an inc/Core/Logger service with Util accessors.

* docs: add quick-start and internal-testing guides
Resolve conflicts keeping both sides:
- Main.php: Logger (scaffold-engine) + FeatureRegistry/FeaturesSettingsPage (v2); example markers preserved
- Util.php: both logger() and FeatureRegistry accessors
- Assets.php: v2 handle()/HANDLE_PREFIX + scaffold-engine HMR master switch + lazy tailwind
- composer.lock: regenerated against merged composer.json
rtcamp/wp-phpstan is type "library" with no extra.phpstan entry, so
extension-installer reports it as "not supported" and never registers it.
Requiring the package therefore had no effect on PHPStan: none of the
shared baseline's parameters were applied, so #748 adopted the standard
for PHPCS but silently not for PHPStan.

Include the baseline explicitly, as its README and features-plugin-skeleton
both do. The baseline includes szepeviktor/phpstan-wordpress itself and
must load it exactly once, so extension-installer is told to ignore that
package; without the ignore, PHPStan fails on a duplicate include.

level 8 still overrides the baseline's 5 (checked with dump-parameters),
and phpstan reports no errors.
fix: actually load the shared PHPStan baseline
npm runs `prepare` on every install, and composer's post-install-cmd runs
`npm i`, so `composer install` reached bin/init.js -- an interactive
scaffolder that offers to delete the .git directory.

It does not disarm itself either. installHusky() reads the existing
prepare script, lets `npx husky init` overwrite it, then appends the old
value back:

    packageJson.scripts.prepare += ` && ${prepareScript}`

so a scaffolded project ends up with `husky && npm run init` and re-runs
the scaffolder on every install from then on.

Point prepare at sync-ai instead, which is what actually needs to run
after each install; it exits 0 whether or not the framework is present.
The append above then produces `husky && npm run sync-ai`, which is
correct. Scaffolding stays available as an explicit `npm run init`, and
features-plugin-skeleton keeps init out of prepare the same way.
Brings the branch up to date with the six commits merged since 2026-06-24
(#737, #746, #747, #748 and follow-ups) and fixes what that surfaced.

Conflicts:
  .gitignore   kept this branch's graphify-out rules; the base added nothing.
  README.md    took the base's rewritten README and re-applied this branch's
               one addition, the "AI tooling" section.
  package.json union of both sides: the base's @rtcamp/eslint-config and
               @rtcamp/stylelint-config, plus this branch's script changes.

Also:

- @rtcamp/wp-tooling was pinned to "^0.1.0", a registry range for a package
  that is not published (npm 404s it), so `npm install` could not succeed.
  Point it at the branch split, as features-plugin-skeleton does.

- Drop the GitHub Packages registry lines from .npmrc. All three @rtCamp
  dependencies now resolve from git branch refs, so no scope registry and no
  read:packages token is needed. The file's own TODO asked for this.

- Regenerate package-lock.json. Git text-merged the two lock files, which
  left it internally inconsistent (@emnapi entries missing), and `npm ci
  --ignore-scripts` -- what the setup-node-with-cache action runs -- failed
  on it. Rebuilt from scratch; `npm ci` now succeeds.

- phpcbf the PHP added on this branch: it predates the rtCampWP standard
  adopted in #748, which found 8 fixable violations across 5 files
  (import ordering, useless return annotations, class-brace and parent-call
  spacing).

- Scope WordPressVIPMinimum.Performance.FetchingRemoteData off tests/*. The
  new LoggerTest reads a local fixture with file_get_contents; the caching
  advice is about remote URLs. Mirrors the exclusion #748 added for
  WordPressVIPMinimum.Functions.RestrictedFunctions.

Verified: npm ci, npm run init -- --help, lint:js, lint:css, phpcs (0/0),
phpstan (no errors), and a non-interactive scaffold via
`node bin/init.js --name="Acme Portfolio" --yes`.
fix: stop running the scaffolder from the prepare hook
feat(scaffold): delegate theme setup to the shared wp-framework engine
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants