diff --git a/system/src/Grav/Console/Cli/DevTools/DevToolsCommand.php b/system/src/Grav/Console/Cli/DevTools/DevToolsCommand.php
index 71bd1fc33..435c2545a 100644
--- a/system/src/Grav/Console/Cli/DevTools/DevToolsCommand.php
+++ b/system/src/Grav/Console/Cli/DevTools/DevToolsCommand.php
@@ -1,189 +1,162 @@
-grav = Grav::instance(array('loader' => $autoload));
- $this->grav['config']->init();
- $this->grav['uri']->init();
- $this->grav['streams'];
- $this->inflector = $this->grav['inflector'];
- $this->locator = $this->grav['locator'];
- $this->gpm = new GPM(true);
- }
- /**
- *
- */
- protected function copyComponent()
- {
- $name = $this->component['name'];
- $folderName = $this->inflector->hyphenize($name);
- $type = $this->component['type'];
- $template = $this->component['template'];
-
-
- $templateFolder = __DIR__ . '/components/' . $type . DS . $template;
- $componentFolder = $this->locator->findResource($type . 's://') . DS . $folderName;
-
- Folder::copy($templateFolder, $componentFolder);
- return;
- }
-
- protected function renameComponent()
- {
- $name = $this->component['name'];
- $className = $this->inflector->camelize($name);
- $folderName = $this->inflector->hyphenize($name);
- $titleName = $this->inflector->titleize($name);
- $description = $this->component['description'];
- $type = $this->component['type'];
- $template = $this->component['template'];
-
- unset($this->component['type']);
- unset($this->component['template']);
-
- $componentFolder = $this->locator->findResource($type . 's://') . DS . $folderName;
-
- rename($componentFolder . '/' . $type . '.php' , $componentFolder . DS . $folderName . PLUGIN_EXT);
- rename($componentFolder . '/' . $type . '.yaml' , $componentFolder . DS . $folderName . YAML_EXT);
-
- //PHP File
-
- $data = file_get_contents($componentFolder . DS . $folderName . PLUGIN_EXT);
-
- $data = str_replace('@@CLASSNAME@@', $className, $data); // @todo dynamic renaming
- $data = str_replace('@@HYPHENNAME@@', $folderName, $data);
-
- file_put_contents($componentFolder . DS . $folderName . PLUGIN_EXT, $data);
-
- //README File
-
- $data = file_get_contents($componentFolder . DS . 'README.md');
-
- $data = str_replace('@@NAME@@', $titleName, $data); // @todo dynamic renaming
- $data = str_replace('@@DESCRIPTION@@', $description, $data);
-
- file_put_contents($componentFolder . DS . 'README.md', $data);
-
- //Blueprints File
- $filename = $componentFolder . '/blueprints' . YAML_EXT;
- $file = CompiledYamlFile::instance($filename);
-
- $blueprints = new Data\Blueprints($type . 's://');
- $blueprint = $blueprints->get($folderName . '/blueprints');
-
- $obj = new Data\Data([], $blueprint);
- $obj->merge($this->component);
- $obj->file($file);
- $obj->save();
-
- return;
- }
-
- /**
- *
- */
- protected function validateOptions()
- {
- foreach (array_filter($this->options) as $type => $value) {
- $this->validate($type, $value);
- }
- }
-
- /**
- * @param $type
- * @param $value
- * @param string $extra
- *
- * @return mixed
- */
- protected function validate($type, $value, $extra = '')
- {
- switch ($type) {
- case 'name':
- //Check If name
- if ($value == null || trim($value) == '') {
- throw new \RuntimeException('Plugin Name cannot be empty');
- }
- if (false != $this->gpm->findPackage($value) || false != $this->gpm->isPluginInstalled($value) || false != $this->gpm->isThemeInstalled($value)) {
- throw new \RuntimeException('Package exists (either as theme or plugin)');
- }
-
- break;
-
- case 'description':
- if($value == null || trim($value) == '') {
- throw new \RuntimeException('Description cannot be empty');
- }
-
- break;
-
- case 'developer':
- if ($value === null || trim($value) == '') {
- throw new \RuntimeException('Developer\'s Name cannot be empty');
- }
-
- break;
-
- case 'email':
- if (!preg_match('/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/', $value)) {
- throw new \RuntimeException('Not a valid email address');
- }
-
- break;
- }
-
- return $value;
- }
-}
+grav = Grav::instance(array('loader' => $autoload));
+ $this->grav['config']->init();
+ $this->grav['uri']->init();
+ $this->grav['streams'];
+ $this->inflector = $this->grav['inflector'];
+ $this->locator = $this->grav['locator'];
+ $this->twig = new Twig($this->grav);
+ $this->gpm = new GPM(true);
+ }
+
+ /**
+ *
+ */
+ protected function createComponent()
+ {
+ $name = $this->component['name'];
+ $folderName = $this->inflector->hyphenize($name);
+ $type = $this->component['type'];
+
+ $template = $this->component['template'];
+ $templateFolder = __DIR__ . '/components/' . $type . DS . $template;
+ $componentFolder = $this->locator->findResource($type . 's://') . DS . $folderName;
+
+ //Copy All files to component folder
+ Folder::copy($templateFolder, $componentFolder);
+
+ //Add Twig vars and templates then initialize
+ $this->twig->twig_vars['component'] = $this->component;
+ $this->twig->twig_paths[] = $templateFolder;
+ $this->twig->init();
+
+ //Get all templates of component then process each with twig and save
+ $templates = Folder::all($componentFolder);
+ foreach($templates as $templateFile) {
+ if (Utils::endsWith($templateFile, '.twig') && !Utils::endsWith($templateFile, '.html.twig')) {
+ $content = $this->twig->processTemplate($templateFile);
+ $file = File::instance($componentFolder . DS . str_replace('.twig', '', $templateFile));
+ $file->content($content);
+ $file->save();
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ protected function validateOptions()
+ {
+ foreach (array_filter($this->options) as $type => $value) {
+ $this->validate($type, $value);
+ }
+ }
+
+ /**
+ * @param $type
+ * @param $value
+ * @param string $extra
+ *
+ * @return mixed
+ */
+ protected function validate($type, $value, $extra = '')
+ {
+ switch ($type) {
+ case 'name':
+ //Check If name
+ if ($value == null || trim($value) == '') {
+ throw new \RuntimeException('Plugin Name cannot be empty');
+ }
+ if (false != $this->gpm->findPackage($value) || false != $this->gpm->isPluginInstalled($value) || false != $this->gpm->isThemeInstalled($value)) {
+ throw new \RuntimeException('Package exists (either as theme or plugin)');
+ }
+
+ break;
+
+ case 'description':
+ if($value == null || trim($value) == '') {
+ throw new \RuntimeException('Description cannot be empty');
+ }
+
+ break;
+
+ case 'developer':
+ if ($value === null || trim($value) == '') {
+ throw new \RuntimeException('Developer\'s Name cannot be empty');
+ }
+
+ break;
+
+ case 'email':
+ if (!preg_match('/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/', $value)) {
+ throw new \RuntimeException('Not a valid email address');
+ }
+
+ break;
+ }
+
+ return $value;
+ }
+}
diff --git a/system/src/Grav/Console/Cli/DevTools/NewPluginCommand.php b/system/src/Grav/Console/Cli/DevTools/NewPluginCommand.php
index 5e480c3f3..6bfdb742e 100644
--- a/system/src/Grav/Console/Cli/DevTools/NewPluginCommand.php
+++ b/system/src/Grav/Console/Cli/DevTools/NewPluginCommand.php
@@ -1,139 +1,138 @@
-setName('new-plugin')
- ->setAliases(['newplugin'])
- ->addOption(
- 'name',
- 'pn',
- InputOption::VALUE_OPTIONAL,
- 'The name of your new Grav plugin'
- )
- ->addOption(
- 'description',
- 'd',
- InputOption::VALUE_OPTIONAL,
- 'A description of your new Grav plugin'
- )
- ->addOption(
- 'developer',
- 'dv',
- InputOption::VALUE_OPTIONAL,
- 'The name/username of the developer'
- )
- ->addOption(
- 'email',
- 'e',
- InputOption::VALUE_OPTIONAL,
- 'The developer\'s email'
- )
- ->setDescription('Creates a new Grav plugin with the basic required files')
- ->setHelp('The new-plugin command creates a new Grav instance and performs the creation of a plugin.');
- }
-
- /**
- * @return int|null|void
- */
- protected function serve()
- {
- $this->init();
-
- /**
- * @var array DevToolsCommand $component
- */
- $this->component['type'] = 'plugin';
- $this->component['template'] = 'blank'; // @todo add prompt for template type when more templates are added
- $this->component['version'] = '0.1.0'; // @todo add optional non prompting version argument
-
- $this->options = [
- 'name' => $this->input->getOption('name'),
- 'description' => $this->input->getOption('description'),
- 'author' => [
- 'name' => $this->input->getOption('developer'),
- 'email' => $this->input->getOption('email')
- ]
- ];
-
- $this->validateOptions();
-
- $this->component = array_replace($this->component, $this->options);
-
- $helper = $this->getHelper('question');
-
- if (!$this->options['name']) {
- $question = new Question('Enter Plugin Name: ');
- $question->setValidator(function ($value) {
- return $this->validate('name', $value);
- });
-
- $this->component['name'] = $helper->ask($this->input, $this->output, $question);
- }
-
- if (!$this->options['description']) {
- $question = new Question('Enter Plugin Description: ');
- $question->setValidator(function ($value) {
- return $this->validate('description', $value);
- });
-
- $this->component['description'] = $helper->ask($this->input, $this->output, $question);
- }
-
- if (!$this->options['author']['name']) {
- $question = new Question('Enter Developer Name: ');
- $question->setValidator(function ($value) {
- return $this->validate('developer', $value);
- });
-
- $this->component['author']['name'] = $helper->ask($this->input, $this->output, $question);
- }
-
- if (!$this->options['author']['email']) {
- $question = new Question('Enter Developer Email: ');
- $question->setValidator(function ($value) {
- return $this->validate('email', $value);
- });
-
- $this->component['author']['email'] = $helper->ask($this->input, $this->output, $question);
- }
- $this->copyComponent();
- $this->renameComponent();
- }
-
-}
+setName('new-plugin')
+ ->setAliases(['newplugin'])
+ ->addOption(
+ 'name',
+ 'pn',
+ InputOption::VALUE_OPTIONAL,
+ 'The name of your new Grav plugin'
+ )
+ ->addOption(
+ 'description',
+ 'd',
+ InputOption::VALUE_OPTIONAL,
+ 'A description of your new Grav plugin'
+ )
+ ->addOption(
+ 'developer',
+ 'dv',
+ InputOption::VALUE_OPTIONAL,
+ 'The name/username of the developer'
+ )
+ ->addOption(
+ 'email',
+ 'e',
+ InputOption::VALUE_OPTIONAL,
+ 'The developer\'s email'
+ )
+ ->setDescription('Creates a new Grav plugin with the basic required files')
+ ->setHelp('The new-plugin command creates a new Grav instance and performs the creation of a plugin.');
+ }
+
+ /**
+ * @return int|null|void
+ */
+ protected function serve()
+ {
+ $this->init();
+
+ /**
+ * @var array DevToolsCommand $component
+ */
+ $this->component['type'] = 'plugin';
+ $this->component['template'] = 'blank'; // @todo add prompt for template type when more templates are added
+ $this->component['version'] = '0.1.0'; // @todo add optional non prompting version argument
+
+ $this->options = [
+ 'name' => $this->input->getOption('name'),
+ 'description' => $this->input->getOption('description'),
+ 'author' => [
+ 'name' => $this->input->getOption('developer'),
+ 'email' => $this->input->getOption('email')
+ ]
+ ];
+
+ $this->validateOptions();
+
+ $this->component = array_replace($this->component, $this->options);
+
+ $helper = $this->getHelper('question');
+
+ if (!$this->options['name']) {
+ $question = new Question('Enter Plugin Name: ');
+ $question->setValidator(function ($value) {
+ return $this->validate('name', $value);
+ });
+
+ $this->component['name'] = $helper->ask($this->input, $this->output, $question);
+ }
+
+ if (!$this->options['description']) {
+ $question = new Question('Enter Plugin Description: ');
+ $question->setValidator(function ($value) {
+ return $this->validate('description', $value);
+ });
+
+ $this->component['description'] = $helper->ask($this->input, $this->output, $question);
+ }
+
+ if (!$this->options['author']['name']) {
+ $question = new Question('Enter Developer Name: ');
+ $question->setValidator(function ($value) {
+ return $this->validate('developer', $value);
+ });
+
+ $this->component['author']['name'] = $helper->ask($this->input, $this->output, $question);
+ }
+
+ if (!$this->options['author']['email']) {
+ $question = new Question('Enter Developer Email: ');
+ $question->setValidator(function ($value) {
+ return $this->validate('email', $value);
+ });
+
+ $this->component['author']['email'] = $helper->ask($this->input, $this->output, $question);
+ }
+ $this->createComponent();
+ }
+
+}
diff --git a/system/src/Grav/Console/Cli/DevTools/NewThemeCommand.php b/system/src/Grav/Console/Cli/DevTools/NewThemeCommand.php
index 6341ca7db..6694778d4 100644
--- a/system/src/Grav/Console/Cli/DevTools/NewThemeCommand.php
+++ b/system/src/Grav/Console/Cli/DevTools/NewThemeCommand.php
@@ -1,140 +1,147 @@
-setName('new-theme')
- ->setAliases(['newtheme'])
- ->addOption(
- 'name',
- 'pn',
- InputOption::VALUE_OPTIONAL,
- 'The name of your new Grav theme'
- )
- ->addOption(
- 'description',
- 'd',
- InputOption::VALUE_OPTIONAL,
- 'A description of your new Grav theme'
- )
- ->addOption(
- 'developer',
- 'dv',
- InputOption::VALUE_OPTIONAL,
- 'The name/username of the developer'
- )
- ->addOption(
- 'email',
- 'e',
- InputOption::VALUE_OPTIONAL,
- 'The developer\'s email'
- )
- ->setDescription('Creates a new Grav theme with the basic required files')
- ->setHelp('The new-theme command creates a new Grav instance and performs the creation of a theme.');
- }
-
- /**
- * @return int|null|void
- */
- protected function serve()
- {
- $this->init();
-
- /**
- * @var array DevToolsCommand $component
- */
- $this->component['type'] = 'theme';
- $this->component['template'] = 'blank'; // @todo add prompt for template type when more templates are added
- $this->component['version'] = '0.1.0'; // @todo add optional non prompting version argument
-
- $this->options = [
- 'name' => $this->input->getOption('name'),
- 'description' => $this->input->getOption('description'),
- 'author' => [
- 'name' => $this->input->getOption('developer'),
- 'email' => $this->input->getOption('email')
- ]
- ];
-
- $this->validateOptions();
-
- $this->component = array_replace($this->component, $this->options);
-
- $helper = $this->getHelper('question');
-
- if (!$this->options['name']) {
- $question = new Question('Enter Theme Name: ');
- // @todo set validator
-
- $this->component['name'] = $helper->ask($this->input, $this->output, $question);
- }
-
- if (!$this->options['description']) {
- $question = new Question('Enter Theme Description: ');
- // @todo set validator
-
- $this->component['description'] = $helper->ask($this->input, $this->output, $question);
- }
-
- if (!$this->options['author']['name']) {
- $question = new Question('Enter Developer Name: ');
- // @todo set validator
-
- $this->component['author']['name'] = $helper->ask($this->input, $this->output, $question);
- }
-
- if (!$this->options['author']['email']) {
- $question = new Question('Enter Developer Email: ');
- // @todo set validator
-
- $this->component['author']['email'] = $helper->ask($this->input, $this->output, $question);
- }
-
- $question = new ChoiceQuestion(
- 'Please choose a template type',
- array('bootstrap', 'inheritence')
- );
- $this->component['template'] = $helper->ask($this->input, $this->output, $question);
-
- if ($this->component['template'] == 'inheritence') {
- $themes = $this->gpm->getInstalledThemes();
- $installedThemes = [];
- foreach($themes as $key => $theme) {
- array_push($installedThemes, $key);
- }
- $question = new ChoiceQuestion(
- 'Please choose a theme to extend: ',
- $installedThemes
- );
- $this->component['extends'] = $helper->ask($this->input, $this->output, $question);
- }
- $this->copyComponent();
- $this->renameComponent();
- }
-
-}
+setName('new-theme')
+ ->setAliases(['newtheme'])
+ ->addOption(
+ 'name',
+ 'pn',
+ InputOption::VALUE_OPTIONAL,
+ 'The name of your new Grav theme'
+ )
+ ->addOption(
+ 'description',
+ 'd',
+ InputOption::VALUE_OPTIONAL,
+ 'A description of your new Grav theme'
+ )
+ ->addOption(
+ 'developer',
+ 'dv',
+ InputOption::VALUE_OPTIONAL,
+ 'The name/username of the developer'
+ )
+ ->addOption(
+ 'email',
+ 'e',
+ InputOption::VALUE_OPTIONAL,
+ 'The developer\'s email'
+ )
+ ->setDescription('Creates a new Grav theme with the basic required files')
+ ->setHelp('The new-theme command creates a new Grav instance and performs the creation of a theme.');
+ }
+
+ /**
+ * @return int|null|void
+ */
+ protected function serve()
+ {
+ $this->init();
+
+ /**
+ * @var array DevToolsCommand $component
+ */
+ $this->component['type'] = 'theme';
+ $this->component['template'] = 'blank'; // @todo add prompt for template type when more templates are added
+ $this->component['version'] = '0.1.0'; // @todo add optional non prompting version argument
+
+ $this->options = [
+ 'name' => $this->input->getOption('name'),
+ 'description' => $this->input->getOption('description'),
+ 'author' => [
+ 'name' => $this->input->getOption('developer'),
+ 'email' => $this->input->getOption('email')
+ ]
+ ];
+
+ $this->validateOptions();
+
+ $this->component = array_replace($this->component, $this->options);
+
+ $helper = $this->getHelper('question');
+
+ if (!$this->options['name']) {
+ $question = new Question('Enter Theme Name: ');
+ $question->setValidator(function ($value) {
+ return $this->validate('name', $value);
+ });
+
+ $this->component['name'] = $helper->ask($this->input, $this->output, $question);
+ }
+
+ if (!$this->options['description']) {
+ $question = new Question('Enter Theme Description: ');
+ $question->setValidator(function ($value) {
+ return $this->validate('description', $value);
+ });
+
+ $this->component['description'] = $helper->ask($this->input, $this->output, $question);
+ }
+
+ if (!$this->options['author']['name']) {
+ $question = new Question('Enter Developer Name: ');
+ $question->setValidator(function ($value) {
+ return $this->validate('developer', $value);
+ });
+
+ $this->component['author']['name'] = $helper->ask($this->input, $this->output, $question);
+ }
+
+ if (!$this->options['author']['email']) {
+ $question = new Question('Enter Developer Email: ');
+ $question->setValidator(function ($value) {
+ return $this->validate('email', $value);
+ });
+
+ $this->component['author']['email'] = $helper->ask($this->input, $this->output, $question);
+ }
+
+ $question = new ChoiceQuestion(
+ 'Please choose a template type',
+ array('bootstrap', 'inheritence')
+ );
+ $this->component['template'] = $helper->ask($this->input, $this->output, $question);
+
+ if ($this->component['template'] == 'inheritence') {
+ $themes = $this->gpm->getInstalledThemes();
+ $installedThemes = [];
+ foreach($themes as $key => $theme) {
+ array_push($installedThemes, $key);
+ }
+ $question = new ChoiceQuestion(
+ 'Please choose a theme to extend: ',
+ $installedThemes
+ );
+ $this->component['extends'] = $helper->ask($this->input, $this->output, $question);
+ }
+ $this->createComponent();
+ }
+
+}
diff --git a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/CHANGELOG.md b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/CHANGELOG.md
deleted file mode 100644
index e69de29bb..000000000
diff --git a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/CHANGELOG.md.twig b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/CHANGELOG.md.twig
new file mode 100644
index 000000000..973fb2766
--- /dev/null
+++ b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/CHANGELOG.md.twig
@@ -0,0 +1,5 @@
+# v0.1.0
+## {{ "now"|date("m/d/Y") }}
+
+1. [](#new)
+ * ChangeLog started...
diff --git a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/LICENSE b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/LICENSE
deleted file mode 100644
index e69de29bb..000000000
diff --git a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/LICENSE.twig b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/LICENSE.twig
new file mode 100644
index 000000000..6f88097cd
--- /dev/null
+++ b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/LICENSE.twig
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) {{ "now"|date("Y") }} {{ component.author.name }}
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/README.md b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/README.md
deleted file mode 100644
index 430e28152..000000000
--- a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# @@NAME@@
-
-The **@@NAME@@** Plugin is for [Grav](http://github.com/getgrav/grav)
-
-@@DESCRIPTION@@
diff --git a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/README.md.twig b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/README.md.twig
new file mode 100644
index 000000000..5b80e3210
--- /dev/null
+++ b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/README.md.twig
@@ -0,0 +1,5 @@
+# {{ component.name|titleize }}
+
+The **{{ component.name|titleize }}** Plugin is for [Grav](http://github.com/getgrav/grav)
+
+{{ component.description }}
diff --git a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/blueprints.yaml b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/blueprints.yaml
deleted file mode 100644
index 62f8b012b..000000000
--- a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/blueprints.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-cosgrove: "my field"
-form:
- validation: loose
diff --git a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/blueprints.yaml.twig b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/blueprints.yaml.twig
new file mode 100644
index 000000000..6da9784b2
--- /dev/null
+++ b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/blueprints.yaml.twig
@@ -0,0 +1,8 @@
+name: {{ component.name|titleize }}
+version: 0.1.0
+description: {{ component.description }}
+icon: sign-in
+author:
+ name: {{ component.author.name }}
+ email: {{ component.author.email }}
+license: MIT
diff --git a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/plugin.php b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/plugin.php.twig
similarity index 86%
rename from system/src/Grav/Console/Cli/DevTools/components/plugin/blank/plugin.php
rename to system/src/Grav/Console/Cli/DevTools/components/plugin/blank/plugin.php.twig
index f0bb239b4..0166af4c0 100644
--- a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/plugin.php
+++ b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/plugin.php.twig
@@ -1,90 +1,90 @@
- ['onPluginsInitialized', 0]
- ];
- }
-
- /**
- * Initialize the plugin
- */
- public function onPluginsInitialized()
- {
- if ($this->grav['config']->get('plugins.@@HYPHENNAME@@.enabled')) { // Check if enabled in configuration.
-
- $this->active = true; // Set's the plugin state to active.
-
- $this->enable([
- 'onPageInitialized' => ['onPageInitialized', 0] // Adds the onPageInitialized event listener
- ]);
- }
-
- }
-
- /**
- * Does something with pages
- */
- public function onPageInitialized()
- {
- // Exit the function if plugin is not active
- if (!$this->active){
- return;
- }
-
- // Do things with the page
- $somevariable = $this->returnTrue(); // Call a protected function and set a variable to it's value
-
- $this->doSomeProcesses(); // Call a protected function that runs some processes
- }
-
- protected function returnTrue()
- {
- return true;
- }
-
- protected function doSomeProcesses()
- {
- // Generate a random 10 letter string
- $result = "";
- $chars = "abcdefghijklmnopqrstuvwxyz";
- $charArray = str_split($chars);
- for($i = 0; $i < 10; $i++){
- $randItem = array_rand($charArray);
- $result .= "".$charArray[$randItem];
- }
-
- // Do some math
- $two = 8*4;
- $twentyone = 7*3; // anyone up for poker?
- }
-}
+ ['onPluginsInitialized', 0]
+ ];
+ }
+
+ /**
+ * Initialize the plugin
+ */
+ public function onPluginsInitialized()
+ {
+ if ($this->grav['config']->get('plugins.{{ component.name|hyphenize }}.enabled')) { // Check if enabled in configuration.
+
+ $this->active = true; // Set's the plugin state to active.
+
+ $this->enable([
+ 'onPageInitialized' => ['onPageInitialized', 0] // Adds the onPageInitialized event listener
+ ]);
+ }
+
+ }
+
+ /**
+ * Does something with pages
+ */
+ public function onPageInitialized()
+ {
+ // Exit the function if plugin is not active
+ if (!$this->active){
+ return;
+ }
+
+ // Do things with the page
+ $somevariable = $this->returnTrue(); // Call a protected function and set a variable to it's value
+
+ $this->doSomeProcesses(); // Call a protected function that runs some processes
+ }
+
+ protected function returnTrue()
+ {
+ return true;
+ }
+
+ protected function doSomeProcesses()
+ {
+ // Generate a random 10 letter string
+ $result = "";
+ $chars = "abcdefghijklmnopqrstuvwxyz";
+ $charArray = str_split($chars);
+ for($i = 0; $i < 10; $i++){
+ $randItem = array_rand($charArray);
+ $result .= "".$charArray[$randItem];
+ }
+
+ // Do some math
+ $two = 8*4;
+ $twentyone = 7*3; // anyone up for poker?
+ }
+}
diff --git a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/plugin.yaml b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/plugin.yaml.twig
similarity index 93%
rename from system/src/Grav/Console/Cli/DevTools/components/plugin/blank/plugin.yaml
rename to system/src/Grav/Console/Cli/DevTools/components/plugin/blank/plugin.yaml.twig
index d4ca94189..e8683c2d8 100644
--- a/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/plugin.yaml
+++ b/system/src/Grav/Console/Cli/DevTools/components/plugin/blank/plugin.yaml.twig
@@ -1 +1 @@
-enabled: true
+enabled: true
diff --git a/system/src/Grav/Console/Cli/DevTools/components/theme/bootstrap/README.md b/system/src/Grav/Console/Cli/DevTools/components/theme/bootstrap/README.md
deleted file mode 100644
index 32a2e69c2..000000000
--- a/system/src/Grav/Console/Cli/DevTools/components/theme/bootstrap/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# @@NAME@@
-
-The **@@NAME@@** Theme is for [Grav](http://github.com/getgrav/grav)
-
-@@DESCRIPTION@@
diff --git a/system/src/Grav/Console/Cli/DevTools/components/theme/bootstrap/README.md.twig b/system/src/Grav/Console/Cli/DevTools/components/theme/bootstrap/README.md.twig
new file mode 100644
index 000000000..5b80e3210
--- /dev/null
+++ b/system/src/Grav/Console/Cli/DevTools/components/theme/bootstrap/README.md.twig
@@ -0,0 +1,5 @@
+# {{ component.name|titleize }}
+
+The **{{ component.name|titleize }}** Plugin is for [Grav](http://github.com/getgrav/grav)
+
+{{ component.description }}
diff --git a/system/src/Grav/Console/Cli/DevTools/components/theme/bootstrap/blueprints.yaml.twig b/system/src/Grav/Console/Cli/DevTools/components/theme/bootstrap/blueprints.yaml.twig
new file mode 100644
index 000000000..6da9784b2
--- /dev/null
+++ b/system/src/Grav/Console/Cli/DevTools/components/theme/bootstrap/blueprints.yaml.twig
@@ -0,0 +1,8 @@
+name: {{ component.name|titleize }}
+version: 0.1.0
+description: {{ component.description }}
+icon: sign-in
+author:
+ name: {{ component.author.name }}
+ email: {{ component.author.email }}
+license: MIT
diff --git a/system/src/Grav/Console/Cli/DevTools/components/theme/bootstrap/theme.php b/system/src/Grav/Console/Cli/DevTools/components/theme/bootstrap/theme.php
deleted file mode 100644
index 2bd4a5173..000000000
--- a/system/src/Grav/Console/Cli/DevTools/components/theme/bootstrap/theme.php
+++ /dev/null
@@ -1,9 +0,0 @@
-