Skip to content

Implemented theme architecture - #12

Open
Shifrin wants to merge 4 commits into
mainfrom
issue-1-theme-preapre
Open

Shifrin wants to merge 4 commits into
mainfrom
issue-1-theme-preapre

Conversation

@Shifrin

@Shifrin Shifrin commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Implemented theme, template overrides and asset publishing architecture.

- Manifest-driven (PHP-less) themes loaded from `theme.json` via ThemeFactory
  and ThemeManifestValidator; generic Theme with template path/map support
- ThemeResolver (default vs active resolution) and ThemeLoader
- ThemeConfig and ThemeAssetsProvider (hash of the theme identity -> dist/)
- Contracts: ThemeInterface, ThemeConfigInterface, ThemeResolverInterface,
  AssetsProviderInterface
- Value objects ThemeSlug and TemplatePath with their exceptions
- Hash value object used by the theme assets provider
- `themesPath` support in Config/ConfigInterface
- ArraySearchHelper: return the default when a dotted-path leaf already
  exists but is not an array (fixes null-valued theme config keys)
- Unit tests and fixtures for the whole theme subsystem

Signed-off-by: Mohammed Shifreen <mshifreen@gmail.com>
- TemplateMapOverrides: app-level overrides merged with the theme template
  maps, cached per extension with a content-addressed PSR-6 cache key (bound
  to the app override + current theme maps, so stale entries are never served)
- TemplateResolver: resolves the candidate template paths for an extension,
  override candidates first, then the extension's own template path as the
  final fallback
- TemplateRendererInterface: the rendering contract (implementation to come)
- TemplateNotFoundException for missing view files
- Extended ExtensionInterface with getSlug(), getTemplatePath() and
  getAssetsProvider(); updated the ExampleExtension test fixture accordingly
- Unit tests for the override map and template resolver

Signed-off-by: Mohammed Shifreen <mshifreen@gmail.com>
- AssetsPublisher: publishes an AssetsProviderInterface bundle into the
  public webroot under public/assets/<hash>/, fingerprinted with a
  completion marker so republishing the same content is a no-op and stale
  or partial targets are reconciled
- AssetPublishException with translatable factory methods
- BaseUrl: parses a loosely specified base URL config value (scheme, host,
  port, path prefix) once at boot, with BaseUrlConfigurationException
- UrlGenerator: named-route, ResourcePath and plain-path URL resolution in
  Relative/Absolute/NetworkPath forms (UrlType)
- AssetsPipelineInterface and AssetsPublisherInterface contracts; ResourcePath
  abstract value object
- View: template rendering view service composing the renderer, URL
  generator and asset pipeline, with layout/extension context
- Unit tests for all of the above, including the ExampleResourcePath fixture

Signed-off-by: Mohammed Shifreen <mshifreen@gmail.com>
Definitions & DI rework:
- Introduced DefinitionsInterface plus grouped definition classes under
  Container/Definitions (Console, Event, Http, Logging, Service); removed the
  flat src/Infrastructure/definitions.php
- BaseService replaces BaseServiceProvider: merges the grouped definitions
  and bootstraps asset publishing for the active theme and configured
  extensions
- PhpDiContainerBuilder now loads and wires the configured themes (ThemeLoader/
  ThemeResolver/ThemeFactory) and wraps build failures in ContainerException;
  ContainerBuilderInterface moved from Container/ to Contract/

Supporting pieces:
- Escaper helper + layer-agnostic EscaperInterface (Contract), wired in the
  HTTP definitions
- ExtensionSlug value object and InvalidExtensionSlugException
- AGENTS.md at the repository root

Dependencies & tooling:
- composer.json now declares psr/cache and symfony/filesystem directly and
  bumps PHPUnit (lock updated); version 0.1.0-alpha; dropped the dev/ autoload
  path
- Updated PHPStan, Rector and PHP-CS-Fixer configuration

Cleanup:
- License header sweep across src/ and test/ (webifycms.com/extension/base/license
  to webifycms.com/license)
- Removed the unused duplicate Infrastructure\Contract\EscaperInterface and
  fixed a stale docblock in BaseServiceTest

Signed-off-by: Mohammed Shifreen <mshifreen@gmail.com>
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.

1 participant