{"id":18772230,"url":"https://github.com/doctrine/symfony-doctrine-static-website-generator","last_synced_at":"2025-07-24T23:07:47.467Z","repository":{"id":66084632,"uuid":"153563527","full_name":"doctrine/symfony-doctrine-static-website-generator","owner":"doctrine","description":null,"archived":false,"fork":false,"pushed_at":"2018-10-22T23:27:41.000Z","size":32,"stargazers_count":14,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-05T15:51:25.458Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/doctrine.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-10-18T04:27:11.000Z","updated_at":"2024-03-21T17:34:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"e724e5e5-a299-498d-ab94-1ffad1acc2ed","html_url":"https://github.com/doctrine/symfony-doctrine-static-website-generator","commit_stats":{"total_commits":5,"total_committers":1,"mean_commits":5.0,"dds":0.0,"last_synced_commit":"ffc614f8078c5f0519e6ef7afe72d8bf543b9336"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doctrine%2Fsymfony-doctrine-static-website-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doctrine%2Fsymfony-doctrine-static-website-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doctrine%2Fsymfony-doctrine-static-website-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doctrine%2Fsymfony-doctrine-static-website-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/doctrine","download_url":"https://codeload.github.com/doctrine/symfony-doctrine-static-website-generator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248678021,"owners_count":21144200,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T19:28:14.797Z","updated_at":"2025-04-13T07:32:54.119Z","avatar_url":"https://github.com/doctrine.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Symfony \u0026 Doctrine Static Website Generator\n\nThis is an example Symfony Flex application which pulls together the following\npackages to create a static website generator:\n\n- [doctrine/skeleton-mapper](https://github.com/doctrine/skeleton-mapper)\n- [doctrine/static-website-generator](https://github.com/doctrine/static-website-generator)\n- [doctrine/doctrine-skeleton-mapper-bundle](https://github.com/doctrine/DoctrineSkeletonMapperBundle)\n- [doctrine/doctrine-static-website-generator-bundle](https://github.com/doctrine/DoctrineStaticWebsiteGeneratorBundle)\n\n## Setup\n\nFirst clone the repository:\n\n    $ git clone git@github.com:jwage/symfony-doctrine-static-website-generator.git\n\nNow run composer install:\n\n    $ cd symfony-doctrine-static-website-generator\n    $ composer install\n\n## Building\n\nNow you are ready to build the example static website:\n\n    $ php bin/console doctrine:build-website\n\n## Usage\n\n### Routes\n\nTake a look at the parameter named `doctrine.static_website.routes` in [config/routes.yml](https://github.com/jwage/symfony-doctrine-static-website-generator/blob/master/config/services.yaml)\nfor defining routes for your static website.\n\n```yaml\nparameters:\n    doctrine.static_website.routes:\n        homepage:\n            path: /index.html\n            controller: App\\Controller\\UserController::index\n\n        user:\n            path: /user/{username}.html\n            controller: App\\Controller\\UserController::user\n            provider: App\\Requests\\UserRequests::getUsers\n```\n\n### Controllers\n\nIn your `src/Controller` directory, you can create plain old PHP classes for controllers and map them\nusing routes.\n\nOnce you have created a controller, you have to configure a `ControllerProvider` in the\n`config/services.yaml` file and pass it your controllers:\n\n```yaml\nservices:\n    # ...\n\n    Doctrine\\StaticWebsiteGenerator\\Controller\\ControllerProvider:\n        arguments:\n            -\n                - '@App\\Controller\\UserController'\n\n```\n\nHere is what the `UserController` looks like:\n\n```php\n\u003c?php\n\nnamespace App\\Controller;\n\nuse App\\Models\\User;\nuse App\\Repositories\\UserRepository;\nuse Doctrine\\StaticWebsiteGenerator\\Controller\\Response;\n\nclass UserController\n{\n    /** @var UserRepository */\n    private $userRepository;\n\n    public function __construct(UserRepository $userRepository)\n    {\n        $this-\u003euserRepository = $userRepository;\n    }\n\n    public function index() : Response\n    {\n        $users = $this-\u003euserRepository-\u003efindAll();\n\n        return new Response([\n            'users' =\u003e $users\n        ]);\n    }\n\n    public function user(string $username) : Response\n    {\n        $user = $this-\u003euserRepository-\u003efindOneByUsername($username);\n\n        return new Response([\n            'user' =\u003e $user,\n        ], '/user.html.twig');\n    }\n}\n```\n\n### Data Sources\n\nData sources are a simple way to use a PHP service to provide data for a Doctrine Skeleton Mapper model. They\nare contained in the `src/DataSources` directory and must implement the `Doctrine\\SkeletonMapper\\DataSource\\DataSource`\ninterface.\n\nHere is what the `Users` data source looks like:\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace App\\DataSources;\n\nuse Doctrine\\SkeletonMapper\\DataSource\\DataSource;\n\nclass Users implements DataSource\n{\n    /**\n     * @return mixed[][]\n     */\n    public function getSourceRows() : array\n    {\n        return [\n            ['username' =\u003e 'jwage'],\n            ['username' =\u003e 'ocramius'],\n            ['username' =\u003e 'ccovey'],\n        ];\n    }\n}\n```\n\n### Models\n\nModels are contained in the `src/Models` directory and are plain PHP classes\nthat must implement the following interfaces:\n\n- `Doctrine\\SkeletonMapper\\Hydrator\\HydratableInterface`\n- `Doctrine\\SkeletonMapper\\Mapping\\LoadMetadataInterface`\n\nHere is what the `User` model looks like:\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Models;\n\nuse Doctrine\\SkeletonMapper\\Hydrator\\HydratableInterface;\nuse Doctrine\\SkeletonMapper\\Mapping\\ClassMetadataInterface;\nuse Doctrine\\SkeletonMapper\\Mapping\\LoadMetadataInterface;\nuse Doctrine\\SkeletonMapper\\ObjectManagerInterface;\n\nclass User implements HydratableInterface, LoadMetadataInterface\n{\n    /** @var string */\n    private $username;\n\n    public static function loadMetadata(ClassMetadataInterface $metadata) : void\n    {\n        $metadata-\u003esetIdentifier(['username']);\n    }\n\n    /**\n     * @param mixed[] $user\n     */\n    public function hydrate(array $user, ObjectManagerInterface $objectManager) : void\n    {\n        $this-\u003eusername = (string) ($user['username'] ?? '');\n    }\n\n    public function getUsername() : string\n    {\n        return $this-\u003eusername;\n    }\n}\n```\n\n### Object Repositories\n\nObject Repositories are contained in the `src/Repositories` directory and must extend the\n`Doctrine\\SkeletonMapper\\ObjectRepository\\BasicObjectRepository` class.\n\nHere is what the `UserRepository` looks like:\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Repositories;\n\nuse App\\Models\\User;\nuse Doctrine\\SkeletonMapper\\ObjectRepository\\BasicObjectRepository;\n\nclass UserRepository extends BasicObjectRepository\n{\n    public function findOneByUsername(string $username) : User\n    {\n        /** @var User $user */\n        $user = $this-\u003efindOneBy(['username' =\u003e $username]);\n\n        return $user;\n    }\n}\n```\n\n### Requests\n\nYou can dynamically generate static content by using a route, controller and provider. Take this `user` route\nfor example:\n\n```yaml\nparameters:\n    doctrine.static_website.routes:\n        # ...\n\n        user:\n            path: /user/{username}.html\n            controller: App\\Controller\\UserController::user\n            provider: App\\Requests\\UserRequests::getUsers\n```\n\nNote the `App\\Requests\\UserRequests` class:\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Requests;\n\nuse App\\Models\\User;\nuse App\\Repositories\\UserRepository;\nuse Doctrine\\StaticWebsiteGenerator\\Request\\ArrayRequestCollection;\nuse Doctrine\\StaticWebsiteGenerator\\Request\\RequestCollection;\n\nclass UserRequests\n{\n    /** @var UserRepository */\n    private $userRepository;\n\n    public function __construct(UserRepository $userRepository)\n    {\n        $this-\u003euserRepository = $userRepository;\n    }\n\n    public function getUsers() : RequestCollection\n    {\n        /** @var User[] $users */\n        $users = $this-\u003euserRepository-\u003efindAll();\n\n        $requests = [];\n\n        foreach ($users as $user) {\n            $requests[] = [\n                'username' =\u003e $user-\u003egetUsername(),\n            ];\n        }\n\n        return new ArrayRequestCollection($requests);\n    }\n}\n```\n\nFor every user returned by the `getUsers` method, a `/user/{username}.html` file will be generated.\n\n## New Flex Application\n\nYou can also get started fresh with a brand new Flex application. I would love to make this a Symfony Flex recipe\nbut for now you have to do it all manually but it is only a few steps.\n\nFirst create a brand new Flex application:\n\n    $ composer create-project symfony/skeleton:4.1.* my-project\n    $ cd my-project\n\nNow just install the `doctrine/doctrine-static-website-generator-bundle` package:\n\n    $ composer require doctrine/doctrine-static-website-generator-bundle\n\nAdd `DoctrineSkeletonMapperBundle` and `DoctrineStaticWebsiteGeneratorBundle` to the `config/bundles.php`\nfile to enable the bundles:\n\n```php\n\u003c?php\n\nreturn [\n    Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle::class =\u003e ['all' =\u003e true],\n    Doctrine\\Bundle\\DoctrineSkeletonMapperBundle\\DoctrineSkeletonMapperBundle::class =\u003e ['all' =\u003e true],\n    Doctrine\\Bundle\\DoctrineStaticWebsiteGeneratorBundle\\DoctrineStaticWebsiteGeneratorBundle::class =\u003e ['all' =\u003e true],\n];\n```\n\nCreate the following directories:\n\n    $ mkdir source            # source files\n    $ mkdir templates         # twig templates\n    $ mkdir templates/layouts # twig layout files\n\nCreate `templates/layouts/default.html.twig` and place the following code in it:\n\n```html\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003ctitle\u003e{{ site.title }}\u003c/title\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        {% block content '' %}\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\nCreate your first file in `source` named `index.md` and place the following content inside:\n\n```md\nTest\n====\n\nWe are in a Symfony Flex application!\n```\n\nAfter you run `php bin/console doctrine:build-website` you will see the following file in the\n`build-dev` directory:\n\n```html\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003ctitle\u003eSymfony \u0026amp; Doctrine Static Website\u003c/title\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003ch1\u003eTest\u003c/h1\u003e\n        \u003cp\u003eWe are in a Symfony Flex application!\u003c/p\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoctrine%2Fsymfony-doctrine-static-website-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdoctrine%2Fsymfony-doctrine-static-website-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoctrine%2Fsymfony-doctrine-static-website-generator/lists"}