-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from tripal/1-tripal_extension_module_template
1 tripal extension module template
- Loading branch information
Showing
11 changed files
with
413 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
src/Drush/Generators/TripalExtensionModuleGenerator.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace Drupal\tripal_devtools\Drush\Generators; | ||
|
||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface; | ||
use Drupal\Core\Extension\Exception\UnknownExtensionException; | ||
use Drupal\Core\Extension\ModuleExtensionList; | ||
use DrupalCodeGenerator\Application; | ||
use DrupalCodeGenerator\Asset\AssetCollection; | ||
use DrupalCodeGenerator\Attribute\Generator; | ||
use DrupalCodeGenerator\Command\BaseGenerator; | ||
use DrupalCodeGenerator\GeneratorType; | ||
use DrupalCodeGenerator\Validator\Required; | ||
use Symfony\Component\DependencyInjection\ContainerInterface; | ||
|
||
#[Generator( | ||
name: 'tripal:extension-module', | ||
description: 'Generates a Tripal extension module', | ||
templatePath: __DIR__ . '/../../../templates/generator/tripal_extension_module', | ||
type: GeneratorType::MODULE, | ||
)] | ||
final class TripalExtensionModuleGenerator extends BaseGenerator implements ContainerInjectionInterface { | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function __construct( | ||
private readonly ModuleExtensionList $moduleList, | ||
) { | ||
parent::__construct(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public static function create(ContainerInterface $container): self { | ||
return new self($container->get('extension.list.module')); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function generate(array &$vars, AssetCollection $assets): void { | ||
$ir = $this->createInterviewer($vars); | ||
|
||
$vars['machine_name'] = $ir->askMachineName(); | ||
$vars['name'] = $ir->askName(); | ||
|
||
$vars['description'] = $ir->ask('Module description', 'Provides additional functionality for the site.', new Required()); | ||
$vars['package'] = $ir->ask('Package', 'Tripal Extension'); | ||
|
||
$dependencies = $ir->ask('Dependencies (comma separated)', 'tripal, tripal_chado'); | ||
// @todo Clean-up and test. | ||
$vars['dependencies'] = $this->buildDependencies($dependencies); | ||
|
||
$vars['class_prefix'] = '{machine_name|camelize}'; | ||
|
||
if ($ir->confirm('Would you like to create the module file?', TRUE)) { | ||
$assets->addFile('{machine_name}/{machine_name}.module', 'module.module.twig'); | ||
} | ||
|
||
if ($ir->confirm('Would you like to create install file (install tasks + creating tables)?', FALSE)) { | ||
$assets->addFile('{machine_name}/{machine_name}.install', 'module.install.twig'); | ||
} | ||
|
||
if ($ir->confirm('Would you like to create permissions.yml file?', FALSE)) { | ||
$assets->addFile('{machine_name}/{machine_name}.permissions.yml', 'module.permissions.yml.twig'); | ||
$vars['permissions'] = TRUE; | ||
} | ||
|
||
if ($vars['form'] = $ir->confirm('Would you like to create settings form?', TRUE)) { | ||
$assets->addFile('{machine_name}/src/Form/{machine_name|camelize}SettingsForm.php') | ||
->template('SettingsForm.php.twig'); | ||
$assets->addFile('{machine_name}/config/schema/{machine_name}.schema.yml') | ||
->template('module.schema.yml.twig'); | ||
$assets->addFile('{machine_name}/{machine_name}.links.menu.yml') | ||
->template('module.links.menu.twig'); | ||
} | ||
|
||
$assets->addFile('{machine_name}/{machine_name}.info.yml', 'module.info.yml.twig'); | ||
|
||
if ($vars['form']) { | ||
$assets->addFile('{machine_name}/{machine_name}.routing.yml') | ||
->template('module.routing.yml.twig'); | ||
} | ||
} | ||
|
||
/** | ||
* Builds array of dependencies from comma-separated string. | ||
*/ | ||
private function buildDependencies(?string $dependencies_encoded): array { | ||
|
||
$dependencies = $dependencies_encoded ? \explode(',', $dependencies_encoded) : []; | ||
|
||
foreach ($dependencies as &$dependency) { | ||
$dependency = \str_replace(' ', '_', \trim(\strtolower($dependency))); | ||
// Check if the module name is already prefixed. | ||
if (\str_contains($dependency, ':')) { | ||
continue; | ||
} | ||
// Dependencies should be namespaced in the format {project}:{name}. | ||
$project = $dependency; | ||
try { | ||
// The extension list is internal for extending not for instantiating. | ||
// @see \Drupal\Core\Extension\ExtensionList | ||
/** @psalm-suppress InternalMethod */ | ||
$package = $this->moduleList->getExtensionInfo($dependency)['package'] ?? NULL; | ||
if ($package === 'Core') { | ||
$project = 'drupal'; | ||
} | ||
} | ||
catch (UnknownExtensionException) { | ||
|
||
} | ||
$dependency = $project . ':' . $dependency; | ||
} | ||
|
||
$dependency_sorter = static function (string $a, string $b): int { | ||
// Core dependencies go first. | ||
$a_is_drupal = \str_starts_with($a, 'drupal:'); | ||
$b_is_drupal = \str_starts_with($b, 'drupal:'); | ||
if ($a_is_drupal xor $b_is_drupal) { | ||
return $a_is_drupal ? -1 : 1; | ||
} | ||
return $a <=> $b; | ||
}; | ||
\uasort($dependencies, $dependency_sorter); | ||
|
||
return $dependencies; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php declare(strict_types = 1); | ||
/** | ||
* @file | ||
* Primary module hooks for {{ name }} module. | ||
*/ | ||
{% if create_theme %} | ||
/** | ||
* Implements hook_theme(). | ||
*/ | ||
function {{ machine_name }}_theme(): array { | ||
return [ | ||
'{{ theme_key }}' => [ | ||
'variables' => ['foo' => NULL], | ||
], | ||
]; | ||
} | ||
{% endif %} | ||
{% if create_preprocess %} | ||
/** | ||
* Prepares variables for {{ template_name }} template. | ||
* | ||
* Default template: {{ template_name }}. | ||
* | ||
* @param array $variables | ||
* An associative array containing: | ||
* - foo: Foo variable description. | ||
*/ | ||
function template_preprocess_{{ theme_key }}(array &$variables): void { | ||
$variables['foo'] = 'bar'; | ||
} | ||
{% endif %} |
64 changes: 64 additions & 0 deletions
64
templates/generator/tripal_extension_module/SettingsForm.php.twig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<?php | ||
namespace Drupal\{{ machine_name }}\Form; | ||
use Drupal\Core\Form\ConfigFormBase; | ||
use Drupal\Core\Form\FormStateInterface; | ||
/** | ||
* Configure {{ name }} settings for this site. | ||
*/ | ||
class {{ machine_name|camelize }}SettingsForm extends ConfigFormBase { | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getFormId() { | ||
return '{{ machine_name }}_settings'; | ||
} | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function getEditableConfigNames() { | ||
return ['{{ machine_name }}.settings']; | ||
} | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function buildForm(array $form, FormStateInterface $form_state) { | ||
$form['example'] = [ | ||
'#type' => 'textfield', | ||
'#title' => $this->t('Example'), | ||
'#description' => $this->t('Please type the word "example".'), | ||
'#default_value' => $this->config('{{ machine_name }}.settings')->get('example'), | ||
]; | ||
return parent::buildForm($form, $form_state); | ||
} | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function validateForm(array &$form, FormStateInterface $form_state) { | ||
if ($form_state->getValue('example') != 'example') { | ||
$form_state->setErrorByName('example', $this->t('The value is not correct. Instead enter "example" to get validation to pass.')); | ||
} | ||
parent::validateForm($form, $form_state); | ||
} | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function submitForm(array &$form, FormStateInterface $form_state) { | ||
$value = $form_state->getValue('example'); | ||
$this->config('{{ machine_name }}.settings') | ||
->set('example', $value) | ||
->save(); | ||
$this->messenger()->addStatus("Setting the value of {{ machine_name }}.settings.example to $value."); | ||
parent::submitForm($form, $form_state); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
templates/generator/tripal_extension_module/module.info.yml.twig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
name: {{ name }} | ||
type: module | ||
description: {{ description }} | ||
package: {{ package }} | ||
core_version_requirement: ^10 | ||
{% if dependencies %} | ||
dependencies: | ||
{% for dependency in dependencies %} | ||
- {{ dependency }} | ||
{% endfor %} | ||
{% endif %} | ||
{% if form %} | ||
configure: {{ machine_name }}.settings_form | ||
{% endif %} |
130 changes: 130 additions & 0 deletions
130
templates/generator/tripal_extension_module/module.install.twig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
<?php | ||
/** | ||
* @file | ||
* Install, update and uninstall functions for the {{ name }} module. | ||
*/ | ||
/** | ||
* Implements hook_install(). | ||
* | ||
* Use this function for all tasks which need to be executed when this module | ||
* is installed. We suggest submitting Tripal jobs to complete any longer tasks | ||
* such as importing an ontology. | ||
*/ | ||
function {{ machine_name }}_install() { | ||
// Uncomment the following code to add a Drupal status message | ||
// showing when this function is called. | ||
// \Drupal::messenger()->addStatus(__FUNCTION__); | ||
} | ||
/** | ||
* Implements hook_uninstall(). | ||
* | ||
* Use this method for all tasks which need to be executed when this module is | ||
* uninstalled. We DO NOT suggest deleting any terms or data added to Chado | ||
* by this module on uninstall. | ||
*/ | ||
function {{ machine_name }}_uninstall() { | ||
// Uncomment the following code to add a Drupal status message | ||
// showing when this function is called. | ||
// \Drupal::messenger()->addStatus(__FUNCTION__); | ||
} | ||
/** | ||
* Implements hook_schema(). | ||
* | ||
* Use the Drupal Schema API to define any database tables you want created | ||
* in the DRUPAL Schema. Do Not use this to create Tripal/Chado Custom tables | ||
* or Materialized Views. | ||
* | ||
* @see https://www.drupal.org/docs/7/api/schema-api/schema-reference | ||
*/ | ||
function {{ machine_name }}_schema() { | ||
$schema = []; | ||
// Uncomment the following code example to create the {{ machine_name }}_example | ||
// table in the Drupal Schema. The {{ machine_name }}_example table has | ||
// id, uid, status, type created, and data columns, where the primary key is the id. | ||
/* @code-sample | ||
$schema['{{ machine_name }}_example'] = [ | ||
'description' => 'Table description.', | ||
'fields' => [ | ||
'id' => [ | ||
'type' => 'serial', | ||
'not null' => TRUE, | ||
'description' => 'Primary Key: Unique record ID.', | ||
], | ||
'uid' => [ | ||
'type' => 'int', | ||
'unsigned' => TRUE, | ||
'not null' => TRUE, | ||
'default' => 0, | ||
'description' => 'The {users}.uid of the user who created the record.', | ||
], | ||
'status' => [ | ||
'description' => 'Boolean indicating whether this record is active.', | ||
'type' => 'int', | ||
'unsigned' => TRUE, | ||
'not null' => TRUE, | ||
'default' => 0, | ||
'size' => 'tiny', | ||
], | ||
'type' => [ | ||
'type' => 'varchar_ascii', | ||
'length' => 64, | ||
'not null' => TRUE, | ||
'default' => '', | ||
'description' => 'Type of the record.', | ||
], | ||
'created' => [ | ||
'type' => 'int', | ||
'not null' => TRUE, | ||
'default' => 0, | ||
'description' => 'Timestamp when the record was created.', | ||
], | ||
'data' => [ | ||
'type' => 'blob', | ||
'not null' => TRUE, | ||
'size' => 'big', | ||
'description' => 'The arbitrary data for the item.', | ||
], | ||
], | ||
'primary key' => ['id'], | ||
'indexes' => [ | ||
'type' => ['type'], | ||
'uid' => ['uid'], | ||
'status' => ['status'], | ||
], | ||
]; | ||
*/ | ||
return $schema; | ||
} | ||
/** | ||
* Implements hook_requirements(). | ||
* | ||
* Use this function to define specific requirements for your module. | ||
* If the severity key is set to warning or error then your module will | ||
* not be able to be installed. | ||
*/ | ||
function {{ machine_name }}_requirements($phase) { | ||
$requirements = []; | ||
// This example requirement is only run when checking requirements | ||
// through the UI. It simply generates a random number between 1-100 | ||
// and produces a warning if it's above 50. This should show up on the | ||
// Drupal Report Status page. | ||
if ($phase == 'runtime') { | ||
$value = mt_rand(0, 100); | ||
$requirements['{{ machine_name }}_status'] = [ | ||
'title' => t('{{ name }} status'), | ||
'value' => t('{{ name }} value: @value', ['@value' => $value]), | ||
'severity' => $value > 50 ? REQUIREMENT_INFO : REQUIREMENT_WARNING, | ||
]; | ||
} | ||
return $requirements; | ||
} |
6 changes: 6 additions & 0 deletions
6
templates/generator/tripal_extension_module/module.links.menu.twig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{{ machine_name }}.settings_form: | ||
title: '{{ name }}' | ||
description: 'Configure {{ name }}.' | ||
parent: tripal.extension | ||
route_name: {{ machine_name }}.settings_form | ||
weight: 10 |
Oops, something went wrong.