Skip to content

PageTypes

PageTypes are a way to define different types of pages in your project. Each PageType controller is responsible for rendering a specific type of page, such as a blog post, a product page, etc, and carries metadata about the page type, such as the path prefix.

All PageType controllers are stored in their own directory structure under ./src/Controller/PageTypes/.

Default PageType Controllers

The default PageType controller is ./src/Controller/PageTypes/Web/WebPage.php. This controller will respond to all URLs unless another controller matches the request.

There is also a ./src/Controller/PageTypes/Blog/BlogPage.php controller that can be leveraged for blog posts.


Creating a New PageType

When to Create a New PageType

Before creating a new PageType, consider whether you need to create a new controller for it. If you do not need custom rendering logic or a separate url path prefix for this set of pages, you can simply create new pages in the administration panel and assign them to parent pages as needed.

You can create a new PageType controller by issuing the following command:

ddev symfony console make:page:type
This command will prompt you for information about your new page type and then create a new controller in the ./src/Controller/PageTypes/ directory. You can then modify the controller to render the page type as needed.

Page types will appear in the administration panel as tabs to make managing them easier for the user:

Page Types

Editing the PageType

Once you have created a new PageType controller, you can edit it by opening it from the ./src/Controller/PageTypes/ directory in your code editor. This generated class can be treated like any other Symfony controller, and comes with two generated methods and associated url paths by default:

  • index: This method is called when the user visits the main page of this type (e.g. /my-awesome-type). You can use this method to render a list of pages of this type or any other content you want to display on the main page.

  • view: This method is called when the user visits a specific page of this type (e.g. /my-awesome-type/my-first-page). You can use this method to render the content of the specific page, including any sections that are assigned to it.

While the generated methods are a good starting point, you are free to change the methods as needed to fit your requirements. You can add additional methods, change the routing, or modify the logic to suit your needs.

You will also see a PageTypeDefinition attribute at the top of the class that holds your PageType's metadata. This metadata is synchronized to the database and is used to display details in the administration panel and when new page URLs are generated for this type.

Generated PageType Example
<?php  /* Generated with make:page:type */

#[PageTypeDefinition(
    uuid: 'e61656b8-785d-41e6-a603-0ee1cd83e166',
    iconHTML: '<i class="fa-solid fa-cube"></i>',
    name: 'My Awesome Type',
    description: 'This is a test page type for demonstration purposes',
    pathPrefix: '/my-awesome-type',
    enabled: true
)]
class MyAwesomeTypePage extends AbstractController
{
    public function __construct(
        readonly private PageBuilder    $pageBuilder,
        readonly private PageRepository $pageRepository,
        readonly private PageParameters $pageParameters,
    ) {}

    private function getHeaderAndFooter(Request $request, ?Page $page): array
    {
        // ...
        // helper function to get the built-in header and footer
    }

    #[
        Route(
            path: "/my-awesome-type",
            name: "__my_awesome_type",
        )
    ]
    final public function index(Request $request): Response
    {
        // ...
        // logic to handle the main index page of this type (/my-awesome-type)
    }

    #[
        Route(
            path: "/my-awesome-type/{slug}",
            name: "__my_awesome_type_view",
            requirements: [
                'slug' => '.+' # allows nested paths to match
            ],
        )
    ]
    final public function view(Request $request, string $slug): Response
    {
        // ...
        // logic to handle viewing a specific page of this type (/my-awesome-type/{slug})
    }
}

Saving Changes to a PageType

Whenever you modify a PageType's PageTypeDefinition attribute, you will need to synchronize changes to the database. This is done by running the following command:

ddev symfony console app:sync

Deleting a PageType

Because PageType controllers are registered to the database, they are given a UUID for mapping purposes. To delete a PageType controller, you will need to grab the UUID of the controller you want to delete from the PageTypeDefinition portion of the code.

ddev symfony console unmake:page:type
This command will prompt you for the UUID of the PageType controller you want to delete. Once you provide the UUID, the command will remove the controller from the code base and also remove the associated PageType from the database.


Using PageTypes for Organization Only

You can use PageType controllers to separate pages in the administration panel, even if you do not want to supply custom rendering logic. Simply generate a PageType controller and remove the view and index methods (along with their routing attributes). This will allow you to create pages of this type in the administration panel that fall back to the default WebPage controller for rendering.