diff --git a/web/modules/custom/example/.gitignore b/web/modules/custom/example/.gitignore
new file mode 100644
index 0000000..c8153b5
--- /dev/null
+++ b/web/modules/custom/example/.gitignore
@@ -0,0 +1,2 @@
+/composer.lock
+/vendor/
diff --git a/web/modules/custom/example/composer.json b/web/modules/custom/example/composer.json
new file mode 100644
index 0000000..1036ea1
--- /dev/null
+++ b/web/modules/custom/example/composer.json
@@ -0,0 +1,5 @@
+{
+ "require": {
+ "symfony/config": "^6.1"
+ }
+}
diff --git a/web/modules/custom/example/example.info.yml b/web/modules/custom/example/example.info.yml
new file mode 100644
index 0000000..888947d
--- /dev/null
+++ b/web/modules/custom/example/example.info.yml
@@ -0,0 +1,5 @@
+name: Example module
+description: TODO
+type: module
+core_version_requirement: ^9||^10
+package: Example
diff --git a/web/modules/custom/example/example.routing.yml b/web/modules/custom/example/example.routing.yml
new file mode 100644
index 0000000..9504c9b
--- /dev/null
+++ b/web/modules/custom/example/example.routing.yml
@@ -0,0 +1,7 @@
+drupal-module-template.example:
+ path: /@opdavies/drupal-module-template
+ defaults:
+ _controller: Drupal\example\Controller\ExamplePageController
+ _title: Example page
+ requirements:
+ _permission: access content
diff --git a/web/modules/custom/example/example.services.yml b/web/modules/custom/example/example.services.yml
new file mode 100644
index 0000000..3db3f80
--- /dev/null
+++ b/web/modules/custom/example/example.services.yml
@@ -0,0 +1,7 @@
+services:
+ Drupal\Core\Logger\LoggerChannelFactoryInterface:
+ alias: logger.factory
+ private: true
+
+ Drupal\example\Controller\ExamplePageController:
+ autowire: true
diff --git a/web/modules/custom/example/phpcs.xml.dist b/web/modules/custom/example/phpcs.xml.dist
new file mode 100644
index 0000000..eed65a9
--- /dev/null
+++ b/web/modules/custom/example/phpcs.xml.dist
@@ -0,0 +1,31 @@
+
+
+ Codestyle ruleset for Drupal
+
+
+
+
+
+
+
+
+
+ ./src
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/modules/custom/example/src/Controller/ExamplePageController.php b/web/modules/custom/example/src/Controller/ExamplePageController.php
new file mode 100644
index 0000000..859f49b
--- /dev/null
+++ b/web/modules/custom/example/src/Controller/ExamplePageController.php
@@ -0,0 +1,29 @@
+logger->get('example')->info('Example page viewed.');
+
+ return [
+ '#markup' => $this->t(
+ 'This is an example page from the Drupal Module Template.',
+ ['@url' => 'https://github.com/opdavies/drupal-module-template']
+ ),
+ ];
+ }
+
+}
diff --git a/web/modules/custom/example/tests/src/Functional/ExamplePageTest.php b/web/modules/custom/example/tests/src/Functional/ExamplePageTest.php
new file mode 100644
index 0000000..5ecb1b8
--- /dev/null
+++ b/web/modules/custom/example/tests/src/Functional/ExamplePageTest.php
@@ -0,0 +1,31 @@
+drupalGet('/@opdavies/drupal-module-template');
+
+ // Assert.
+ $this->assertSession()->statusCodeEquals(Response::HTTP_OK);
+ }
+
+}
diff --git a/web/modules/custom/example/tests/src/Kernel/.keep b/web/modules/custom/example/tests/src/Kernel/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/web/modules/custom/example/tests/src/Unit/.keep b/web/modules/custom/example/tests/src/Unit/.keep
new file mode 100644
index 0000000..e69de29