Issue #3031415 by markcarver: Overhaul CDN Providers API

parent 2b13823e
<?php
/**
* @file
* Drupal Bootstrap Drush commands.
*/
use Drupal\bootstrap\Bootstrap;
use Drupal\bootstrap\Theme;
use Drupal\Component\Serialization\Yaml;
/**
* Implements hook_drush_command().
*/
function bootstrap_drush_command() {
$items['bootstrap-generate-docs'] = [
'description' => dt('Generates markdown documentation for the Drupal based code.'),
'arguments' => [
'type' => 'The specific type of documentation to generate, defaults to "all". Can be: "all", "settings".',
],
'aliases' => ['bs-docs'],
];
return $items;
}
/**
* Generates markdown documentation.
*
* @param string $type
* The type of documentation.
*/
function drush_bootstrap_generate_docs($type = 'all') {
$types = $type === 'all' ? ['settings'] : [$type];
foreach ($types as $type) {
$function = "_drush_bootstrap_generate_docs_$type";
if (function_exists($function)) {
$ret = $function(Bootstrap::getTheme('bootstrap'));
if ($ret) {
drush_log('Successfully generated documentation for: ' . $type, 'success');
}
else {
drush_log('Unable to generate documentation for: ' . $type, 'error');
}
}
else {
drush_log('Invalid documentation type: ' . $type, 'error');
}
}
}
/**
* Generates settings documentation.
*
* @param \Drupal\bootstrap\Theme $bootstrap
* The theme instance of the Drupal Bootstrap base theme.
*/
function _drush_bootstrap_generate_docs_settings(Theme $bootstrap) {
$filename = realpath($bootstrap->getPath() . '/docs/Theme-Settings.md');
$marker_start = "<!-- THEME SETTINGS GENERATION START -->";
$marker_end = "<!-- THEME SETTINGS GENERATION END -->\n";
$contents = @file_get_contents($filename) ?: '';
$parts = @preg_split('/' . preg_quote($marker_start, '/') . '|' . preg_quote($marker_end, '/') . '/', $contents) ?: [];
$start = isset($parts[0]) ? [trim($parts[0])] : [];
$end = isset($parts[2]) ? [trim($parts[2])] : [];
// Determine the groups.
$groups = [
'general' => [],
'components' => [],
'javascript' => [],
'cdn' => [],
'advanced' => [],
];
foreach ($bootstrap->getSettingPlugin() as $setting) {
// Only get the first two groups (we don't need 3rd, or more, levels).
$_groups = array_slice(array_filter($setting->getGroups()), 0, 2, FALSE);
if (!$_groups) {
continue;
}
$groups[array_keys($_groups)[0]][implode(' > ', $_groups)][] = $setting->getPluginDefinition();
}
// Generate a table of each group's settings.
$lines = [$marker_start];
foreach ($groups as $subgroups) {
foreach ($subgroups as $group => $settings) {
$lines[] = '';
$lines[] = '---';
$lines[] = '';
$lines[] = "### $group";
$lines[] = '';
$lines[] = '<table class="table table-striped table-responsive">';
$lines[] = ' <thead>';
$lines[] = ' <tr>';
$lines[] = ' <th class="col-xs-3">Setting name</th>';
$lines[] = ' <th>Description and default value</th>';
$lines[] = ' </tr>';
$lines[] = ' </thead>';
$lines[] = ' <tbody>';
foreach ($settings as $definition) {
$lines[] = ' <tr>';
$lines[] = ' <td class="col-xs-3">';
$lines[] = $definition['id'];
$lines[] = ' </td>';
$lines[] = ' <td>';
if ($description = trim(str_replace('&quot;', '"', $definition['description']))) {
$lines[] = ' <div class="help-block">' . $description . '</div>';
}
if ($example = trim(Yaml::encode([$definition['id'] => $definition['defaultValue']]))) {
$lines[] = ' <pre class="language-yaml"><code>' . $example . '</code></pre>';
}
$lines[] = ' </td>';
$lines[] = ' </tr>';
}
$lines[] = ' </tbody>';
$lines[] = '</table>';
}
}
$lines[] = $marker_end;
// Ensure we have link references at the bottom.
$output = implode("\n", array_merge($start, $lines, $end)) . "\n";
// Save the generated output to the appropriate file.
return file_put_contents($filename, $output) !== FALSE;
}
......@@ -771,19 +771,14 @@ function bootstrap_element_smart_description(array &$element, array &$target = N
function bootstrap_get_cdn_assets($type = NULL, $provider = NULL, $theme = NULL) {
Bootstrap::deprecated();
$original_type = $type;
$assets = [];
$return = [];
$config = \Drupal::config('system.performance');
$cdnAssets = ProviderManager::load($theme, $provider)->getCdnAssets();
$assets = ProviderManager::load($theme, $provider)->getCdnAssets();
$types = !isset($type) ? ['css', 'js'] : (array) $type;
foreach ($types as $type) {
if ($config->get("$type.preprocess") && !empty($cdnAssets['min'][$type])) {
$assets[$type] = $cdnAssets['min'][$type];
}
elseif (!empty($data[$type])) {
$assets[$type] = $cdnAssets[$type];
}
$return[$type] = $assets->get($type, $config->get("$type.preprocess"));
}
return is_string($original_type) ? $assets[$original_type] : $assets;
return is_string($original_type) ? $return[$original_type] : $return;
}
/**
......
......@@ -28,15 +28,6 @@ After NodeJS has finished installing its own modules, it will automatically
invoke `grunt install` for you. This is a grunt task that is specifically
designed to keep the project in sync amongst maintainers.
## Drush
There are several commands available to run, please execute `drush` to view the
full list. This topic only covers the commands this project created.
### `drush bootstrap-generate-docs` or `drush bs-docs`
Generates markdown documentation for the Drupal based code. Possible arguments:
- **type:** The specific type of documentation to generate, defaults to `all`.
Possible values: `all|settings`
## Grunt
There are several tasks available to run, please execute `grunt --help` to view
the full list of tasks currently available. This topic only covers the most
......@@ -105,6 +96,15 @@ this limits the rapid development of the `overrides.less` file to the default
Bootstrap theme. If you have switched themes, you must manually compile all
the version and theme override files.
## Custom Scripts
This project also uses custom/standalone PHP scripts opposed to vendor specific
CLI programs (e.g. Drush or Drupal Console). This is primarily to ensure these
scripts can be executed regardless of which vendor specific CLI program or
version a maintainer may have installed.
### `./gen-theme-setting-docs.php`
Generates the markdown documentation for all available theme settings.
## Releases
This project attempts to provide more structured release notes. This allows the
project to communicate more effectively to the users what exactly has changed
......@@ -128,6 +128,11 @@ However, if it is long, it should really be a change record.
<p>&nbsp;</p>
<p>Changes since <!-- previous release --> (<!-- commit count -->):</p>
<h3 id="security">Security Announcements</h3>
<ul>
<li><!-- Issue/Commit Message --></li>
</ul>
<h3 id="features">New Features</h3>
<ul>
<li><!-- Issue/Commit Message --></li>
......
......@@ -82,34 +82,34 @@ $theme->setSetting('my_setting', 'a new value');
</tr>
</thead>
<tbody>
<tr>
<td class="col-xs-3">
button_colorize
</td>
<td>
<div class="help-block">Adds classes to buttons based on their text value.</div>
<pre class="language-yaml"><code>button_colorize: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
button_iconize
</td>
<td>
<div class="help-block">Adds icons to buttons based on the text value</div>
<pre class="language-yaml"><code>button_iconize: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
button_size
</td>
<td>
<div class="help-block">Defines the Bootstrap Buttons specific size</div>
<pre class="language-yaml"><code>button_size: ''</code></pre>
</td>
</tr>
</tbody>
<tr>
<td class="col-xs-3">
<span id="button-colorize" data-anchor="true">button_colorize</span>
</td>
<td>
<div class="help-block">Adds classes to buttons based on their text value.</div>
<pre class="language-yaml"><code>button_colorize: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="button-iconize" data-anchor="true">button_iconize</span>
</td>
<td>
<div class="help-block">Adds icons to buttons based on the text value</div>
<pre class="language-yaml"><code>button_iconize: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="button-size" data-anchor="true">button_size</span>
</td>
<td>
<div class="help-block">Defines the Bootstrap Buttons specific size</div>
<pre class="language-yaml"><code>button_size: ''</code></pre>
</td>
</tr>
</tbody>
</table>
---
......@@ -124,16 +124,16 @@ button_size
</tr>
</thead>
<tbody>
<tr>
<td class="col-xs-3">
fluid_container
</td>
<td>
<div class="help-block">Uses the <code>.container-fluid</code> class instead of <code>.container</code>.</div>
<pre class="language-yaml"><code>fluid_container: 0</code></pre>
</td>
</tr>
</tbody>
<tr>
<td class="col-xs-3">
<span id="fluid-container" data-anchor="true">fluid_container</span>
</td>
<td>
<div class="help-block">Uses the <code>.container-fluid</code> class instead of <code>.container</code>.</div>
<pre class="language-yaml"><code>fluid_container: 0</code></pre>
</td>
</tr>
</tbody>
</table>
---
......@@ -148,52 +148,52 @@ fluid_container
</tr>
</thead>
<tbody>
<tr>
<td class="col-xs-3">
forms_has_error_value_toggle
</td>
<td>
<div class="help-block">If an element has a <code>.has-error</code> class attached to it, enabling this will automatically remove that class when a value is entered.</div>
<pre class="language-yaml"><code>forms_has_error_value_toggle: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
forms_required_has_error
</td>
<td>
<div class="help-block">If an element in a form is required, enabling this will always display the element with a <code>.has-error</code> class. This turns the element red and helps in usability for determining which form elements are required to submit the form.</div>
<pre class="language-yaml"><code>forms_required_has_error: 0</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
forms_smart_descriptions
</td>
<td>
<div class="help-block">Convert descriptions into tooltips (must be enabled) automatically based on certain criteria. This helps reduce the, sometimes unnecessary, amount of noise on a page full of form elements.</div>
<pre class="language-yaml"><code>forms_smart_descriptions: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
forms_smart_descriptions_allowed_tags
</td>
<td>
<div class="help-block">Prevents descriptions from becoming tooltips by checking for HTML not in the list above (i.e. links). Separate by commas. To disable this filtering criteria, leave an empty value.</div>
<pre class="language-yaml"><code>forms_smart_descriptions_allowed_tags: 'b, code, em, i, kbd, span, strong'</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
forms_smart_descriptions_limit
</td>
<td>
<div class="help-block">Prevents descriptions from becoming tooltips by checking the character length of the description (HTML is not counted towards this limit). To disable this filtering criteria, leave an empty value.</div>
<pre class="language-yaml"><code>forms_smart_descriptions_limit: '250'</code></pre>
</td>
</tr>
</tbody>
<tr>
<td class="col-xs-3">
<span id="forms-has-error-value-toggle" data-anchor="true">forms_has_error_value_toggle</span>
</td>
<td>
<div class="help-block">If an element has a <code>.has-error</code> class attached to it, enabling this will automatically remove that class when a value is entered.</div>
<pre class="language-yaml"><code>forms_has_error_value_toggle: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="forms-required-has-error" data-anchor="true">forms_required_has_error</span>
</td>
<td>
<div class="help-block">If an element in a form is required, enabling this will always display the element with a <code>.has-error</code> class. This turns the element red and helps in usability for determining which form elements are required to submit the form.</div>
<pre class="language-yaml"><code>forms_required_has_error: 0</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="forms-smart-descriptions" data-anchor="true">forms_smart_descriptions</span>
</td>
<td>
<div class="help-block">Convert descriptions into tooltips (must be enabled) automatically based on certain criteria. This helps reduce the, sometimes unnecessary, amount of noise on a page full of form elements.</div>
<pre class="language-yaml"><code>forms_smart_descriptions: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="forms-smart-descriptions-allowed-tags" data-anchor="true">forms_smart_descriptions_allowed_tags</span>
</td>
<td>
<div class="help-block">Prevents descriptions from becoming tooltips by checking for HTML not in the list above (i.e. links). Separate by commas. To disable this filtering criteria, leave an empty value.</div>
<pre class="language-yaml"><code>forms_smart_descriptions_allowed_tags: 'b, code, em, i, kbd, span, strong'</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="forms-smart-descriptions-limit" data-anchor="true">forms_smart_descriptions_limit</span>
</td>
<td>
<div class="help-block">Prevents descriptions from becoming tooltips by checking the character length of the description (HTML is not counted towards this limit). To disable this filtering criteria, leave an empty value.</div>
<pre class="language-yaml"><code>forms_smart_descriptions_limit: '250'</code></pre>
</td>
</tr>
</tbody>
</table>
---
......@@ -208,25 +208,25 @@ forms_smart_descriptions_limit
</tr>
</thead>
<tbody>
<tr>
<td class="col-xs-3">
image_responsive
</td>
<td>
<div class="help-block">Images in Bootstrap 3 can be made responsive-friendly via the addition of the <code>.img-responsive</code> class. This applies <code>max-width: 100%;</code> and <code>height: auto;</code> to the image so that it scales nicely to the parent element.</div>
<pre class="language-yaml"><code>image_responsive: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
image_shape
</td>
<td>
<div class="help-block">Add classes to an <code>&lt;img&gt;</code> element to easily style images in any project.</div>
<pre class="language-yaml"><code>image_shape: ''</code></pre>
</td>
</tr>
</tbody>
<tr>
<td class="col-xs-3">
<span id="image-responsive" data-anchor="true">image_responsive</span>
</td>
<td>
<div class="help-block">Images in Bootstrap 3 can be made responsive-friendly via the addition of the <code>.img-responsive</code> class. This applies <code>max-width: 100%;</code> and <code>height: auto;</code> to the image so that it scales nicely to the parent element.</div>
<pre class="language-yaml"><code>image_responsive: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="image-shape" data-anchor="true">image_shape</span>
</td>
<td>
<div class="help-block">Add classes to an <code>&lt;img&gt;</code> element to easily style images in any project.</div>
<pre class="language-yaml"><code>image_shape: ''</code></pre>
</td>
</tr>
</tbody>
</table>
---
......@@ -241,52 +241,52 @@ image_shape
</tr>
</thead>
<tbody>
<tr>
<td class="col-xs-3">
table_bordered
</td>
<td>
<div class="help-block">Add borders on all sides of the table and cells.</div>
<pre class="language-yaml"><code>table_bordered: 0</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
table_condensed
</td>
<td>
<div class="help-block">Make tables more compact by cutting cell padding in half.</div>
<pre class="language-yaml"><code>table_condensed: 0</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
table_hover
</td>
<td>
<div class="help-block">Enable a hover state on table rows.</div>
<pre class="language-yaml"><code>table_hover: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
table_striped
</td>
<td>
<div class="help-block">Add zebra-striping to any table row within the <code>&lt;tbody&gt;</code>.</div>
<pre class="language-yaml"><code>table_striped: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
table_responsive
</td>
<td>
<div class="help-block">Wraps tables with <code>.table-responsive</code> to make them horizontally scroll when viewing them on devices under 768px. When viewing on devices larger than 768px, you will not see a difference in the presentational aspect of these tables. The <code>Automatic</code> option will only apply this setting for front-end facing tables, not the tables in administrative areas.</div>
<pre class="language-yaml"><code>table_responsive: -1</code></pre>
</td>
</tr>
</tbody>
<tr>
<td class="col-xs-3">
<span id="table-bordered" data-anchor="true">table_bordered</span>
</td>
<td>
<div class="help-block">Add borders on all sides of the table and cells.</div>
<pre class="language-yaml"><code>table_bordered: 0</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="table-condensed" data-anchor="true">table_condensed</span>
</td>
<td>
<div class="help-block">Make tables more compact by cutting cell padding in half.</div>
<pre class="language-yaml"><code>table_condensed: 0</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="table-hover" data-anchor="true">table_hover</span>
</td>
<td>
<div class="help-block">Enable a hover state on table rows.</div>
<pre class="language-yaml"><code>table_hover: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="table-striped" data-anchor="true">table_striped</span>
</td>
<td>
<div class="help-block">Add zebra-striping to any table row within the <code>&lt;tbody&gt;</code>.</div>
<pre class="language-yaml"><code>table_striped: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="table-responsive" data-anchor="true">table_responsive</span>
</td>
<td>
<div class="help-block">Wraps tables with <code>.table-responsive</code> to make them horizontally scroll when viewing them on devices under 768px. When viewing on devices larger than 768px, you will not see a difference in the presentational aspect of these tables. The <code>Automatic</code> option will only apply this setting for front-end facing tables, not the tables in administrative areas.</div>
<pre class="language-yaml"><code>table_responsive: -1</code></pre>
</td>
</tr>
</tbody>
</table>
---
......@@ -301,34 +301,34 @@ table_responsive
</tr>
</thead>
<tbody>
<tr>
<td class="col-xs-3">
breadcrumb
</td>
<td>
<div class="help-block">Show or hide the Breadcrumbs</div>
<pre class="language-yaml"><code>breadcrumb: '1'</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
breadcrumb_home
</td>
<td>
<div class="help-block">If your site has a module dedicated to handling breadcrumbs already, ensure this setting is enabled.</div>
<pre class="language-yaml"><code>breadcrumb_home: 0</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
breadcrumb_title
</td>
<td>
<div class="help-block">If your site has a module dedicated to handling breadcrumbs already, ensure this setting is disabled.</div>
<pre class="language-yaml"><code>breadcrumb_title: 1</code></pre>
</td>
</tr>
</tbody>
<tr>
<td class="col-xs-3">
<span id="breadcrumb" data-anchor="true">breadcrumb</span>
</td>
<td>
<div class="help-block">Show or hide the Breadcrumbs</div>
<pre class="language-yaml"><code>breadcrumb: '1'</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="breadcrumb-home" data-anchor="true">breadcrumb_home</span>
</td>
<td>
<div class="help-block">If your site has a module dedicated to handling breadcrumbs already, ensure this setting is enabled.</div>
<pre class="language-yaml"><code>breadcrumb_home: 0</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="breadcrumb-title" data-anchor="true">breadcrumb_title</span>
</td>
<td>
<div class="help-block">If your site has a module dedicated to handling breadcrumbs already, ensure this setting is disabled.</div>
<pre class="language-yaml"><code>breadcrumb_title: 1</code></pre>
</td>
</tr>
</tbody>
</table>
---
......@@ -343,25 +343,25 @@ breadcrumb_title
</tr>
</thead>
<tbody>
<tr>
<td class="col-xs-3">
navbar_inverse
</td>
<td>
<div class="help-block">Select if you want the inverse navbar style.</div>
<pre class="language-yaml"><code>navbar_inverse: 0</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
navbar_position
</td>
<td>
<div class="help-block">Determines where the navbar is positioned on the page.</div>
<pre class="language-yaml"><code>navbar_position: ''</code></pre>
</td>
</tr>
</tbody>
<tr>
<td class="col-xs-3">
<span id="navbar-inverse" data-anchor="true">navbar_inverse</span>
</td>
<td>
<div class="help-block">Select if you want the inverse navbar style.</div>
<pre class="language-yaml"><code>navbar_inverse: 0</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
<span id="navbar-position" data-anchor="true">navbar_position</span>
</td>
<td>
<div class="help-block">Determines where the navbar is positioned on the page.</div>
<pre class="language-yaml"><code>navbar_position: ''</code></pre>
</td>
</tr>
</tbody>
</table>
---
......@@ -376,13 +376,13 @@ navbar_position
</tr>
</thead>
<tbody>
<tr>
<td class="col-xs-3">
region_wells
</td>
<td>
<div class="help-block">Enable the <code>.well</code>, <code>.well-sm</code> or <code>.well-lg</code> classes for specified regions.</div>
<pre class="language-yaml"><code>region_wells:
<tr>
<td class="col-xs-3">
<span id="region-wells" data-anchor="true">region_wells</span>
</td>
<td>
<div class="help-block">Enable the <code>.well</code>, <code>.well-sm</code> or <code>.well-lg</code> classes for specified regions.</div>
<pre class="language-yaml"><code>region_wells:
navigation: ''
navigation_collapsible: ''
header: ''
......@@ -392,9 +392,9 @@ region_wells
sidebar_first: ''
sidebar_second: well
footer: ''</code></pre>
</td>
</tr>
</tbody>
</td>
</tr>
</tbody>
</table>
---
......@@ -409,87 +409,88 @@ region_wells
</tr>
</thead>
<tbody>
<tr>
<td class="col-xs-3">
modal_enabled
</td>
<td>
<pre class="language-yaml"><code>modal_enabled: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
modal_jquery_ui_bridge
</td>
<td>
<div class="help-block">Enabling this replaces the core/jquery.ui.dialog dependency in the core/drupal.dialog library with a jQuery UI Dialog widget bridge. This bridge adds support to Bootstrap Modals so that it may interpret jQuery UI Dialog functionality.</div>
<pre class="language-yaml"><code>modal_jquery_ui_bridge: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
modal_animation
</td>
<td>
<div class="help-block">Apply a CSS fade transition to modals.</div>
<pre class="language-yaml"><code>modal_animation: 1</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
modal_backdrop
</td>
<td>
<div class="help-block">Includes a modal-backdrop element. Alternatively, specify <code>static</code> for a backdrop which doesn't close the modal on click.</div>
<pre class="language-yaml"><code>modal_backdrop: 'true'</code></pre>
</td>
</tr>
<tr>
<td class="col-xs-3">
modal_focus_input
</td>
<td>
<div class="help-block">Enabling this focuses on the first available and visible input found in the modal after it's opened. If no element is found, the close button (if visible) is focused instead.</div>
<pre class="language-yaml"><code>modal_focus_input: 1</code></pre>
</td>