Skip to content
This repository has been archived by the owner on Dec 1, 2023. It is now read-only.

Extension Generator #468

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
129 changes: 129 additions & 0 deletions app/console/src/Commands/ExtensionGenerateCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php

namespace Pagekit\Console\Commands;

use Pagekit\Application\Console\Command;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Helper\DialogHelper;
use Symfony\Component\Finder\Finder;

class ExtensionGenerateCommand extends Command
{
/**
* {@inheritdoc}
*/
protected $name = 'extension:generate';

/**
* {@inheritdoc}
*/
protected $description = 'Generate a new extension';

protected $visitor;

/**
* {@inheritdoc}
*/
protected function configure()
{
$this->addArgument('name', InputArgument::OPTIONAL, 'Extension Name');
}

/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$options = $this->getGeneratorOptions($output);
$this->generateTemplateFiles($options);
}

protected function generateTemplateFiles($options) {
$templateDirectory = $this->container->path() . '/app/console/src/Templates/Extension';
$outputDirectory = $this->container->path() . '/packages/' . $options['name'];


if (is_dir($outputDirectory)) {
// don't create the bundle if it already exists
$this->line('The extension already exists');
return;
} else {
// create the directory for the extension
mkdir($outputDirectory, 0777, true);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

777 This is not a little too wide at the levels of rights?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probs should be a bit less open than 777

mkdir($outputDirectory . '/src/Controller', 0777, true);
}

$twig = new \Twig_Environment(new \Twig_Loader_Filesystem($templateDirectory), array(
'debug' => true,
'cache' => false,
'strict_variables' => true,
'autoescape' => true
));

$this->line('Generating template files');

// get the template files
$files = $files = Finder::create()->files()->in($templateDirectory);
$files->in($templateDirectory . '/src/Controller');
$files = $files->name('*.twig');

$progress = new ProgressBar($this->output, count($files));
$progress->start();

// fill in the templates, write to the extension directory
foreach ($files as $file) {
$relativeFilePath = str_replace($templateDirectory, '', $file->getPathname());
$destinationFilePath = $outputDirectory . '/' . str_replace('.twig', '', $relativeFilePath);

file_put_contents($destinationFilePath, $twig->render($relativeFilePath, $options));
$progress->advance();
}
$progress->finish();
$this->line('Your extension has been created in packages/' . $options['name']);
}

protected function getGeneratorOptions(OutputInterface $output)
{
$options = array();
$dialog = $this->getHelper('dialog');
$options['name'] = $this->argument('name');

if (empty($options['name'])) {
$options['name'] = $dialog->ask(
$output,
'<question>Please enter the name of the extension</question> ',
'my_extension'
);
}

$options['title'] = $dialog->ask(
$output,
'<question>Enter a human-readable name for extension</question> ',
'My Extension'
);

$options['author'] = $dialog->ask(
$output,
'<question>Enter your name</question> ',
false
);

$options['email'] = $dialog->ask(
$output,
'<question>Enter your email</question> ',
false
);

$options['namespace'] = $dialog->ask(
$output,
'<question>PHP namespace of the extension, eg Pagekit\Hello.</question> ',
false
);

return $options;
}
}
1 change: 1 addition & 0 deletions app/console/src/Templates/Extension/README.md.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Your Extension
17 changes: 17 additions & 0 deletions app/console/src/Templates/Extension/composer.json.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{% block json %}
{
"name": "{{ name }}",
"type": "pagekit-extension",
"version": "0.1.0",
"title": "{{ title }}",
"description": "An extension by {{ author }}",
"license": "MIT",
"authors": [
{
"name": "{{ author }}",
"email": "{{ email }}",
"homepage": ""
}
]
}
{% endblock json %}
155 changes: 155 additions & 0 deletions app/console/src/Templates/Extension/index.php.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<?php

use Pagekit\Application;

/*
* This array is the module definition.
* It's used by Pagekit to load your extension and register all things
* that your extension provides (routes, menu items, php classes etc)
*/
{% block array_configuration %}
return [

/*
* Define a unique name.
*/
'name' => '{{ name }}',

/*
* Define the type of this module.
* Has to be 'extension' here. Can be 'theme' for a theme.
*/
'type' => 'extension',

/*
* Main entry point. Called when your extension is both installed and activated.
* Either assign an closure or a string that points to a PHP class.
* Example: 'main' => '{{ namespace }}\\HelloWorldExtension'
*/
'main' => function (Application $app) {

// bootstrap code
},

/*
* Register all namespaces to be loaded.
* Map from namespace to folder where the classes are located.
* Remember to escape backslashes with a second backslash.
*/
'autoload' => [

'{{ namespace }}' => 'src'

],

/*
* Define nodes. A node is similar to a route with the difference
* that it can be placed anywhere in the menu structure. The
* resulting route is therefore determined on runtime.
*/
'nodes' => [],


/*
* Define routes.
*/
'routes' => [

'/{{ name }}' => [
'name' => '@{{ name }}/admin',
'controller' => [
'{{ namespace }}\\Controller\\Controller'
]
]

],

/*
* Define menu items for the backend.
*/
'menu' => [

// name, can be used for menu hierarchy
'{{ name }}' => [

// Label to display
'label' => '{{ title }}',

// Icon to display
'icon' => '{{ name }}:icon.svg',

// URL this menu item links to
'url' => '@{{ name }}/admin',

// Optional: Expression to check if menu item is active on current url
// 'active' => '@{{ name }}*'

// Optional: Limit access to roles which have specific permission assigned
// 'access' => '{{ name }}: manage hellos'
],

'{{ name }}: panel' => [

// Parent menu item, makes this appear on 2nd level
'parent' => '{{ name }}',

// See above
'label' => '{{ title }}',
'icon' => '{{ name }}:icon.svg',
'url' => '@{{ name }}/admin'
// 'access' => '{{ name }}: manage hellos'
],

'{{ name }}: settings' => [
'parent' => '{{ name }}',
'label' => 'Settings',
'url' => '@{{ name }}/admin/settings',
'access' => 'system: manage settings'
]

],

/*
* Define permissions.
* Will be listed in backend and can then be assigned to certain roles.
*/
'permissions' => [

// Unique name.
// Convention: extension name and speaking name of this permission (spaces allowd)
'{{ name }}: manage settings' => [
'title' => 'Manage settings'
],

],

/*
* Link to a settings screen from the extensions listing.
*/
'settings' => '@{{ name }}/admin/settings',

/*
* Default module configuration.
* Can be overwritten by changed config during runtime.
*/
'config' => [

'default' => 'World'

],

/*
* Listen to events.
*/
'events' => [

'view.scripts' => function ($event, $scripts) {
$scripts->register('hello-settings', 'hello:app/bundle/settings.js', '~extensions');
$scripts->register('hello-site', 'hello:app/bundle/site.js', '~site-edit');
$scripts->register('hello-link', 'hello:app/bundle/link.js', '~panel-link');
}

]

];
{% endblock array_configuration %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

{% block namespace %}
namespace {{ namespace }}\Controller;
{% endblock namespace %}

use Pagekit\Application as App;

{% block route %}
/**
* @Route("/{{ name }}")
*/
{% endblock route %}

{% block class_definition %}
class Controller
{% endblock class_definition %}
{
public function indexAction()
{
return "Index View";
}

public function settingsAction()
{
return "Settings View"
}
}
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"symfony/stopwatch": "~2.7.3",
"symfony/templating": "~2.7.3",
"symfony/translation": "~2.7.3",
"symfony/var-dumper": "~2.7.3"
"symfony/var-dumper": "~2.7.3",
"twig/twig": "^1.22"
},
"require-dev": {
"phpunit/phpunit": "~4.7.3"
Expand Down