diff --git a/app/console/src/Commands/ExtensionGenerateCommand.php b/app/console/src/Commands/ExtensionGenerateCommand.php new file mode 100644 index 000000000..0b773930c --- /dev/null +++ b/app/console/src/Commands/ExtensionGenerateCommand.php @@ -0,0 +1,129 @@ +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); + 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, + 'Please enter the name of the extension ', + 'my_extension' + ); + } + + $options['title'] = $dialog->ask( + $output, + 'Enter a human-readable name for extension ', + 'My Extension' + ); + + $options['author'] = $dialog->ask( + $output, + 'Enter your name ', + false + ); + + $options['email'] = $dialog->ask( + $output, + 'Enter your email ', + false + ); + + $options['namespace'] = $dialog->ask( + $output, + 'PHP namespace of the extension, eg Pagekit\Hello. ', + false + ); + + return $options; + } +} diff --git a/app/console/src/Templates/Extension/README.md.twig b/app/console/src/Templates/Extension/README.md.twig new file mode 100644 index 000000000..a150cfae8 --- /dev/null +++ b/app/console/src/Templates/Extension/README.md.twig @@ -0,0 +1 @@ +# Your Extension diff --git a/app/console/src/Templates/Extension/composer.json.twig b/app/console/src/Templates/Extension/composer.json.twig new file mode 100644 index 000000000..0610e5c4a --- /dev/null +++ b/app/console/src/Templates/Extension/composer.json.twig @@ -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 %} diff --git a/app/console/src/Templates/Extension/index.php.twig b/app/console/src/Templates/Extension/index.php.twig new file mode 100644 index 000000000..8e01efaee --- /dev/null +++ b/app/console/src/Templates/Extension/index.php.twig @@ -0,0 +1,155 @@ + '{{ 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 %} diff --git a/app/console/src/Templates/Extension/src/Controller/Controller.php.twig b/app/console/src/Templates/Extension/src/Controller/Controller.php.twig new file mode 100644 index 000000000..1fe17c5eb --- /dev/null +++ b/app/console/src/Templates/Extension/src/Controller/Controller.php.twig @@ -0,0 +1,28 @@ +