(Grav GitSync) Automatic Commit from RealStickman
197
plugins/devtools/CHANGELOG.md
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
# v1.5.4
|
||||||
|
## 10/26/2021
|
||||||
|
|
||||||
|
1. [](#improved)
|
||||||
|
* Moved offline check to CLI flag [#70](https://github.com/getgrav/grav-plugin-devtools/issues/70)
|
||||||
|
* Updated footer copyrights for Pure Blank
|
||||||
|
|
||||||
|
# v1.5.3
|
||||||
|
## 06/16/2021
|
||||||
|
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Fixes over-zealous regex that caused duplication in copy tasks [#69](https://github.com/getgrav/grav-plugin-devtools/issues/69)
|
||||||
|
|
||||||
|
# v1.5.2
|
||||||
|
## 05/19/2021
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* Added basic TailwindCSS theme [#65](https://github.com/getgrav/grav-plugin-devtools/pull/65)
|
||||||
|
1. [](#improved)
|
||||||
|
* Fixed typo [#67](https://github.com/getgrav/grav-plugin-devtools/pull/67)
|
||||||
|
* Use canonical URLs [#58](https://github.com/getgrav/grav-plugin-devtools/pull/58)
|
||||||
|
* Replace `theme_config` with `config.theme` [#60](https://github.com/getgrav/grav-plugin-devtools/pull/60)
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Fixed a bad path regarding composer install after plugin creation
|
||||||
|
|
||||||
|
# v1.5.1
|
||||||
|
## 03/17/2021
|
||||||
|
|
||||||
|
1. [](#improved)
|
||||||
|
* Clearer instructions for composer initialization [#62](https://github.com/getgrav/grav-plugin-devtools/pull/62)
|
||||||
|
* Comment out autoload subscription event by default now that Grav 1.7 is out [#62](https://github.com/getgrav/grav-plugin-devtools/pull/62)
|
||||||
|
|
||||||
|
# v1.5.0
|
||||||
|
## 02/18/2021
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* Updated CLI commands for latest standards
|
||||||
|
* Pass phpstan level 8 tests
|
||||||
|
1. [](#improved)
|
||||||
|
* Add default configuration to an inherited theme's YAML file [getgrav/grav-premium-issues#50](https://github.com/getgrav/grav-premium-issues/issues/50)
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Output cmd does not correctly show colors [#56](https://github.com/getgrav/grav-plugin-devtools/issues/56)
|
||||||
|
|
||||||
|
# v1.4.2
|
||||||
|
## 12/02/2020
|
||||||
|
|
||||||
|
1. [](#improved)
|
||||||
|
* User return typehints in plugin.php
|
||||||
|
* Add proper twig escapes into a new theme
|
||||||
|
|
||||||
|
# v1.4.1
|
||||||
|
## 05/20/2020
|
||||||
|
|
||||||
|
1. [](#improved)
|
||||||
|
* Make name key Composer 2.0 compatible [#48](https://github.com/getgrav/grav-plugin-devtools/pull/48)
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Correct type for themes [#49](https://github.com/getgrav/grav-plugin-devtools/pull/49)
|
||||||
|
|
||||||
|
# v1.4.0
|
||||||
|
## 04/27/2020
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* Added new required `slug:` and `type:` attributes to blueprints
|
||||||
|
1. [](#improved)
|
||||||
|
* Fixed plugin autoload
|
||||||
|
|
||||||
|
# v1.3.1
|
||||||
|
## 02/24/2020
|
||||||
|
|
||||||
|
1. [](#improved)
|
||||||
|
* Set `validation: loose` in plugin blueprints by default
|
||||||
|
* Add Grav 1.6 dependency to all new plugins and themes
|
||||||
|
|
||||||
|
# v1.3.0
|
||||||
|
## 02/13/2020
|
||||||
|
|
||||||
|
1. [](#improved)
|
||||||
|
* Added composer-based autoloader to the `new-plugin` command
|
||||||
|
|
||||||
|
# v1.2.4
|
||||||
|
## 11/06/2019
|
||||||
|
|
||||||
|
1. [](#improved)
|
||||||
|
* Added the ability to use devtools without an online connection to GPM
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Regression fix for missing `theme_config` in pure-blank [#45](https://github.com/getgrav/grav-plugin-devtools/issues/45)
|
||||||
|
|
||||||
|
# v1.2.3
|
||||||
|
## 06/20/2019
|
||||||
|
|
||||||
|
1. [](#improved)
|
||||||
|
* pure-blank: Use new 'deferred' blocks for header
|
||||||
|
* pure-blank: Use `home_url` variable
|
||||||
|
* pure-blank: Improved `README.md.twig`
|
||||||
|
|
||||||
|
# v1.2.2
|
||||||
|
## 04/21/2019
|
||||||
|
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Add Github username field to new-theme template [#39](https://github.com/getgrav/grav-plugin-devtools/pull/39)
|
||||||
|
|
||||||
|
# v1.2.1
|
||||||
|
## 08/04/2018
|
||||||
|
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Fixed incorrect folder name as a result of renaming typo of `inheritence` to `inheritance` [#32](https://github.com/getgrav/grav-plugin-devtools/issues/32)
|
||||||
|
|
||||||
|
# v1.2.0
|
||||||
|
## 07/25/2018
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* Internationalization for blank plugin component [#30](https://github.com/getgrav/grav-plugin-devtools/issues/30)
|
||||||
|
1. [](#improved)
|
||||||
|
* Added a new check for reserved PHP words [#7](https://github.com/getgrav/grav-plugin-devtools/issues/7)
|
||||||
|
* Improved regex for valid emails [#21](https://github.com/getgrav/grav-plugin-devtools/issues/21)
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Fix broken renaming when doing a theme 'copy'
|
||||||
|
* Typos [#31](https://github.com/getgrav/grav-plugin-devtools/pull/31)
|
||||||
|
|
||||||
|
# v1.1.1
|
||||||
|
## 03/29/2018
|
||||||
|
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Fixed theme inheritance bug [#25](https://github.com/getgrav/grav-plugin-devtools/pull/25)
|
||||||
|
|
||||||
|
# v1.1.0
|
||||||
|
## 03/29/2018
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* Added new Theme `copy` option to create a new theme from another
|
||||||
|
1. [](#improved)
|
||||||
|
* Stop flushing GPM cache on each call to speed things up considerably!
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Updated README.md [#23](https://github.com/getgrav/grav-plugin-devtools/pull/23)
|
||||||
|
* Properly extend Theme or Plugin [#24](https://github.com/getgrav/grav-plugin-devtools/pull/24)
|
||||||
|
|
||||||
|
# v1.0.8
|
||||||
|
## 10/02/2017
|
||||||
|
|
||||||
|
1. [](#bugfix)
|
||||||
|
inherited theme is after new theme [#9](https://github.com/getgrav/grav-plugin-devtools/issues/9)
|
||||||
|
|
||||||
|
# v1.0.7
|
||||||
|
## 10/02/2017
|
||||||
|
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Various fixes for things that broke with the blueprint generation PR [#20](https://github.com/getgrav/grav-plugin-devtools/issues/20)
|
||||||
|
|
||||||
|
# v1.0.6
|
||||||
|
## 09/28/2017
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* Added blueprint generation [#17](https://github.com/getgrav/grav-plugin-devtools/pull/17)
|
||||||
|
1. [](#improved)
|
||||||
|
* changed Pure CDN location [#19](https://github.com/getgrav/grav-plugin-devtools/pull/19)
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Fixed readme referencing `githubid` [#13](https://github.com/getgrav/grav-plugin-devtools/pull/13)
|
||||||
|
|
||||||
|
# v1.0.5
|
||||||
|
## 02/26/2017
|
||||||
|
|
||||||
|
1. [](#improved)
|
||||||
|
* Added GitHub ID prompt [#5](https://github.com/getgrav/grav-plugin-devtools/pull/5)
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Added missing closing html tag [#12](https://github.com/getgrav/grav-plugin-devtools/pull/12)
|
||||||
|
|
||||||
|
# v1.0.4
|
||||||
|
## 10/19/2016
|
||||||
|
|
||||||
|
1. [](#improved)
|
||||||
|
* More complete README.md
|
||||||
|
* Typo in Error template
|
||||||
|
|
||||||
|
# v1.0.3
|
||||||
|
## 09/16/2016
|
||||||
|
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Removed `Theme` from theme's class causing events to not process - https://github.com/getgrav/grav/issues/1047
|
||||||
|
* Typo in README.md
|
||||||
|
|
||||||
|
# v1.0.2
|
||||||
|
## 07/20/2016
|
||||||
|
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Removed old `header.html.twig`
|
||||||
|
|
||||||
|
# v1.0.1
|
||||||
|
## 05/06/2016
|
||||||
|
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Fix for Grav 1.0.x
|
||||||
|
|
||||||
|
# v1.0.0
|
||||||
|
## 04/19/2016
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* ChangeLog started...
|
21
plugins/devtools/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Grav
|
||||||
|
|
||||||
|
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.
|
79
plugins/devtools/README.md
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
# Grav Devtools Plugin
|
||||||
|
|
||||||
|
The `devtools` is a [Grav](http://github.com/getgrav/grav) Plugin that lets you quickly create a scaffolding for your new plugins and themes. The plugin provides CLI commands that allow for the quick and easy deployment of a sample scaffolding for your new plugin.
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
## GPM Installation (Preferred)
|
||||||
|
|
||||||
|
The simplest way to install this plugin is via the [Grav Package Manager (GPM)](http://learn.getgrav.org/advanced/grav-gpm). From the root of your Grav install type:
|
||||||
|
|
||||||
|
bin/gpm install devtools
|
||||||
|
|
||||||
|
## Manual Installation
|
||||||
|
|
||||||
|
If for some reason you can't use GPM you can manually install this plugin. Download the zip version of this repository and unzip it under `/your/site/grav/user/plugins`. Then, rename the folder to `devtools`.
|
||||||
|
|
||||||
|
You should now have all the plugin files under
|
||||||
|
|
||||||
|
/your/site/grav/user/plugins/devtools
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
By default, devtools will perform a check with the online gpm repository to ensure name-collision avoidance. If you wish to not perform this online check, change the devtools.yaml at `user/config/plugins` from `collision_check: true` to `collision_check: false`.
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
## Plugin Scaffolding
|
||||||
|
|
||||||
|
To create a new plugin you simply need to run: `bin/plugin devtools new-plugin` and fill in the few questions at the prompts:
|
||||||
|
|
||||||
|
```
|
||||||
|
> bin/plugin devtools new-plugin
|
||||||
|
Enter Plugin Name: MyPlugin
|
||||||
|
Enter Plugin Description: My New Custom Plugin
|
||||||
|
Enter Developer Name: Johnny Rotten
|
||||||
|
Enter GitHub ID (can be blank): pretty-vacant
|
||||||
|
Enter Developer Email: johnny@rotten.com
|
||||||
|
|
||||||
|
SUCCESS plugin myplugin -> Created Successfully
|
||||||
|
|
||||||
|
Path: /home/johnnyr/webroot/grav-installation/user/plugins/myplugin
|
||||||
|
```
|
||||||
|
|
||||||
|
## Theme Scaffolding
|
||||||
|
|
||||||
|
To create a new theme you simply need to run: `bin/plugin devtools new-theme` and fill in the few questions at the prompts:
|
||||||
|
|
||||||
|
```
|
||||||
|
> bin/plugin devtools new-theme
|
||||||
|
Enter Theme Name: MyTheme
|
||||||
|
Enter Theme Description: My New Custom Theme
|
||||||
|
Enter Developer Name: Johnny Rotten
|
||||||
|
Enter GitHub ID (can be blank): pretty-vacant
|
||||||
|
Enter Developer Email: johnny@rotten.com
|
||||||
|
Please choose a template type
|
||||||
|
[pure-blank ] Basic Theme using Pure.css
|
||||||
|
[inheritance] Inherit from another theme
|
||||||
|
[copy ] Copy another theme
|
||||||
|
> pure-blank
|
||||||
|
|
||||||
|
SUCCESS theme mytheme -> Created Successfully
|
||||||
|
|
||||||
|
Path: /home/johnnyr/webroot/grav-installation/user/themes/mytheme
|
||||||
|
```
|
||||||
|
|
||||||
|
There are **three template creation options**
|
||||||
|
|
||||||
|
1. `pure-blank` - This is a very basic blank theme that uses the [Pure CSS framework](http://purecss.io/)
|
||||||
|
2. `inheritance` - This creates a very basic template with minimal files that inherits a base theme. To find out more about theme inheritance, [check out the subject in more details on the Grav Learn site](https://learn.getgrav.org/themes/customization#theme-inheritance).
|
||||||
|
3. `copy` - This allows you to create a new theme based on an existing theme. This is the simplest way to get started with a new theme by using another theme as the basis.
|
||||||
|
|
||||||
|
## Skipping Online Project Name Collision Checking
|
||||||
|
|
||||||
|
By default, devtools will check your project's name with the existing gpm ecosystem to ensure no collisions. In order to skip this check, add an `--offline` or `-o` to your command:
|
||||||
|
|
||||||
|
`bin/plugin devtools new-theme --offline`
|
||||||
|
or
|
||||||
|
|
||||||
|
`bin/plugin devtools new-theme -o`
|
41
plugins/devtools/blueprints.yaml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
name: DevTools
|
||||||
|
slug: devtools
|
||||||
|
type: plugin
|
||||||
|
version: 1.5.4
|
||||||
|
description: Plugin and Theme scaffolding utilities
|
||||||
|
icon: cogs
|
||||||
|
author:
|
||||||
|
name: Team Grav
|
||||||
|
email: devs@getgrav.org
|
||||||
|
url: http://getgrav.org
|
||||||
|
homepage: https://github.com/getgrav/grav-plugin-devtools
|
||||||
|
keywords: devtools, plugin, theme
|
||||||
|
bugs: https://github.com/getgrav/grav-plugin-devtools/issues
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- { name: grav, version: '>=1.7.0' }
|
||||||
|
|
||||||
|
form:
|
||||||
|
validation: strict
|
||||||
|
fields:
|
||||||
|
enabled:
|
||||||
|
type: toggle
|
||||||
|
label: PLUGIN_ADMIN.PLUGIN_STATUS
|
||||||
|
highlight: 1
|
||||||
|
default: 0
|
||||||
|
options:
|
||||||
|
1: PLUGIN_ADMIN.ENABLED
|
||||||
|
0: PLUGIN_ADMIN.DISABLED
|
||||||
|
validate:
|
||||||
|
type: bool
|
||||||
|
collision_check:
|
||||||
|
type: toggle
|
||||||
|
label: PLUGIN_DEVTOOLS.COLLISION_CHECK
|
||||||
|
highlight: 1
|
||||||
|
default: 1
|
||||||
|
options:
|
||||||
|
1: PLUGIN_ADMIN.ENABLED
|
||||||
|
0: PLUGIN_ADMIN.DISABLED
|
||||||
|
validate:
|
||||||
|
type: bool
|
362
plugins/devtools/classes/DevToolsCommand.php
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Grav\Plugin\Console;
|
||||||
|
|
||||||
|
use Grav\Common\Grav;
|
||||||
|
use Grav\Common\Filesystem\Folder;
|
||||||
|
use Grav\Common\GPM\GPM;
|
||||||
|
use Grav\Common\Inflector;
|
||||||
|
use Grav\Common\Twig\Twig;
|
||||||
|
use Grav\Common\Utils;
|
||||||
|
use RocketTheme\Toolbox\File\File;
|
||||||
|
use Grav\Console\ConsoleCommand;
|
||||||
|
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class DevToolsCommand
|
||||||
|
* @package Grav\Plugin\Console
|
||||||
|
*/
|
||||||
|
class DevToolsCommand extends ConsoleCommand
|
||||||
|
{
|
||||||
|
/** @var array */
|
||||||
|
protected $component = [];
|
||||||
|
/** @var Inflector */
|
||||||
|
protected $inflector;
|
||||||
|
/** @var UniformResourceLocator */
|
||||||
|
protected $locator;
|
||||||
|
/** @var Twig */
|
||||||
|
protected $twig;
|
||||||
|
/** @var GPM */
|
||||||
|
protected $gpm;
|
||||||
|
/** @var array */
|
||||||
|
protected $options = [];
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
protected $reserved_keywords = ['__halt_compiler', 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor'];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the basic requirements for the developer tools
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function init(): void
|
||||||
|
{
|
||||||
|
if (!function_exists('curl_version')) {
|
||||||
|
exit('FATAL: DEVTOOLS requires PHP Curl module to be installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
$grav = Grav::instance();
|
||||||
|
$grav['config']->init();
|
||||||
|
$grav['uri']->init();
|
||||||
|
|
||||||
|
$this->inflector = $grav['inflector'];
|
||||||
|
$this->locator = $grav['locator'];
|
||||||
|
$this->twig = $grav['twig'];
|
||||||
|
$this->gpm = new GPM();
|
||||||
|
|
||||||
|
//Add `theme://` to prevent fail
|
||||||
|
$this->locator->addPath('theme', '', []);
|
||||||
|
$this->locator->addPath('plugin', '', []);
|
||||||
|
$this->locator->addPath('blueprint', '', []);
|
||||||
|
// $this->config->set('theme', $config->get('themes.' . $name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backwards compatibility to Grav 1.6.
|
||||||
|
*
|
||||||
|
* @return InputInterface
|
||||||
|
*/
|
||||||
|
public function getInput(): InputInterface
|
||||||
|
{
|
||||||
|
return $this->input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backwards compatibility to Grav 1.6.
|
||||||
|
*
|
||||||
|
* @return SymfonyStyle
|
||||||
|
*/
|
||||||
|
public function getIO(): SymfonyStyle
|
||||||
|
{
|
||||||
|
$output = $this->output;
|
||||||
|
if (!$output instanceof SymfonyStyle) {
|
||||||
|
$this->output = $output = new SymfonyStyle($this->input, $this->output);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the component type and renames accordingly
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function createComponent(): bool
|
||||||
|
{
|
||||||
|
$name = $this->component['name'];
|
||||||
|
$folder_name = strtolower($this->inflector::hyphenize($name));
|
||||||
|
$new_theme = $folder_name;
|
||||||
|
$type = $this->component['type'];
|
||||||
|
$grav = Grav::instance();
|
||||||
|
$config = $grav['config'];
|
||||||
|
$current_theme = $config->get('system.pages.theme');
|
||||||
|
$template = $this->component['template'];
|
||||||
|
$source_theme = null;
|
||||||
|
|
||||||
|
if (isset($this->component['copy'])) {
|
||||||
|
$current_theme = $this->component['copy'];
|
||||||
|
$source_theme = $this->locator->findResource('themes://' . $current_theme);
|
||||||
|
$template_folder = $source_theme;
|
||||||
|
} else {
|
||||||
|
$template_folder = __DIR__ . "/../components/{$type}/{$template}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type === 'blueprint') {
|
||||||
|
$component_folder = $this->locator->findResource('themes://' . $current_theme) . '/blueprints';
|
||||||
|
} else {
|
||||||
|
$component_folder = $this->locator->findResource($type . 's://') . DS . $folder_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false === $template_folder) {
|
||||||
|
$this->output->writeln("<red>Theme {$current_theme} does not exist</red>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($template === 'inheritance') {
|
||||||
|
$parent_theme = $this->component['extends'];
|
||||||
|
$yaml_file = $this->locator->findResource('themes://' . $parent_theme) . '/' . $parent_theme . '.yaml';
|
||||||
|
$this->component['config'] = file_get_contents($yaml_file);;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($source_theme)) {
|
||||||
|
/**
|
||||||
|
* Copy existing theme and regex-replace old stuff with new
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Get source if a symlink
|
||||||
|
if (is_link($template_folder)) {
|
||||||
|
$template_folder = readlink($template_folder);
|
||||||
|
if (false === $template_folder) {
|
||||||
|
$this->output->writeln("<red>Theme {$current_theme} is a bad symlink</red>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Copy All files to component folder
|
||||||
|
try {
|
||||||
|
Folder::copy($template_folder, $component_folder, '/.git|node_modules/');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->output->writeln("<red>" . $e->getMessage() . "</red>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do some filename renaming
|
||||||
|
$base_old_filename = $component_folder . '/' . $current_theme;
|
||||||
|
$base_new_filename = $component_folder . '/' . $new_theme;
|
||||||
|
@rename( $base_old_filename . '.php', $base_new_filename . '.php');
|
||||||
|
@rename( $base_old_filename . '.yaml', $base_new_filename . '.yaml');
|
||||||
|
|
||||||
|
$camelized_current = $this->inflector::camelize($current_theme);
|
||||||
|
$camelized_new = $this->inflector::camelize($name);
|
||||||
|
|
||||||
|
$hyphenized_current = $this->inflector::hyphenize($current_theme);
|
||||||
|
$hyphenized_new = $this->inflector::hyphenize($name);
|
||||||
|
|
||||||
|
$titleized_current = $this->inflector::titleize($current_theme);
|
||||||
|
$titleized_new = $this->inflector::titleize($name);
|
||||||
|
|
||||||
|
$underscoreized_current = $this->inflector::underscorize($current_theme);
|
||||||
|
$underscoreized_new = $this->inflector::underscorize($name);
|
||||||
|
|
||||||
|
$variations_regex = [
|
||||||
|
["/$camelized_current/", "/$hyphenized_current/"],
|
||||||
|
[$camelized_new, $hyphenized_new]
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!in_array("/$titleized_current/", array_values($variations_regex[0]))) {
|
||||||
|
$current_regex = $variations_regex[0];
|
||||||
|
$new_regex = $variations_regex[1];
|
||||||
|
$current_regex[] = "/$titleized_current/";
|
||||||
|
$new_regex[] = $titleized_new;
|
||||||
|
$variations_regex = [$current_regex, $new_regex];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array("/$underscoreized_current/", array_values($variations_regex[0]))) {
|
||||||
|
$current_regex = $variations_regex[0];
|
||||||
|
$new_regex = $variations_regex[1];
|
||||||
|
$current_regex[] = "/$underscoreized_current/";
|
||||||
|
$new_regex[] = $underscoreized_new;
|
||||||
|
$variations_regex = [$current_regex, $new_regex];
|
||||||
|
}
|
||||||
|
|
||||||
|
$regex_array = [
|
||||||
|
$new_theme . '.php' => $variations_regex,
|
||||||
|
'blueprints.yaml' => $variations_regex,
|
||||||
|
'README.md' => $variations_regex,
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($regex_array as $filename => $data) {
|
||||||
|
$filename = $component_folder . '/' . $filename;
|
||||||
|
if (!file_exists($filename)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$file = file_get_contents($filename);
|
||||||
|
if ($file) {
|
||||||
|
$file = preg_replace($data[0], $data[1], $file);
|
||||||
|
}
|
||||||
|
file_put_contents($filename, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $source_theme;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/**
|
||||||
|
* Use components folder and twig processing
|
||||||
|
*/
|
||||||
|
//Copy All files to component folder
|
||||||
|
try {
|
||||||
|
Folder::copy($template_folder, $component_folder);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->output->writeln("<red>" . $e->getMessage() . "</red>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add Twig vars and templates then initialize
|
||||||
|
$this->twig->twig_vars['component'] = $this->component;
|
||||||
|
$this->twig->twig_paths[] = $template_folder;
|
||||||
|
$this->twig->init();
|
||||||
|
|
||||||
|
//Get all templates of component then process each with twig and save
|
||||||
|
$templates = Folder::all($component_folder);
|
||||||
|
|
||||||
|
try {
|
||||||
|
foreach($templates as $templateFile) {
|
||||||
|
if (Utils::endsWith($templateFile, '.twig') && !Utils::endsWith($templateFile, '.html.twig')) {
|
||||||
|
$content = $this->twig->processTemplate($templateFile);
|
||||||
|
$file = File::instance($component_folder . DS . str_replace('.twig', '', $templateFile));
|
||||||
|
$file->content($content);
|
||||||
|
$file->save();
|
||||||
|
|
||||||
|
//Delete twig template
|
||||||
|
$file = File::instance($component_folder . DS . $templateFile);
|
||||||
|
$file->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->output->writeln("<red>" . $e->getMessage() . "</red>");
|
||||||
|
$this->output->writeln("Rolling back...");
|
||||||
|
Folder::delete($component_folder);
|
||||||
|
$this->output->writeln($type . "creation failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($type !== 'blueprint') {
|
||||||
|
rename($component_folder . DS . $type . '.php', $component_folder . DS . $folder_name . '.php');
|
||||||
|
rename($component_folder . DS . $type . '.yaml', $component_folder . DS . $folder_name . '.yaml');
|
||||||
|
} else {
|
||||||
|
$bpname = $this->inflector::hyphenize($this->component['bpname']);
|
||||||
|
rename($component_folder . DS . $type . '.yaml', $component_folder . DS . $bpname . '.yaml');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->output->writeln('');
|
||||||
|
$this->output->writeln('<green>SUCCESS</green> ' . $type . ' <magenta>' . $name . '</magenta> -> Created Successfully');
|
||||||
|
$this->output->writeln('');
|
||||||
|
$this->output->writeln('Path: <cyan>' . $component_folder . '</cyan>');
|
||||||
|
$this->output->writeln('');
|
||||||
|
if ($type === 'plugin') {
|
||||||
|
$this->output->writeln('<yellow>Please run `cd ' . $component_folder . '` and `composer update` to initialize the autoloader</yellow>');
|
||||||
|
$this->output->writeln('');
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterate through all options and validate
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function validateOptions(): void
|
||||||
|
{
|
||||||
|
foreach (array_filter($this->options) as $type => $value) {
|
||||||
|
$this->validate($type, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $type
|
||||||
|
* @param mixed $value
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function validate(string $type, $value)
|
||||||
|
{
|
||||||
|
switch ($type) {
|
||||||
|
case 'name':
|
||||||
|
// Check If name
|
||||||
|
if ($value === null || trim($value) === '') {
|
||||||
|
throw new \RuntimeException('Name cannot be empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->options['offline']) {
|
||||||
|
// Check for name collision with online gpm.
|
||||||
|
if (false !== $this->gpm->findPackage($value)) {
|
||||||
|
throw new \RuntimeException('Package name exists in GPM');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->output->writeln('');
|
||||||
|
$this->output->writeln(' <red>Warning</red>: Please note that by skipping the online check, your project\'s plugin or theme name may conflict with an existing plugin or theme.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's reserved
|
||||||
|
if ($this->isReservedWord(strtolower($value))) {
|
||||||
|
throw new \RuntimeException("\"" . $value . "\" is a reserved word and cannot be used as the name");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'description':
|
||||||
|
if($value === null || trim($value) === '') {
|
||||||
|
throw new \RuntimeException('Description cannot be empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'themename':
|
||||||
|
if($value === null || trim($value) === '') {
|
||||||
|
throw new \RuntimeException('Theme Name cannot be empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'developer':
|
||||||
|
if ($value === null || trim($value) === '') {
|
||||||
|
throw new \RuntimeException('Developer\'s Name cannot be empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'githubid':
|
||||||
|
// GitHubID can be blank, so nothing here
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'email':
|
||||||
|
if (!preg_match('/^(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){255,})(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){65,}@)(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22))(?:\.(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-[a-z0-9]+)*\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-[a-z0-9]+)*)|(?:\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\]))$/iD', $value)) {
|
||||||
|
throw new \RuntimeException('Not a valid email address');
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $word
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isReservedWord(string $word): bool
|
||||||
|
{
|
||||||
|
return in_array($word, $this->reserved_keywords, true);
|
||||||
|
}
|
||||||
|
}
|
88
plugins/devtools/cli/NewBlueprintCommand.php
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Grav\Plugin\Console;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||||
|
use Symfony\Component\Console\Question\Question;
|
||||||
|
|
||||||
|
require_once(__DIR__ . '/../classes/DevToolsCommand.php');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class NewThemeCommand
|
||||||
|
* @package Grav\Console\Cli\DevTools
|
||||||
|
*/
|
||||||
|
class NewBlueprintCommand extends DevToolsCommand
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function configure(): void
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->setName('new-blueprint')
|
||||||
|
->setAliases(['newblueprint','blueprint'])
|
||||||
|
->addOption(
|
||||||
|
'bpname',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'The name of your new Grav theme'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'name',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'The name of your new Grav theme'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'template',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'The name/username of the developer'
|
||||||
|
)
|
||||||
|
->setDescription('Create a blueprint that extend the default.yaml blueprint files')
|
||||||
|
->setHelp('The <info>new-blueprint</info> command creates a new blueprint file.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected function serve(): int
|
||||||
|
{
|
||||||
|
$this->init();
|
||||||
|
|
||||||
|
$input = $this->getInput();
|
||||||
|
$io = $this->getIO();
|
||||||
|
|
||||||
|
$this->component['type'] = 'blueprint';
|
||||||
|
$this->component['template'] = 'modular';
|
||||||
|
$this->component['version'] = '0.1.0';
|
||||||
|
$this->component['themename'] = 'bonjour';
|
||||||
|
|
||||||
|
$this->options = [
|
||||||
|
'name' => $input->getOption('name'),
|
||||||
|
'bpname' => $input->getOption('bpname'),
|
||||||
|
'template' => $input->getOption('template'),
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->validateOptions();
|
||||||
|
|
||||||
|
$this->component = array_replace($this->component, $this->options);
|
||||||
|
|
||||||
|
if (!$this->options['template']) {
|
||||||
|
$question = new ChoiceQuestion('Please choose a template type', ['newtab', 'append']);
|
||||||
|
|
||||||
|
$this->component['template'] = $io->askQuestion($question);
|
||||||
|
}
|
||||||
|
if (!$this->options['bpname']) {
|
||||||
|
$question = new Question('Enter <yellow>Blueprint Name</yellow>');
|
||||||
|
|
||||||
|
$this->component['bpname'] = $io->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->createComponent();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
146
plugins/devtools/cli/NewPluginCommand.php
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Grav\Plugin\Console;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Question\Question;
|
||||||
|
|
||||||
|
require_once(__DIR__ . '/../classes/DevToolsCommand.php');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class NewPluginCommand
|
||||||
|
* @package Grav\Console\Cli\DevTools
|
||||||
|
*/
|
||||||
|
class NewPluginCommand extends DevToolsCommand
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function configure(): void
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->setName('new-plugin')
|
||||||
|
->setAliases(['newplugin'])
|
||||||
|
->addOption(
|
||||||
|
'name',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'The name of your new Grav plugin'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'desc',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'A description of your new Grav plugin'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'dev',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'The name/username of the developer'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'github',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'The developer\'s GitHub ID'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'email',
|
||||||
|
'e',
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'The developer\'s email'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'offline',
|
||||||
|
'o',
|
||||||
|
InputOption::VALUE_NONE,
|
||||||
|
'Skip online name collision check'
|
||||||
|
)
|
||||||
|
->setDescription('Creates a new Grav plugin with the basic required files')
|
||||||
|
->setHelp('The <info>new-plugin</info> command creates a new Grav instance and performs the creation of a plugin.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected function serve(): int
|
||||||
|
{
|
||||||
|
$this->init();
|
||||||
|
|
||||||
|
$input = $this->getInput();
|
||||||
|
$io = $this->getIO();
|
||||||
|
|
||||||
|
$this->component['type'] = 'plugin';
|
||||||
|
$this->component['template'] = 'blank';
|
||||||
|
$this->component['version'] = '0.1.0';
|
||||||
|
|
||||||
|
$this->options = [
|
||||||
|
'name' => $input->getOption('name'),
|
||||||
|
'description' => $input->getOption('desc'),
|
||||||
|
'author' => [
|
||||||
|
'name' => $input->getOption('dev'),
|
||||||
|
'email' => $input->getOption('email'),
|
||||||
|
'githubid' => $input->getOption('github')
|
||||||
|
],
|
||||||
|
'offline' => $input->getOption('offline'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->validateOptions();
|
||||||
|
|
||||||
|
$this->component = array_replace($this->component, $this->options);
|
||||||
|
|
||||||
|
if (!$this->options['name']) {
|
||||||
|
$question = new Question('Enter <yellow>Plugin Name</yellow>');
|
||||||
|
$question->setValidator(function ($value) {
|
||||||
|
return $this->validate('name', $value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->component['name'] = $io->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->options['description']) {
|
||||||
|
$question = new Question('Enter <yellow>Plugin Description</yellow>');
|
||||||
|
$question->setValidator(function ($value) {
|
||||||
|
return $this->validate('description', $value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->component['description'] = $io->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->options['author']['name']) {
|
||||||
|
$question = new Question('Enter <yellow>Developer Name</yellow>');
|
||||||
|
$question->setValidator(function ($value) {
|
||||||
|
return $this->validate('developer', $value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->component['author']['name'] = $io->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!$this->options['author']['githubid']) {
|
||||||
|
$question = new Question('Enter <yellow>GitHub ID</yellow> (can be blank)');
|
||||||
|
$question->setValidator(function ($value) {
|
||||||
|
return $this->validate('githubid', $value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->component['author']['githubid'] = $io->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->options['author']['email']) {
|
||||||
|
$question = new Question('Enter <yellow>Developer Email</yellow>');
|
||||||
|
$question->setValidator(function ($value) {
|
||||||
|
return $this->validate('email', $value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->component['author']['email'] = $io->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->component['template'] = 'blank';
|
||||||
|
|
||||||
|
$this->createComponent();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
171
plugins/devtools/cli/NewThemeCommand.php
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Grav\Plugin\Console;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||||
|
use Symfony\Component\Console\Question\Question;
|
||||||
|
|
||||||
|
require_once(__DIR__ . '/../classes/DevToolsCommand.php');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class NewThemeCommand
|
||||||
|
* @package Grav\Console\Cli\DevTools
|
||||||
|
*/
|
||||||
|
class NewThemeCommand extends DevToolsCommand
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function configure(): void
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->setName('new-theme')
|
||||||
|
->setAliases(['newtheme'])
|
||||||
|
->addOption(
|
||||||
|
'name',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'The name of your new Grav theme'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'desc',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'A description of your new Grav theme'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'dev',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'The name/username of the developer'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'github',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'The developer\'s GitHub ID'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'email',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'The developer\'s email'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'offline',
|
||||||
|
'o',
|
||||||
|
InputOption::VALUE_NONE,
|
||||||
|
'Skip online name collision check'
|
||||||
|
)
|
||||||
|
->setDescription('Creates a new Grav theme with the basic required files')
|
||||||
|
->setHelp('The <info>new-theme</info> command creates a new Grav instance and performs the creation of a theme.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected function serve(): int
|
||||||
|
{
|
||||||
|
$this->init();
|
||||||
|
|
||||||
|
$input = $this->getInput();
|
||||||
|
$io = $this->getIO();
|
||||||
|
|
||||||
|
$this->component['type'] = 'theme';
|
||||||
|
$this->component['template'] = 'blank';
|
||||||
|
$this->component['version'] = '0.1.0';
|
||||||
|
|
||||||
|
$this->options = [
|
||||||
|
'name' => $input->getOption('name'),
|
||||||
|
'description' => $input->getOption('desc'),
|
||||||
|
'author' => [
|
||||||
|
'name' => $input->getOption('dev'),
|
||||||
|
'email' => $input->getOption('email'),
|
||||||
|
'githubid' => $input->getOption('github'),
|
||||||
|
],
|
||||||
|
'offline' => $input->getOption('offline'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->validateOptions();
|
||||||
|
|
||||||
|
$this->component = array_replace($this->component, $this->options);
|
||||||
|
|
||||||
|
if (!$this->options['name']) {
|
||||||
|
$question = new Question('Enter <yellow>Theme Name</yellow>');
|
||||||
|
$question->setValidator(function ($value) {
|
||||||
|
return $this->validate('name', $value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->component['name'] = $io->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->options['description']) {
|
||||||
|
$question = new Question('Enter <yellow>Theme Description</yellow>');
|
||||||
|
$question->setValidator(function ($value) {
|
||||||
|
return $this->validate('description', $value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->component['description'] = $io->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->options['author']['name']) {
|
||||||
|
$question = new Question('Enter <yellow>Developer Name</yellow>');
|
||||||
|
$question->setValidator(function ($value) {
|
||||||
|
return $this->validate('developer', $value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->component['author']['name'] = $io->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->options['author']['githubid']) {
|
||||||
|
$question = new Question('Enter <yellow>GitHub ID</yellow> (can be blank)');
|
||||||
|
$question->setValidator(function ($value) {
|
||||||
|
return $this->validate('githubid', $value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->component['author']['githubid'] = $io->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->options['author']['email']) {
|
||||||
|
$question = new Question('Enter <yellow>Developer Email</yellow>');
|
||||||
|
$question->setValidator(function ($value) {
|
||||||
|
return $this->validate('email', $value);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->component['author']['email'] = $io->askQuestion($question);
|
||||||
|
}
|
||||||
|
|
||||||
|
$question = new ChoiceQuestion(
|
||||||
|
'Please choose an option',
|
||||||
|
['pure-blank' => 'Basic Theme using Pure.css', 'tailwind' => 'Basic Theme using tailwind.css', 'inheritance' => 'Inherit from another theme', 'copy' => 'Copy another theme']
|
||||||
|
);
|
||||||
|
$this->component['template'] = $io->askQuestion($question);
|
||||||
|
|
||||||
|
if ($this->component['template'] === 'inheritance') {
|
||||||
|
$themes = $this->gpm->getInstalledThemes();
|
||||||
|
$installedThemes = [];
|
||||||
|
foreach ($themes as $key => $theme) {
|
||||||
|
$installedThemes[] = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
$question = new ChoiceQuestion('Please choose a theme to extend', $installedThemes);
|
||||||
|
$this->component['extends'] = $io->askQuestion($question);
|
||||||
|
} elseif ($this->component['template'] === 'copy') {
|
||||||
|
$themes = $this->gpm->getInstalledThemes();
|
||||||
|
$installedThemes = [];
|
||||||
|
foreach ($themes as $key => $theme) {
|
||||||
|
$installedThemes[] = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
$question = new ChoiceQuestion(
|
||||||
|
'Please choose a theme to copy',
|
||||||
|
$installedThemes
|
||||||
|
);
|
||||||
|
$this->component['copy'] = $io->askQuestion($question);
|
||||||
|
}
|
||||||
|
$this->createComponent();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
title: {{ component.bpname }}
|
||||||
|
extends@:
|
||||||
|
type: default
|
||||||
|
context: blueprints://pages
|
||||||
|
|
||||||
|
form:
|
||||||
|
fields:
|
||||||
|
tabs:
|
||||||
|
type: tabs
|
||||||
|
active: 1
|
||||||
|
|
||||||
|
fields:
|
||||||
|
content:
|
||||||
|
fields:
|
||||||
|
header.an_example_text_field:
|
||||||
|
type: text
|
||||||
|
label: Add a number
|
||||||
|
default: 5
|
||||||
|
validate:
|
||||||
|
required: true
|
||||||
|
type: int
|
@ -0,0 +1,15 @@
|
|||||||
|
title: Item
|
||||||
|
extends@:
|
||||||
|
type: default
|
||||||
|
context: blueprints://pages
|
||||||
|
|
||||||
|
form:
|
||||||
|
fields:
|
||||||
|
tabs:
|
||||||
|
fields:
|
||||||
|
blog:
|
||||||
|
type: tab
|
||||||
|
title: {{ component.bpname }}
|
||||||
|
|
||||||
|
fields:
|
||||||
|
header.mytextfield:
|
@ -0,0 +1,5 @@
|
|||||||
|
# v0.1.0
|
||||||
|
## {{ "now"|date("m/d/Y") }}
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* ChangeLog started...
|
21
plugins/devtools/components/plugin/blank/LICENSE.twig
Normal file
@ -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.
|
59
plugins/devtools/components/plugin/blank/README.md.twig
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
{% set component_title = (component.name|titleize) %}
|
||||||
|
{% set component_hyphenated = (component.name|hyphenize) %}
|
||||||
|
{% set developer_hyphenated = (component.author.githubid|hyphenize) %}
|
||||||
|
# {{ component_title }} Plugin
|
||||||
|
|
||||||
|
**This README.md file should be modified to describe the features, installation, configuration, and general usage of the plugin.**
|
||||||
|
|
||||||
|
The **{{ component_title }}** Plugin is an extension for [Grav CMS](http://github.com/getgrav/grav). {{ component.description }}
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Installing the {{ component_title }} plugin can be done in one of three ways: The GPM (Grav Package Manager) installation method lets you quickly install the plugin with a simple terminal command, the manual method lets you do so via a zip file, and the admin method lets you do so via the Admin Plugin.
|
||||||
|
|
||||||
|
### GPM Installation (Preferred)
|
||||||
|
|
||||||
|
To install the plugin via the [GPM](http://learn.getgrav.org/advanced/grav-gpm), through your system's terminal (also called the command line), navigate to the root of your Grav-installation, and enter:
|
||||||
|
|
||||||
|
bin/gpm install {{ component_hyphenated }}
|
||||||
|
|
||||||
|
This will install the {{ component_title }} plugin into your `/user/plugins`-directory within Grav. Its files can be found under `/your/site/grav/user/plugins/{{ component_hyphenated }}`.
|
||||||
|
|
||||||
|
### Manual Installation
|
||||||
|
|
||||||
|
To install the plugin manually, download the zip-version of this repository and unzip it under `/your/site/grav/user/plugins`. Then rename the folder to `{{ component_hyphenated }}`. You can find these files on [GitHub](https://github.com/{{ developer_hyphenated }}/grav-plugin-{{ component_hyphenated }}) or via [GetGrav.org](http://getgrav.org/downloads/plugins#extras).
|
||||||
|
|
||||||
|
You should now have all the plugin files under
|
||||||
|
|
||||||
|
/your/site/grav/user/plugins/{{ component_hyphenated }}
|
||||||
|
|
||||||
|
> NOTE: This plugin is a modular component for Grav which may require other plugins to operate, please see its [blueprints.yaml-file on GitHub](https://github.com/{{ developer_hyphenated }}/grav-plugin-{{ component_hyphenated }}/blob/master/blueprints.yaml).
|
||||||
|
|
||||||
|
### Admin Plugin
|
||||||
|
|
||||||
|
If you use the Admin Plugin, you can install the plugin directly by browsing the `Plugins`-menu and clicking on the `Add` button.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Before configuring this plugin, you should copy the `user/plugins/{{ component_hyphenated }}/{{ component_hyphenated }}.yaml` to `user/config/plugins/{{ component_hyphenated }}.yaml` and only edit that copy.
|
||||||
|
|
||||||
|
Here is the default configuration and an explanation of available options:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
enabled: true
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that if you use the Admin Plugin, a file with your configuration named {{component_hyphenated}}.yaml will be saved in the `user/config/plugins/`-folder once the configuration is saved in the Admin.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
**Describe how to use the plugin.**
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
**Did you incorporate third-party code? Want to thank somebody?**
|
||||||
|
|
||||||
|
## To Do
|
||||||
|
|
||||||
|
- [ ] Future plans, if any
|
||||||
|
|
@ -0,0 +1,37 @@
|
|||||||
|
{% set githubid = component.author.githubid ?: component.author.name|hyphenize -%}
|
||||||
|
name: {{ component.name|titleize }}
|
||||||
|
slug: {{ component.name|hyphenize }}
|
||||||
|
type: plugin
|
||||||
|
version: 0.1.0
|
||||||
|
description: {{ component.description }}
|
||||||
|
icon: plug
|
||||||
|
author:
|
||||||
|
name: {{ component.author.name }}
|
||||||
|
email: {{ component.author.email }}
|
||||||
|
homepage: https://github.com/{{ githubid }}/grav-plugin-{{ component.name|hyphenize }}
|
||||||
|
demo: http://demo.yoursite.com
|
||||||
|
keywords: grav, plugin, etc
|
||||||
|
bugs: https://github.com/{{ githubid }}/grav-plugin-{{ component.name|hyphenize }}/issues
|
||||||
|
docs: https://github.com/{{ githubid }}/grav-plugin-{{ component.name|hyphenize }}/blob/develop/README.md
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- { name: grav, version: '>=1.6.0' }
|
||||||
|
|
||||||
|
form:
|
||||||
|
validation: loose
|
||||||
|
fields:
|
||||||
|
enabled:
|
||||||
|
type: toggle
|
||||||
|
label: PLUGIN_ADMIN.PLUGIN_STATUS
|
||||||
|
highlight: 1
|
||||||
|
default: 0
|
||||||
|
options:
|
||||||
|
1: PLUGIN_ADMIN.ENABLED
|
||||||
|
0: PLUGIN_ADMIN.DISABLED
|
||||||
|
validate:
|
||||||
|
type: bool
|
||||||
|
text_var:
|
||||||
|
type: text
|
||||||
|
label: PLUGIN_{{ component.name|underscorize|upper }}.TEXT_VARIABLE
|
||||||
|
help: PLUGIN_{{ component.name|underscorize|upper }}.TEXT_VARIABLE_HELP
|
30
plugins/devtools/components/plugin/blank/composer.json.twig
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{% set githubid = component.author.githubid ?: component.author.name|hyphenize -%}
|
||||||
|
{
|
||||||
|
"name": "{{ githubid|lower }}/{{ component.name|hyphenize }}",
|
||||||
|
"type": "grav-plugin",
|
||||||
|
"description": "{{ component.description }}",
|
||||||
|
"keywords": ["plugin"],
|
||||||
|
"homepage": "https://github.com/{{ githubid }}/grav-plugin-{{ component.name|hyphenize }}",
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "{{ component.author.name }}",
|
||||||
|
"email": "{{ component.author.email }}",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1.3"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Grav\\Plugin\\{{ component.name|camelize }}\\": "classes/"
|
||||||
|
},
|
||||||
|
"classmap": ["{{ component.name|hyphenize }}.php"]
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"platform": {
|
||||||
|
"php": "7.1.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
en:
|
||||||
|
PLUGIN_{{ component.name|underscorize|upper }}:
|
||||||
|
TEXT_VARIABLE: Text Variable
|
||||||
|
TEXT_VARIABLE_HELP: Text to add to the top of a page
|
59
plugins/devtools/components/plugin/blank/plugin.php.twig
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
namespace Grav\Plugin;
|
||||||
|
|
||||||
|
use Composer\Autoload\ClassLoader;
|
||||||
|
use Grav\Common\Plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class {{ component.name|camelize }}Plugin
|
||||||
|
* @package Grav\Plugin
|
||||||
|
*/
|
||||||
|
class {{ component.name|camelize }}Plugin extends Plugin
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* The getSubscribedEvents() gives the core a list of events
|
||||||
|
* that the plugin wants to listen to. The key of each
|
||||||
|
* array section is the event that the plugin listens to
|
||||||
|
* and the value (in the form of an array) contains the
|
||||||
|
* callable (or function) as well as the priority. The
|
||||||
|
* higher the number the higher the priority.
|
||||||
|
*/
|
||||||
|
public static function getSubscribedEvents(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'onPluginsInitialized' => [
|
||||||
|
// Uncomment following line when plugin requires Grav < 1.7
|
||||||
|
// ['autoload', 100000],
|
||||||
|
['onPluginsInitialized', 0]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Composer autoload
|
||||||
|
*
|
||||||
|
* @return ClassLoader
|
||||||
|
*/
|
||||||
|
public function autoload(): ClassLoader
|
||||||
|
{
|
||||||
|
return require __DIR__ . '/vendor/autoload.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the plugin
|
||||||
|
*/
|
||||||
|
public function onPluginsInitialized(): void
|
||||||
|
{
|
||||||
|
// Don't proceed if we are in the admin plugin
|
||||||
|
if ($this->isAdmin()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable the main events we are interested in
|
||||||
|
$this->enable([
|
||||||
|
// Put your main events here
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
enabled: true
|
||||||
|
text_var: Custom Text added by the **{{ component.name|titleize }}** plugin (disable plugin to remove)
|
@ -0,0 +1,5 @@
|
|||||||
|
# v0.1.0
|
||||||
|
## {{ "now"|date("m/d/Y") }}
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* ChangeLog started...
|
21
plugins/devtools/components/theme/inheritance/LICENSE.twig
Normal file
@ -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.
|
@ -0,0 +1,7 @@
|
|||||||
|
# {{ component.name|titleize }} Theme
|
||||||
|
|
||||||
|
The **{{ component.name|titleize }}** Theme is for [Grav CMS](http://github.com/getgrav/grav). This README.md file should be modified to describe the features, installation, configuration, and general usage of this theme.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
{{ component.description }}
|
@ -0,0 +1,19 @@
|
|||||||
|
{% set githubid = component.author.githubid ?: component.author.name|hyphenize -%}
|
||||||
|
name: {{ component.name|titleize }}
|
||||||
|
slug: {{ component.name|hyphenize }}
|
||||||
|
type: theme
|
||||||
|
version: 0.1.0
|
||||||
|
description: {{ component.description }}
|
||||||
|
icon: rebel
|
||||||
|
author:
|
||||||
|
name: {{ component.author.name }}
|
||||||
|
email: {{ component.author.email }}
|
||||||
|
homepage: https://github.com/{{ githubid }}/grav-theme-{{ component.name|hyphenize }}
|
||||||
|
demo: http://demo.yoursite.com
|
||||||
|
keywords: grav, theme, etc
|
||||||
|
bugs: https://github.com/{{ githubid }}/grav-theme-{{ component.name|hyphenize }}/issues
|
||||||
|
readme: https://github.com/{{ githubid }}/grav-theme-{{ component.name|hyphenize }}/blob/develop/README.md
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- { name: grav, version: '>=1.6.0' }
|
BIN
plugins/devtools/components/theme/inheritance/screenshot.jpg
Normal file
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
namespace Grav\Theme;
|
||||||
|
|
||||||
|
use Grav\Common\Theme;
|
||||||
|
|
||||||
|
class {{ component.name|camelize }} extends {{ component.extends|camelize }}
|
||||||
|
{
|
||||||
|
// Access plugin events in this class
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
streams:
|
||||||
|
schemes:
|
||||||
|
theme:
|
||||||
|
type: ReadOnlyStream
|
||||||
|
prefixes:
|
||||||
|
'':
|
||||||
|
- 'user://themes/{{ component.name|hyphenize }}'
|
||||||
|
- 'user://themes/{{ component.extends }}'
|
||||||
|
|
||||||
|
{{ component.config }}
|
BIN
plugins/devtools/components/theme/inheritance/thumbnail.jpg
Normal file
After Width: | Height: | Size: 3.6 KiB |
@ -0,0 +1,5 @@
|
|||||||
|
# v0.1.0
|
||||||
|
## {{ "now"|date("m/d/Y") }}
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* ChangeLog started...
|
21
plugins/devtools/components/theme/pure-blank/LICENSE.twig
Normal file
@ -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.
|
@ -0,0 +1,7 @@
|
|||||||
|
# {{ component.name|titleize }} Theme
|
||||||
|
|
||||||
|
The **{{ component.name|titleize }}** Theme is for [Grav CMS](http://github.com/getgrav/grav). This README.md file should be modified to describe the features, installation, configuration, and general usage of this theme.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
{{ component.description }}
|
@ -0,0 +1,33 @@
|
|||||||
|
{% set githubid = component.author.githubid ?: component.author.name|hyphenize -%}
|
||||||
|
name: {{ component.name|titleize }}
|
||||||
|
slug: {{ component.name|hyphenize }}
|
||||||
|
type: theme
|
||||||
|
version: 0.1.0
|
||||||
|
description: {{ component.description }}
|
||||||
|
icon: rebel
|
||||||
|
author:
|
||||||
|
name: {{ component.author.name }}
|
||||||
|
email: {{ component.author.email }}
|
||||||
|
homepage: https://github.com/{{ githubid }}/grav-theme-{{ component.name|hyphenize }}
|
||||||
|
demo: http://demo.yoursite.com
|
||||||
|
keywords: grav, theme, etc
|
||||||
|
bugs: https://github.com/{{ githubid }}/grav-theme-{{ component.name|hyphenize }}/issues
|
||||||
|
readme: https://github.com/{{ githubid }}/grav-theme-{{ component.name|hyphenize }}/blob/develop/README.md
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- { name: grav, version: '>=1.6.0' }
|
||||||
|
|
||||||
|
form:
|
||||||
|
validation: loose
|
||||||
|
fields:
|
||||||
|
dropdown.enabled:
|
||||||
|
type: toggle
|
||||||
|
label: Dropdown in Menu
|
||||||
|
highlight: 1
|
||||||
|
default: 1
|
||||||
|
options:
|
||||||
|
1: PLUGIN_ADMIN.ENABLED
|
||||||
|
0: PLUGIN_ADMIN.DISABLED
|
||||||
|
validate:
|
||||||
|
type: bool
|
175
plugins/devtools/components/theme/pure-blank/css/custom.css
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/* Core Stuff */
|
||||||
|
* {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.7;
|
||||||
|
color: #606d6e;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
color: #454B4D;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #1F8CD6;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: #175E91;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background: #F0F0F0;
|
||||||
|
margin: 1rem 0;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
border-left: 10px solid #eee;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Utility Classes */
|
||||||
|
.wrapper {
|
||||||
|
margin: 0 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding {
|
||||||
|
padding: 3rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
float: right
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Content Styling */
|
||||||
|
.header .padding {
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background-color: #1F8DD6;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header a {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header .logo {
|
||||||
|
font-size: 1.7rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Menu Settings */
|
||||||
|
.main-nav ul {
|
||||||
|
text-align: center;
|
||||||
|
letter-spacing: -1em;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-nav ul li {
|
||||||
|
display: inline-block;
|
||||||
|
letter-spacing: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-nav ul li a {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
line-height: 45px;
|
||||||
|
color: #fff;
|
||||||
|
padding: 0 20px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-nav > ul > li > a {
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Active dropdown nav item */
|
||||||
|
.main-nav ul li:hover > a {
|
||||||
|
background-color: #175E91;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Selected Dropdown nav item */
|
||||||
|
.main-nav ul li.selected > a {
|
||||||
|
background-color: #fff;
|
||||||
|
color: #175E91;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dropdown CSS */
|
||||||
|
.main-nav ul li {position: relative;}
|
||||||
|
|
||||||
|
.main-nav ul li ul {
|
||||||
|
position: absolute;
|
||||||
|
background-color: #1F8DD6;
|
||||||
|
min-width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
z-index: 999;
|
||||||
|
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.main-nav ul li ul li {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dropdown CSS */
|
||||||
|
.main-nav ul li ul ul {
|
||||||
|
left: 100%;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Active on Hover */
|
||||||
|
.main-nav li:hover > ul {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Child Indicator */
|
||||||
|
.main-nav .has-children > a {
|
||||||
|
padding-right: 30px;
|
||||||
|
}
|
||||||
|
.main-nav .has-children > a:after {
|
||||||
|
font-family: FontAwesome;
|
||||||
|
content: '\f107';
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
right: 8px;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-nav .has-children .has-children > a:after {
|
||||||
|
content: '\f105';
|
||||||
|
}
|
BIN
plugins/devtools/components/theme/pure-blank/images/logo.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
plugins/devtools/components/theme/pure-blank/screenshot.jpg
Normal file
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,5 @@
|
|||||||
|
{% extends 'partials/base.html.twig' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{{ page.content|raw }}
|
||||||
|
{% endblock %}
|
@ -0,0 +1,8 @@
|
|||||||
|
{% extends 'partials/base.html.twig' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="lead text-center">
|
||||||
|
<h1>Error!</h1>
|
||||||
|
{{ page.content|raw }}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,70 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{ (grav.language.getActive ?: grav.config.site.default_lang)|e }}">
|
||||||
|
<head>
|
||||||
|
{% block head %}
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>{% if header.title %}{{ header.title|e }} | {% endif %}{{ site.title|e }}</title>
|
||||||
|
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
{% include 'partials/metadata.html.twig' %}
|
||||||
|
|
||||||
|
<link rel="icon" type="image/png" href="{{ url('theme://images/logo.png')|e }}" />
|
||||||
|
<link rel="canonical" href="{{ page.canonical(true)|e }}" />
|
||||||
|
{% endblock head %}
|
||||||
|
|
||||||
|
{% block stylesheets %}
|
||||||
|
{% do assets.addCss('https://unpkg.com/purecss@1.0.0/build/pure-min.css', 100) %}
|
||||||
|
{% do assets.addCss('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css', 99) %}
|
||||||
|
{% do assets.addCss('theme://css/custom.css', 98) %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block javascripts %}
|
||||||
|
{% do assets.addJs('jquery', 100) %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block assets deferred %}
|
||||||
|
{{ assets.css()|raw }}
|
||||||
|
{{ assets.js()|raw }}
|
||||||
|
{% endblock %}
|
||||||
|
</head>
|
||||||
|
<body id="top" class="{{ page.header.body_classes|e }}">
|
||||||
|
|
||||||
|
{% block header %}
|
||||||
|
<div class="header">
|
||||||
|
<div class="wrapper padding">
|
||||||
|
<a class="logo left" href="{{ home_url|e }}">
|
||||||
|
<i class="fa fa-rebel"></i>
|
||||||
|
{{ config.site.title|e }}
|
||||||
|
</a>
|
||||||
|
{% block header_navigation %}
|
||||||
|
<nav class="main-nav">
|
||||||
|
{% include 'partials/navigation.html.twig' %}
|
||||||
|
</nav>
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<section id="body">
|
||||||
|
<div class="wrapper padding">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block footer %}
|
||||||
|
<div class="footer text-center">
|
||||||
|
<div class="wrapper padding">
|
||||||
|
<p><a href="https://getgrav.org">Grav</a> was <i class="fa fa-code"></i> with <i class="fa fa-heart"></i> by <a href="https://trilby.media">Trilby Media, LLC</a>.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block bottom %}
|
||||||
|
{{ assets.js('bottom')|raw }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,47 @@
|
|||||||
|
{% macro loop(page) %}
|
||||||
|
{% for p in page.children.visible %}
|
||||||
|
{% set current_page = (p.active or p.activeChild) ? 'selected' : '' %}
|
||||||
|
{% if p.children.visible.count > 0 %}
|
||||||
|
<li class="has-children {{ current_page|e }}">
|
||||||
|
<a href="{{ p.url|e }}">
|
||||||
|
{% if p.header.icon %}<i class="fa fa-{{ p.header.icon|e }}"></i>{% endif %}
|
||||||
|
{{ p.menu|e }}
|
||||||
|
</a>
|
||||||
|
<ul>
|
||||||
|
{{ _self.loop(p) }}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="{{ current_page|e }}">
|
||||||
|
<a href="{{ p.url|e }}">
|
||||||
|
{% if p.header.icon %}<i class="fa fa-{{ p.header.icon|e }}"></i>{% endif %}
|
||||||
|
{{ p.menu|e }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{% if config.theme.dropdown.enabled %}
|
||||||
|
{{ _self.loop(pages) }}
|
||||||
|
{% else %}
|
||||||
|
{% for page in pages.children.visible %}
|
||||||
|
{% set current_page = (page.active or page.activeChild) ? 'selected' : '' %}
|
||||||
|
<li class="{{ current_page|e }}">
|
||||||
|
<a href="{{ page.url|e }}">
|
||||||
|
{% if page.header.icon %}<i class="fa fa-{{ page.header.icon|e }}"></i>{% endif %}
|
||||||
|
{{ page.menu|e }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% for mitem in site.menu %}
|
||||||
|
<li>
|
||||||
|
<a href="{{ mitem.url|e }}">
|
||||||
|
{% if mitem.icon %}<i class="fa fa-{{ mitem.icon|e }}"></i>{% endif %}
|
||||||
|
{{ mitem.text|e }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
namespace Grav\Theme;
|
||||||
|
|
||||||
|
use Grav\Common\Theme;
|
||||||
|
|
||||||
|
class {{ component.name|camelize }} extends Theme
|
||||||
|
{
|
||||||
|
// Access plugin events in this class
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
enabled: true
|
||||||
|
dropdown:
|
||||||
|
enabled: true
|
BIN
plugins/devtools/components/theme/pure-blank/thumbnail.jpg
Normal file
After Width: | Height: | Size: 3.6 KiB |
@ -0,0 +1,5 @@
|
|||||||
|
# v0.1.0
|
||||||
|
## {{ "now"|date("m/d/Y") }}
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* ChangeLog started...
|
21
plugins/devtools/components/theme/tailwind/LICENSE.twig
Normal file
@ -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.
|
41
plugins/devtools/components/theme/tailwind/README.md.twig
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# {{ component.name|titleize }} Theme
|
||||||
|
|
||||||
|
The **{{ component.name|titleize }}** Theme is for [Grav CMS](http://github.com/getgrav/grav). This README.md file should be modified to describe the features, installation, configuration, and general usage of this theme.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
{{ component.description }}
|
||||||
|
|
||||||
|
# Instructions
|
||||||
|
|
||||||
|
Run
|
||||||
|
|
||||||
|
`npm install` to setup tailwind and required plugins
|
||||||
|
|
||||||
|
How to build tailwind:
|
||||||
|
|
||||||
|
Development:
|
||||||
|
|
||||||
|
`npm run build` for single time compiling
|
||||||
|
|
||||||
|
`npm run watch` for constant development
|
||||||
|
|
||||||
|
Production:
|
||||||
|
|
||||||
|
`npm run prod` for production compiling. **Don't forget to turn on production mode in the theme config**# Instructions
|
||||||
|
|
||||||
|
Run
|
||||||
|
|
||||||
|
`npm install` to setup tailwind and required plugins
|
||||||
|
|
||||||
|
How to build tailwind:
|
||||||
|
|
||||||
|
Development:
|
||||||
|
|
||||||
|
`npm run build` for single time compiling
|
||||||
|
|
||||||
|
`npm run watch` for constant development
|
||||||
|
|
||||||
|
Production:
|
||||||
|
|
||||||
|
`npm run prod` for production compiling. **Don't forget to turn on production mode in the theme config**
|
@ -0,0 +1,43 @@
|
|||||||
|
{% set githubid = component.author.githubid ?: component.author.name|hyphenize -%}
|
||||||
|
name: {{ component.name|titleize }}
|
||||||
|
slug: {{ component.name|hyphenize }}
|
||||||
|
type: theme
|
||||||
|
version: 0.1.0
|
||||||
|
description: {{ component.description }}
|
||||||
|
icon: rebel
|
||||||
|
author:
|
||||||
|
name: {{ component.author.name }}
|
||||||
|
email: {{ component.author.email }}
|
||||||
|
homepage: https://github.com/{{ githubid }}/grav-theme-{{ component.name|hyphenize }}
|
||||||
|
demo: http://demo.yoursite.com
|
||||||
|
keywords: grav, theme, etc
|
||||||
|
bugs: https://github.com/{{ githubid }}/grav-theme-{{ component.name|hyphenize }}/issues
|
||||||
|
readme: https://github.com/{{ githubid }}/grav-theme-{{ component.name|hyphenize }}/blob/develop/README.md
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- { name: grav, version: '>=1.6.0' }
|
||||||
|
|
||||||
|
form:
|
||||||
|
validation: loose
|
||||||
|
fields:
|
||||||
|
dropdown.enabled:
|
||||||
|
type: toggle
|
||||||
|
label: Dropdown in Menu
|
||||||
|
highlight: 1
|
||||||
|
default: 1
|
||||||
|
options:
|
||||||
|
1: PLUGIN_ADMIN.ENABLED
|
||||||
|
0: PLUGIN_ADMIN.DISABLED
|
||||||
|
validate:
|
||||||
|
type: bool
|
||||||
|
production:
|
||||||
|
type: toggle
|
||||||
|
label: Production Mode
|
||||||
|
highlight: 1
|
||||||
|
default: 1
|
||||||
|
options:
|
||||||
|
1: PLUGIN_ADMIN.ENABLED
|
||||||
|
0: PLUGIN_ADMIN.DISABLED
|
||||||
|
validate:
|
||||||
|
type: bool
|
5
plugins/devtools/components/theme/tailwind/css/site.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/*@import 'yourcssfile.css';*/
|
||||||
|
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
BIN
plugins/devtools/components/theme/tailwind/images/logo.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
@ -0,0 +1,2 @@
|
|||||||
|
THEME_{{ component.name|hyphenize|replace({'-': '_'})|upper }}:
|
||||||
|
ERROR: 'Error!'
|
30
plugins/devtools/components/theme/tailwind/package.json.twig
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "{{ component.name }}",
|
||||||
|
"repository": "",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "postcss css/site.css -o dist/css/site.css --verbose",
|
||||||
|
"watch": "postcss css/site.css -o dist/css/site.css --watch --verbose",
|
||||||
|
"prod" : "postcss css/site.css -o dist/css/site.min.css --env production --verbose"
|
||||||
|
},
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {
|
||||||
|
"alpinejs": "^2.8.2",
|
||||||
|
"tailwindcss": "^2.1.2",
|
||||||
|
"@tailwindcss/forms": "^0.3.2",
|
||||||
|
"@tailwindcss/typography": "^0.4.0",
|
||||||
|
"tailwindcss-debug-screens": "^2.0.0",
|
||||||
|
"autoprefixer": "^10.2.5",
|
||||||
|
"precss": "^4.0.0",
|
||||||
|
"cssnano": "^4.1.11",
|
||||||
|
"postcss": "^8.2.9",
|
||||||
|
"postcss-cli": "^8.3.1",
|
||||||
|
"postcss-import": "^14.0.1",
|
||||||
|
"postcss-nested": "^5.0.5",
|
||||||
|
"postcss-hexrgba": "^2.0.1",
|
||||||
|
"postcss-color-function": "^4.1.0"
|
||||||
|
}
|
||||||
|
}
|
11
plugins/devtools/components/theme/tailwind/postcss.config.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
'postcss-import': {},
|
||||||
|
'precss': {},
|
||||||
|
'tailwindcss': {},
|
||||||
|
'postcss-nested': {},
|
||||||
|
'autoprefixer': {},
|
||||||
|
...process.env.NODE_ENV === 'production'
|
||||||
|
? {'cssnano': {}} : {}
|
||||||
|
},
|
||||||
|
}
|
BIN
plugins/devtools/components/theme/tailwind/screenshot.jpg
Normal file
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,70 @@
|
|||||||
|
const { colors } = require('tailwindcss/defaultTheme');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
purge: [
|
||||||
|
'../../config/**/*.yaml',
|
||||||
|
'../../pages/**/*.md',
|
||||||
|
'./blueprints/**/*.yaml',
|
||||||
|
'./js/**/*.js',
|
||||||
|
'./templates/**/*.twig',
|
||||||
|
'./{{ component.name|hyphenize }}.yaml',
|
||||||
|
'./{{ component.name|hyphenize }}.php'
|
||||||
|
],
|
||||||
|
darkMode: 'class', //false or 'media' or 'class'
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
screens: {
|
||||||
|
sm: '640px',
|
||||||
|
md: '768px',
|
||||||
|
lg: '1024px',
|
||||||
|
xl: '1280px',
|
||||||
|
'2xl': '1536px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors: {
|
||||||
|
'primary': {
|
||||||
|
'lighter': colors.yellow['300'],
|
||||||
|
DEFAULT: colors.yellow['400'],
|
||||||
|
'darker' : colors.yellow['500'],
|
||||||
|
},
|
||||||
|
black: colors.black,
|
||||||
|
white: colors.white,
|
||||||
|
red: colors.red,
|
||||||
|
green: colors.green,
|
||||||
|
blue: colors.blue,
|
||||||
|
orange: colors.orange,
|
||||||
|
indigo: colors.indigo,
|
||||||
|
transparent: 'transparent',
|
||||||
|
'inherit': 'inherit',
|
||||||
|
},
|
||||||
|
typography: (theme) => ({
|
||||||
|
DEFAULT: {
|
||||||
|
css: {
|
||||||
|
color: 'inherit',
|
||||||
|
lineHeight: 'inherit',
|
||||||
|
maxWidth: 'inherit',
|
||||||
|
a: {
|
||||||
|
transition: 'all 500ms',
|
||||||
|
color: theme('colors.primary.DEFAULT'),
|
||||||
|
'&:hover': {
|
||||||
|
color: theme('colors.primary.darker')
|
||||||
|
},
|
||||||
|
textDecoration: 'none'
|
||||||
|
},
|
||||||
|
strong: {
|
||||||
|
color: 'inherit'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
require('@tailwindcss/typography'),
|
||||||
|
require('@tailwindcss/forms'),
|
||||||
|
require('tailwindcss-debug-screens'),
|
||||||
|
],
|
||||||
|
important: false,
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
{% extends 'partials/base.html.twig' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{{ page.content|raw }}
|
||||||
|
{% endblock %}
|
@ -0,0 +1,8 @@
|
|||||||
|
{% extends 'partials/base.html.twig' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="prose">
|
||||||
|
<h1>{{ 'THEME_TAILWIND.ERROR'|t }}</h1>
|
||||||
|
{{ page.content|raw }}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,67 @@
|
|||||||
|
{% set extension = config.theme.production ? '.min' : '' %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{ (grav.language.getActive ?: grav.config.site.default_lang)|e }}">
|
||||||
|
<head>
|
||||||
|
{% block head %}
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>{% if header.title %}{{ header.title|e }} | {% endif %}{{ site.title|e }}</title>
|
||||||
|
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
{% include 'partials/metadata.html.twig' %}
|
||||||
|
|
||||||
|
<link rel="icon" type="image/png" href="{{ url('theme://images/logo.png')|e }}" />
|
||||||
|
<link rel="canonical" href="{{ page.url(true, true)|e }}" />
|
||||||
|
{% endblock head %}
|
||||||
|
|
||||||
|
{% block stylesheets %}
|
||||||
|
{% do assets.addCss('theme://dist/css/app' ~ extension ~ '.css', 98) %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block javascripts %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block assets deferred %}
|
||||||
|
{{ assets.css()|raw }}
|
||||||
|
{{ assets.js()|raw }}
|
||||||
|
{% endblock %}
|
||||||
|
</head>
|
||||||
|
<body id="top" class="{{ page.header.body_classes|e }} {{ config.theme.production ?: 'debug-screens' }}">
|
||||||
|
|
||||||
|
{% block header %}
|
||||||
|
<div class="header">
|
||||||
|
<div class="">
|
||||||
|
<a class="logo" href="{{ home_url|e }}">
|
||||||
|
{{ config.site.title|e }}
|
||||||
|
</a>
|
||||||
|
{% block header_navigation %}
|
||||||
|
<nav class="main-nav">
|
||||||
|
{% include 'partials/navigation.html.twig' %}
|
||||||
|
</nav>
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<section id="body">
|
||||||
|
<div class="prose">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block footer %}
|
||||||
|
<div class="footer text-center">
|
||||||
|
<div class="">
|
||||||
|
<p><a href="http://getgrav.org">Grav</a>, by <a href="http://www.rockettheme.com">RocketTheme</a>.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block bottom %}
|
||||||
|
{{ assets.js('bottom')|raw }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,47 @@
|
|||||||
|
{% macro loop(page) %}
|
||||||
|
{% for p in page.children.visible %}
|
||||||
|
{% set current_page = (p.active or p.activeChild) ? 'selected' : '' %}
|
||||||
|
{% if p.children.visible.count > 0 %}
|
||||||
|
<li class="has-children {{ current_page|e }}">
|
||||||
|
<a href="{{ p.url|e }}">
|
||||||
|
{% if p.header.icon %}<i class="fa fa-{{ p.header.icon|e }}"></i>{% endif %}
|
||||||
|
{{ p.menu|e }}
|
||||||
|
</a>
|
||||||
|
<ul>
|
||||||
|
{{ _self.loop(p) }}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="{{ current_page|e }}">
|
||||||
|
<a href="{{ p.url|e }}">
|
||||||
|
{% if p.header.icon %}<i class="fa fa-{{ p.header.icon|e }}"></i>{% endif %}
|
||||||
|
{{ p.menu|e }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{% if config.theme.dropdown.enabled %}
|
||||||
|
{{ _self.loop(pages) }}
|
||||||
|
{% else %}
|
||||||
|
{% for page in pages.children.visible %}
|
||||||
|
{% set current_page = (page.active or page.activeChild) ? 'selected' : '' %}
|
||||||
|
<li class="{{ current_page|e }}">
|
||||||
|
<a href="{{ page.url|e }}">
|
||||||
|
{% if page.header.icon %}<i class="fa fa-{{ page.header.icon|e }}"></i>{% endif %}
|
||||||
|
{{ page.menu|e }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% for mitem in site.menu %}
|
||||||
|
<li>
|
||||||
|
<a href="{{ mitem.url|e }}">
|
||||||
|
{% if mitem.icon %}<i class="fa fa-{{ mitem.icon|e }}"></i>{% endif %}
|
||||||
|
{{ mitem.text|e }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
namespace Grav\Theme;
|
||||||
|
|
||||||
|
use Grav\Common\Theme;
|
||||||
|
|
||||||
|
class {{ component.name|camelize }} extends Theme
|
||||||
|
{
|
||||||
|
// Access plugin events in this class
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
enabled: true
|
||||||
|
production: false
|
||||||
|
dropdown:
|
||||||
|
enabled: true
|
BIN
plugins/devtools/components/theme/tailwind/thumbnail.jpg
Normal file
After Width: | Height: | Size: 3.6 KiB |
13
plugins/devtools/devtools.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Grav\Plugin;
|
||||||
|
|
||||||
|
use Grav\Common\Plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class DevToolsPlugin
|
||||||
|
* @package Grav\Plugin
|
||||||
|
*/
|
||||||
|
class DevToolsPlugin extends Plugin
|
||||||
|
{
|
||||||
|
}
|
2
plugins/devtools/devtools.yaml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
enabled: true
|
||||||
|
collision_check: true
|
3
plugins/devtools/languages.yaml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
en:
|
||||||
|
PLUGIN_DEVTOOLS:
|
||||||
|
COLLISION_CHECK: Online Name Collision Check
|