Instruction file imported from rcarvello/webmvcframework (
.github/instructions/framework-content-components.instructions.md). Copyright stays with the author.
Framework Content And Components Instructions
These are framework-level instructions for content composition and selected components.
examples/cms remains the canonical reference implementation for these WebMVC capabilities:
- blocks and placeholders
- nested blocks
- OOP usage at controller level (for example
BlockExtended) - multilingual pages via
locales/and{RES:...}resources (assembly-specific and application-global) - composed pages (HMVC) built from multiple assemblies/controllers
- static assembly replacement patterns
- TreeStructure component usage
Wiki References (md)
When a task touches one of these capabilities, consult the corresponding wiki pages in md/ first:
- Framework overview and architecture:
md/Understanding-WebMVC.mdmd/Software-decomposition-and-System-Architecture.md
- Controller OOP patterns and lifecycle:
md/Controller.mdmd/Controller-and-OOP.mdmd/Controller-autorun-method.md
- Views, placeholders, and dynamic template content:
md/View.mdmd/Handling-placeholders.mdmd/Dynamic-Content.md
- Blocks, nested blocks, and block replacement/hiding:
md/Handling-blocks.mdmd/Nesting-of-blocks.mdmd/Insight-about-nesting-of-blocks.mdmd/Hiding-and-replacing-the-content-of-a-block.md
- HMVC/composed pages and decomposition:
md/Content-based-decomposition-and-HMVC.mdmd/Role-Based-Decomposition.mdmd/Skills-and-technologies-decomposition.md
- Localization and resource placeholders
{RES}:md/Decomposition-by-Internationalization--and-Localization.md
- Components and reusable framework elements:
md/Using-Components.mdmd/Component-Based-Development.mdmd/DataRepeater.md
Reference Scope
- Treat
examples/cmsas the canonical showcase for page-oriented WebMVC features rather than DB CRUD. - Prefer these examples when the task involves:
- template placeholders
- blocks and nested blocks
- controller composition
- alternate templates
- localization
- reusable controllers or components
- For changes outside
examples/cms, reuse these patterns as conceptual framework guidance and adapt namespaces/routes to the target assembly.
Standard Assembly Structure
- Most
examples/cmsassemblies follow the aligned 4-artifact pattern:controllers/examples/cms/Name.phpmodels/examples/cms/Name.phpviews/examples/cms/Name.phptemplates/examples/cms/name.html.tpl
- Namespace must reflect the folder structure exactly.
- View constructors should point to template paths like
/examples/cms/name.
Canonical Controller Pattern
- The common controller structure is:
- optional injected
?View $viewand?Model $model - assign concrete model and view in the constructor
- call
parent::__construct($this->view, $this->model) - keep
autorun()as the main initialization point
- optional injected
- Controllers in
examples/cmsare typically GET page controllers. - Public methods often demonstrate URL-invocable actions such as alternate rendering, block hiding, or dynamic binding.
Minimal controller pattern:
public function __construct(?View $view = null, ?Model $model = null)
{
$this->view = empty($view) ? $this->getView() : $view;
$this->model = empty($model) ? $this->getModel() : $model;
parent::__construct($this->view, $this->model);
}
protected function autorun($parameters = null)
{
// initialize page state here
}
Canonical View Pattern
- Views should wrap placeholder and block operations into semantic methods such as:
setMessage(...)setUsers(...)openBlockUsers()openBlockNames()
- Prefer explicit view methods over filling placeholders directly from controllers when the template logic is non-trivial.
Template Placeholders And Blocks
- Use simple placeholders for scalar values:
{Message}{BodyMessage}
- Use block syntax for repeated content:
<!-- BEGIN Users -->
<tr>
<td>{FirstName}</td>
<td>{LastName}</td>
</tr>
<!-- END Users -->
- Nested blocks are supported and shown by
InnerBlocks. - Blocks can be hidden by controller or view logic using
hide(...).
Canonical Examples By Feature
- Basic MVC placeholder flow:
HelloWorld
- Alternate template loading and page variants:
HelloWorldSecond
- Basic repeated blocks:
Block
- Manual block population and DataRepeater comparison:
HelloBlockBlockDataRepeater
- Inheritance and alternate template variants:
BlockExtended
- Nested blocks:
InnerBlocks
- Controller composition / composite pages:
CompositePage
- Dynamic child controller binding:
DynamicBinding
- Localization and locale-dependent content:
Localization
- Reusable child controller as page fragment:
NavigationBar
- Component usage:
TreeDemoCaptchaComponent
- Static or near-static content replacement:
StaticReplacement
Dynamic Binding Rules
- Use
bindController(...)when one controller must be rendered inside another controller's template. - Use a named placeholder binding when the destination is dynamic in the template.
DynamicBindingis the reference example.
Example pattern:
$this->hide("Info");
$controller = new HelloWorld();
$this->bindController($controller, "whitchController");
$this->render();
Composite Page Rules
CompositePageis the reference when a page includes reusable child controllers such asNavigationBar.- Prefer composition over duplicating repeated page fragments in multiple templates.
- For HMVC composition, keep child controllers reusable and parent-driven: instantiate in the parent
autorun(), then bind withbindController(...).
Example pattern:
$navigation = new NavigationBar();
$this->bindController($navigation);
HMVC Localization Rules (#Load)
- When a parent assembly binds a child controller that uses
{RES:...}placeholders (for exampleNavigationBar), the parent locale file must import child locale resources via#Load:. - Use fully qualified locale paths including
.txtto avoid ambiguous loading. - Add one
#Loadper active locale, for example:#Load:locales/en/controllers/examples/cms/NavigationBar.txt#Load:locales/it-it/controllers/examples/cms/NavigationBar.txt
- Keep shared text in child locale files and avoid copying the same keys into every parent assembly.
- If
{RES:...}renders literally in output, treat missing/incorrect#Load:as the first diagnostic check.
Alternate Template Rules
- If the same controller/view logic must render a different presentation, use
loadCustomTemplate(...). HelloWorldSecondandBlockExtendedare the canonical examples.- For compatibility migrations (for example Bootstrap 3 to Bootstrap 5), keep legacy templates untouched and create a
new static template variant, then switch at runtime using
loadCustomTemplate(...).
Example pattern:
$this->view->loadCustomTemplate("templates/examples/cms/hello_world_mobile");
HMVC child override example:
$navigation = new NavigationBar();
$navigation->view->loadCustomTemplate('templates/examples/cms/navigation_bar_bs5');
$this->bindController($navigation);
Localization Rules
Localizationis the canonical reference for locale-dependent page content.- Use
{RES:...}placeholders in templates for resource-driven text. - Localization resources may be scoped to a specific assembly and can also be defined globally at application level.
- Keep locale files under
locales/and keep resource keys stable across templates/controllers. - If model content depends on locale, pass the active locale or read the locale request parameter consistently with the framework example.
Component Rules
- Use
bindComponent(...)for framework components that are not standalone controllers. TreeDemoandCaptchaComponentare the reference examples.- Treat
TreeDemoas the reference for TreeStructure component integration patterns. BlockDataRepeateris the reference when usingframework\components\DataRepeaterinside CMS-style page assembly logic.
Practical Guidance
- If the task is about page composition, start from
CompositePageorDynamicBinding. - If the task is about repeated HTML sections, start from
Block,HelloBlock, orInnerBlocks. - If the task is about visual variants, start from
HelloWorldSecondorBlockExtended. - If the task is about localized CMS pages, start from
Localization. - If the task is outside
examples/cmsbut concerns framework capabilities listed above, still apply these rules and examples as the primary implementation guideline, then map them to the target namespace. - Keep these examples educational and focused: avoid mixing DB CRUD patterns from
examples/dbintoexamples/cmsunless the task explicitly asks for that crossover.