Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
58c22b7
feat: remove old/deprecated files
May 7, 2025
80c2645
feat: init commit of rebuilt theme that is inline with other base themes
May 7, 2025
84b340e
feat: re-organize default templates, auto-register blocks, and twig n…
Jun 5, 2025
6ee5d00
chore: align release metadata for 2.0
Jun 27, 2026
644f78f
ci: replace release workflow for wordpress
Jun 27, 2026
2f9c8ff
test: add wordpress release readiness checks
Jun 27, 2026
6ac9313
feat: upgrade whisk starter to emulsify core 4
Jun 27, 2026
d924e9d
feat: align whisk starter structure with emulsify drupal
Jun 27, 2026
2c1af61
feat: rebuild timber theme bootstrap
Jun 27, 2026
308cb95
fix: implement timber attribute helpers
Jun 27, 2026
7decd36
feat: refine timber template defaults
Jun 27, 2026
0d639fe
feat: load core 4 theme assets
Jun 27, 2026
6e0967f
feat: separate timber and gutenberg block registration
Jun 27, 2026
495c583
test: add wordpress theme smoke coverage
Jun 27, 2026
ac7af7f
docs: document wordpress 2.0 workflow
Jun 27, 2026
c6bbe40
feat(theme): harden parent runtime services
Jun 27, 2026
dddcfa7
feat(starter): simplify Whisk child theme
Jun 27, 2026
8a9846b
docs: document WordPress 2.0 release model
Jun 27, 2026
7dfec74
ci(release): add WordPress release validation
Jun 27, 2026
61f6925
chore(deps): resolve release audit blockers
Jun 27, 2026
5481570
docs: add WordPress sister-project parity contract
Jun 27, 2026
9e5c764
ci(wordpress): add theme readiness validation
Jun 27, 2026
471c69b
chore(wordpress): use wordpress platform adapter
Jun 27, 2026
cbb2d51
test(wordpress): expand generated child fixture smoke
Jun 27, 2026
196f6a7
feat(twig): support project component references
Jun 28, 2026
5b545e9
feat(theme): add editor services and agnostic starter
Jun 28, 2026
d6171c1
refactor(whisk): keep starter source agnostic
Jun 28, 2026
a34c7dc
refactor(theme): improve parent template maintainability
Jun 28, 2026
b57e20c
feat(starter): support standalone wordpress starter
Jun 28, 2026
0ac719e
chore: adjust wordpress spelling and repo url references
Jun 29, 2026
afd7d43
fix: tighten composer stability settings
Jun 29, 2026
4daaf96
docs: clarify wordpress install workflows
Jun 29, 2026
cd9249e
fix: guard child theme force replacement
Jun 29, 2026
46bf29a
docs: document wordpress fixture release gate
Jun 29, 2026
fa897b6
feat: add generated child theme metadata
Jun 29, 2026
9fc90aa
docs: add wordpress component recipes
Jun 29, 2026
6d25eb7
docs: add post 2x optimization roadmap
Jul 6, 2026
099c594
refactor: add runtime autoloading
Jul 6, 2026
cb47609
refactor: group runtime services by domain
Jul 6, 2026
9d3a0e8
refactor: consolidate theme file discovery
Jul 6, 2026
ae9e15f
feat: support optional asset manifest loading
Jul 6, 2026
c57ef89
feat: support block scoped assets
Jul 6, 2026
f4b646a
feat: add optional component discovery cache
Jul 6, 2026
62cf982
refactor: split editor policy services
Jul 7, 2026
dcb451b
feat: support pattern category metadata
Jul 7, 2026
855199b
fix(blocks): use block-scoped acf field values in twig context
Jul 8, 2026
56a258a
refactor(support): consolidate shared asset and diagnostics helpers
Jul 8, 2026
8e3f716
perf(runtime): memoize manifest reads and asset discovery per request
Jul 8, 2026
5c5f378
perf(blocks): enable discovery caching by default outside development
Jul 8, 2026
1ac5c8a
refactor(twig): extract project component loader and config reader
Jul 8, 2026
9cc26ea
chore: remove dead compatibility shims and unused release tooling
Jul 8, 2026
44aa226
docs: refresh architecture docs and add index
Jul 8, 2026
9bd0c51
chore(lint): adopt phpcs wpcs and phpstan for runtime php
Jul 8, 2026
fe44d10
ci(release): force wordpress 2.0 stable release
Jul 8, 2026
d136804
feat(twig): add switch case tags
Jul 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 4 additions & 3 deletions .browserslistrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Browsers that we support

last 1 version
> 1%
maintained node versions
last 2 versions
Firefox ESR
Chrome 41 # Support for Googlebot
not dead
ie 11
not IE 9-11 # For IE 9-11 support, remove 'not'.
35 changes: 0 additions & 35 deletions .eslintrc.yml

This file was deleted.

11 changes: 11 additions & 0 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Emulsify WordPress version (see [releases](https://github.com/emulsify-ds/emulsify-wordpress/releases)):

**What you did:**

**What happened:**

**Reproduction repository (if necessary):**

**Problem description:**

**Suggested solution:**
13 changes: 13 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
**This PR does the following:**
- Adds functionality bullet item
- Fixes this or that bullet item

### Related Issue(s)
- [Title of the issue](https://github.com/emulsify-ds/emulsify-wordpress/issues/1) (if applicable)

### Notes:
- (optional) Document any intentionally unfinished parts or known issues within this PR

### Functional Testing:
- [ ] Document steps that allow someone to fully test your code changes. Include screenshot and links when appropriate.
- [ ] For the 2.0 release branch merge, run the manual `WordPress Theme Readiness` workflow on `release-2.x` with `wordpress_fixture` enabled and confirm both `Practical theme readiness` and `WordPress fixture smoke` pass. Mark N/A for routine PRs.
216 changes: 216 additions & 0 deletions .github/scripts/acf-local-json-smoke.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
<?php
/**
* Smoke checks for ACF Local JSON path integration.
*
* @package Emulsify
*/

if ( PHP_SAPI !== 'cli' ) {
fwrite( STDERR, "This script must be run from the command line.\n" );
exit( 1 );
}

$GLOBALS['emulsify_acf_json_smoke_filters'] = array();

if ( ! function_exists( 'add_filter' ) ) {
function add_filter( string $hook, callable $callback, int $priority = 10, int $accepted_args = 1 ): bool {
$GLOBALS['emulsify_acf_json_smoke_filters'][ $hook ][ $priority ][] = array(
'accepted_args' => $accepted_args,
'callback' => $callback,
);

ksort( $GLOBALS['emulsify_acf_json_smoke_filters'][ $hook ] );

return true;
}
}

if ( ! function_exists( 'apply_filters' ) ) {
function apply_filters( string $hook, $value, ...$arguments ) {
if ( empty( $GLOBALS['emulsify_acf_json_smoke_filters'][ $hook ] ) ) {
return $value;
}

foreach ( $GLOBALS['emulsify_acf_json_smoke_filters'][ $hook ] as $callbacks ) {
foreach ( $callbacks as $callback ) {
$value = call_user_func_array(
$callback['callback'],
array_slice(
array_merge( array( $value ), $arguments ),
0,
$callback['accepted_args']
)
);
}
}

return $value;
}
}

if ( ! function_exists( 'get_stylesheet_directory' ) ) {
function get_stylesheet_directory(): string {
return $GLOBALS['emulsify_acf_json_smoke_child'];
}
}

/**
* Fails the smoke script when an assertion is false.
*
* @param bool $condition Assertion condition.
* @param string $message Failure message.
* @return void
*/
function emulsify_acf_json_smoke_assert( bool $condition, string $message ): void {
if ( ! $condition ) {
throw new RuntimeException( $message );
}
}

/**
* Recursively removes a path.
*
* @param string $path Path to remove.
* @return void
*/
function emulsify_acf_json_smoke_remove( string $path ): void {
if ( ! file_exists( $path ) ) {
return;
}

if ( is_file( $path ) || is_link( $path ) ) {
unlink( $path );
return;
}

$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator( $path, RecursiveDirectoryIterator::SKIP_DOTS ),
RecursiveIteratorIterator::CHILD_FIRST
);

foreach ( $iterator as $item ) {
$item->isDir() && ! $item->isLink() ? rmdir( $item->getPathname() ) : unlink( $item->getPathname() );
}

rmdir( $path );
}

$repo_root = dirname( __DIR__, 2 );
$work_root = sys_get_temp_dir() . '/emulsify-acf-local-json-' . uniqid( '', true );
$child = $work_root . '/child-theme';
$default = $child . '/config/acf-json';
$custom = $work_root . '/custom-acf-json';
$extra = $work_root . '/extra-acf-json';

$GLOBALS['emulsify_acf_json_smoke_child'] = $child;

try {
require_once $repo_root . '/includes/Acf/LocalJson.php';

$inactive = new Emulsify\Theme\Acf\LocalJson();
$inactive->register();

emulsify_acf_json_smoke_assert(
empty( $GLOBALS['emulsify_acf_json_smoke_filters']['acf/settings/save_json'] )
&& empty( $GLOBALS['emulsify_acf_json_smoke_filters']['acf/settings/load_json'] ),
'ACF Local JSON service should not register ACF filters when ACF is unavailable.'
);

if ( ! function_exists( 'acf' ) ) {
function acf(): bool {
return true;
}
}

$service = new Emulsify\Theme\Acf\LocalJson();
$service->register();

emulsify_acf_json_smoke_assert(
isset( $GLOBALS['emulsify_acf_json_smoke_filters']['acf/settings/save_json'] )
&& isset( $GLOBALS['emulsify_acf_json_smoke_filters']['acf/settings/load_json'] ),
'ACF Local JSON service should register ACF filters when ACF is available.'
);

$incoming_save = '/acf/default-save';
$incoming_load = array( '/acf/default-load' );

emulsify_acf_json_smoke_assert(
$incoming_save === apply_filters( 'acf/settings/save_json', $incoming_save ),
'ACF Local JSON save path should no-op when config/acf-json is missing.'
);
emulsify_acf_json_smoke_assert(
$incoming_load === apply_filters( 'acf/settings/load_json', $incoming_load ),
'ACF Local JSON load paths should no-op when config/acf-json is missing.'
);

if ( ! mkdir( $default, 0777, true ) || ! mkdir( $custom, 0777, true ) || ! mkdir( $extra, 0777, true ) ) {
throw new RuntimeException( 'Could not create ACF JSON smoke fixture directories.' );
}

emulsify_acf_json_smoke_assert(
$default === apply_filters( 'acf/settings/save_json', $incoming_save ),
'ACF Local JSON save path should use child config/acf-json by default.'
);
emulsify_acf_json_smoke_assert(
array( '/acf/default-load', $default ) === apply_filters( 'acf/settings/load_json', $incoming_load ),
'ACF Local JSON load paths should keep the default path and add child config/acf-json.'
);

add_filter(
'emulsify_theme_acf_json_remove_default_load_path',
static function (): bool {
return true;
}
);

emulsify_acf_json_smoke_assert(
array( $default ) === apply_filters( 'acf/settings/load_json', $incoming_load ),
'ACF Local JSON should remove the default load path only when explicitly configured.'
);

add_filter(
'emulsify_theme_acf_json_save_path',
static function () use ( $custom ): string {
return $custom;
}
);

add_filter(
'emulsify_theme_acf_json_load_paths',
static function ( array $paths ) use ( $extra ): array {
$paths[] = $extra;

return $paths;
}
);

emulsify_acf_json_smoke_assert(
$custom === apply_filters( 'acf/settings/save_json', $incoming_save ),
'ACF Local JSON save path filter should override the default save path.'
);
emulsify_acf_json_smoke_assert(
array( $custom, $extra ) === apply_filters( 'acf/settings/load_json', $incoming_load ),
'ACF Local JSON load paths filter should alter final load paths.'
);

add_filter(
'emulsify_theme_acf_json_enabled',
static function (): bool {
return false;
},
1
);

emulsify_acf_json_smoke_assert(
$incoming_save === apply_filters( 'acf/settings/save_json', $incoming_save )
&& $incoming_load === apply_filters( 'acf/settings/load_json', $incoming_load ),
'ACF Local JSON enabled filter should disable all path changes.'
);

echo "ACF Local JSON smoke checks passed.\n";
} catch ( Throwable $throwable ) {
fwrite( STDERR, $throwable->getMessage() . "\n" );
exit( 1 );
} finally {
emulsify_acf_json_smoke_remove( $work_root );
}
Loading