first commit

This commit is contained in:
2024-07-15 12:33:27 +02:00
commit ce50ae282b
22084 changed files with 2623791 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
<!-- @file Overview on how to contribute to the Drupal Bootstrap project. -->
<!-- @defgroup -->
# Contributing
Please read the [Getting Started](<!-- @url getting_started -->) topic and the
other various topics on this site first before creating an issue in this
project's issue queue.
Anything that falls within the scope of existing documentation or answered
questions will be marked as "Closed (works as designed)" or
"Closed (won't fix)".
The [Theme development](https://www.drupal.org/forum/3) support forum and
[Drupal StackExchange](https://drupal.stackexchange.com) are also amazing
resources for asking questions, learning new techniques and overall general
support.
## Drupal.org Handbook Pages
There has been some amazing Drupal Community work done around integration
between Drupal and the [Bootstrap Framework]. Additional community driven
documentation can be found on the [original Drupal.org handbook pages](https://www.drupal.org/node/1976938).
If you find that the documentation in these locations are inaccurate or
missing, please update it yourself (all logged in users have edit
capability).
## Creating New Issues
{.alert.alert-info} **Recommended reading:** [How To Solve All Your [Drupal] Problems](http://www.lullabot.com/blog/article/how-solve-all-your-problems)
{.alert.alert-warning} Please, [search the issue queue](https://www.drupal.org/project/issues/search/bootstrap)
first. **DO NOT** duplicate existing issues.
**If you find an existing issue and the issue status is:**
- Closed (fixed, duplicate, won't fix) - **DO NOT** re-open it. Open a new
issue (unless it's "Closed (won't fix)") and reference the existing issue in
the "Related Issues" field.
- Active, NR, NW, RTBC - Please update the issue accordingly, **DO NOT** create
a new issue.
**The [Drupal Bootstrap] issue queue IS for:**
- Fixing bugs and adding new features pertaining to the integration between
Drupal and the [Bootstrap Framework].
**The [Drupal Bootstrap] issue queue IS NOT for:**
- Bugs/feature requests pertaining to the [Bootstrap Framework] itself. Use
[their issue queue](https://github.com/twbs/bootstrap/issues) instead.
- Custom CSS/Layout (e.g. site specific)
- LESS/SASS - Compilation errors, syntax, mixins/functions
- JavaScript, jQuery, Bootstrap plugins or custom (site specific) plugins
- Modules that don't work in multiple themes. File the issue with that module.
It is likely they are not using [APIs](https://api.drupal.org) properly, not
following existing [Coding Standards](https://www.drupal.org/coding-standards)
or not developing with [Best Practices](https://www.drupal.org/best-practices) in
mind. It is actually a rare event when it is a legitimate issue with the
[Drupal Bootstrap] project.
## Slack
The [Drupal Bootstrap] project and its maintainers use the `#bootstrap` channel
in the `drupal.slack.com` workspace to communicate in real time. Please read
the following for more information on how to the community uses this technology:
[Chat with the Drupal community using Slack](https://www.drupal.org/slack).
Please keep in mind though, this **IS NOT** a "support" channel. It's primary
use is to discuss issues and to help fix bugs with the base theme itself.
[Drupal Bootstrap]: https://www.drupal.org/project/bootstrap
[Bootstrap Framework]: https://getbootstrap.com/docs/3.4/

View File

@@ -0,0 +1,127 @@
<!-- @file The "Getting Started" topic. -->
<!-- @defgroup -->
# Getting Started
## Installation
- Install the Bootstrap base theme in `themes` or a similar `sites/*/themes`
directory.
- Enable the [Drupal Bootstrap] base theme.
## Bootstrap Framework Fundamentals
Generally speaking, you should really read the entire [Bootstrap Framework]
documentation site, if you haven't already. Here are the four basic "sections"
that site is split into:
- [Getting Started](https://getbootstrap.com/docs/3.4/getting-started) - An overview of
the [Bootstrap Framework], how to download and use, basic templates and
examples, and more.
- [CSS](https://getbootstrap.com/docs/3.4/css/) - Global CSS settings, fundamental HTML
elements styled and enhanced with extensible classes, and an advanced grid
system.
- [Components](https://getbootstrap.com/docs/3.4/components/) - Over a dozen reusable
components built to provide iconography, dropdowns, input groups, navigation,
alerts, and much more.
- [JavaScript](https://getbootstrap.com/docs/3.4/javascript/) - Bring the
[Bootstrap Framework] components to life with over a dozen custom jQuery
plugins. Easily include them all, or one by one.
## FAQ - Frequently Asked Questions
- [Do you support X module?](#support)
- [Do you support Internet Explorer?](#ie)
- [Is Drupal Bootstrap a module or theme?](#module-or-theme)
- [Where can I discuss an issue in real time?](#discuss)
- [Where should I make changes?](#changes)
---
### Q: Do you support X module? {#support}
**A: Possibly**
Below are a list of modules the [Drupal Bootstrap] base theme actively supports.
This list is constantly growing and each module's support has usually been
implemented because of either extremely high usage or the fact it was designed
explicitly for use with this base theme and has maintainers in both projects.
**Supported modules:**
See project page for a list of supported modules.
**"Un-supported" modules:**
The following modules are "un-supported modules" and are not documented by the
[Drupal Bootstrap] base theme. This does not mean that the base theme will not
work with them or that they are "bad". It simply means that this project does
not have the time, energy or effort it would take to document "every possible
scenario".
It is certainly possible that some of these modules may eventually become
"officially" supported. That will happen only, of course, if there are enough
people to help contribute solid solutions and make supporting them by the base
theme maintainers a relatively "easy" task.
Some of these modules may have blogs or videos floating around on the internet.
However, if you choose to use one of these modules, you are really doing so
at your own expense. Do not expect support from this base theme or the project
you are attempting to integrate the base theme with.
- Color module (in core)
- [Bootstrap API](https://www.drupal.org/project/bootstrap_api)
- [Bootstrap Library](https://www.drupal.org/project/bootstrap_library)
- [LESS module](https://www.drupal.org/project/less)
---
### Q: Do you support Internet Explorer? {#ie}
**A: No, not "officially"**
The [Bootstrap Framework] itself does not officially support older Internet
Explorer [compatibility modes](https://getbootstrap.com/docs/3.4/getting-started/#support-ie-compatibility-modes).
To ensure you are using the latest rendering mode for IE, consider installing
the [HTML5 Tools](https://www.drupal.org/project/html5_tools) module.
Internet Explorer 8 requires the use of [Respond.js] to enable media queries
(Responsive Web Design). However, [Respond.js] does not work with CSS that is
referenced via a CSS `@import` statement, which is the default way Drupal
adds CSS files to a page when CSS aggregation is disabled. To ensure
[Respond.js] works properly, enable CSS aggregation at the bottom of:
`admin/config/development/performance`.
---
### Q: Is Drupal Bootstrap a module or theme? {#module-or-theme}
**A: Theme**
More specifically a base theme. It is _not_ a module. Modules are allowed to
participate in certain hooks, while themes cannot. This is a very important
concept to understand and limits themes from participating in a wider range of
functionality.
---
### Q: Where can I discuss an issue in real time? {#discuss}
**A: In Slack**
The [Drupal Bootstrap] project and its maintainers use the `#bootstrap` channel
in the `drupal.slack.com` workspace to communicate in real time. Please read
the following for more information on how to the community uses this technology:
[Chat with the Drupal community using Slack](https://www.drupal.org/slack).
Please keep in mind though, this **IS NOT** a "support" channel. It's primary
use is to discuss issues and to help fix bugs with the base theme itself.
---
### Q: Where should I make changes? {#changes}
**A: In a custom sub-theme**
You should **never** modify any theme or sub-theme that is packaged and released
from Drupal.org. If you do, all changes you have made would be lost once that
theme is updated. This makes keeping track of changes next to impossible.
Instead, you should create a custom sub-theme that isn't hosted on Drupal.org.
[Respond.js]: https://github.com/scottjehl/Respond
[Drush]: http://www.drush.org
[Drupal Bootstrap]: https://www.drupal.org/project/bootstrap
[Bootstrap Framework]: https://getbootstrap.com/docs/3.4/
[jQuery Update]: https://www.drupal.org/project/jquery_update

View File

@@ -0,0 +1,109 @@
<!-- @file Maintaining the Drupal Bootstrap project. -->
<!-- @defgroup -->
# Maintainers
Generally speaking, these topics will not be very helpful to you unless you are
a maintainer for this project. If you're simply curious about the process or
even want to help improve this aspect of the project, all suggestions will be
appreciated!
## Drupal Bootstrap Styles
The stylesheets bundled with this base theme (formerly known as "overrides")
have moved to a separate and dedicated project. Please file issues there:
https://github.com/unicorn-fail/drupal-bootstrap-styles
## 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
and where to go for additional information. This documentation is intended for
the project maintainers to help provide consistent results between releases.
### Release notes template
The following is just a template to show a typical structured format used as
release notes for this project:
```html
<h3 id="change-records">Change Records</h3>
<!-- Change records table HTML -->
Optionally, you can insert any additional verbiage here.
However, if it is long, it should really be a change record.
<p>&nbsp;</p>
<h3 id="notes">Notes</h3>
<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>
</ul>
<h3 id="bugs">Bug Fixes</h3>
<ul>
<li><!-- Issue/Commit Message --></li>
</ul>
```
### Create a Release Node
{.alert.alert-info} **NOTE:** This project currently relies on the
[Drush Git Release Notes](https://www.drupal.org/project/grn) tool to
automatically generate the the bulk of the release notes. This does, however,
requires maintainers to do the following extra steps. This entire process will
eventually be converted into a fully automated grunt task. Until then, please
download and install this tool and follow the remaining steps.
1. Create a [tag in git](https://www.drupal.org/node/1066342) that follows the
previous version and push it to the repository.
2. Create a [project release node](https://www.drupal.org/node/1068944) for this
newly created tag.
3. _(Skip this step if this is a new "alpha/beta" release)_ In a separate tab,
go to this project's [releases](https://www.drupal.org/node/259843/release)
page. Open and edit the previous release node. It should have followed the
release note template. If it has, copy and paste its contents into the new
release node body.
4. In a separate tab, go to the [change records](https://www.drupal.org/list-changes/bootstrap)
for this project and filter by the new official release version
("alpha/beta/RC" releases should always use the next "official" version for
their change records). If there are no change records, then remove this
section. Otherwise, copy and paste the entire table into the template
(replacing any existing one, if necessary).
5. Generate a list of issues/commits by executing the following from the root
of the project:
`drush release-notes <old> <new> --commit-count`
(e.g. `drush release-notes 7.x-3.0 7.x-3.1 --commit-count`)
If this is a follow-up "alpha/beta/RC" release, always use the last
"alpha/beta/RC" release version instead. This will allow for a quicker
parsing of the list to merge into the previously copied release notes:
`drush release-notes <old> <new> --commit-count`
(e.g. `drush release-notes 7.x-3.1-beta2 7.x-3.1-beta3 --commit-count`)
6. Copy the entire generated output into the template, just under where the
"Change Records" section would be, replacing only the commit count (do not
replace the "since last {offical} version").
7. Go though each item (`<li>`) that contains an issue link, ignoring duplicates
and standalone verbiage (direct commits). Move (cut and paste) these items
into the appropriate "New Features" or "Bug Fixes" sections.
8. Once complete the generated list should be empty (e.g. `<ul></ul>`), remove
it.
9. Save the release node.

View File

@@ -0,0 +1,76 @@
<!-- @file Documentation landing page and topics for the https://drupal-bootstrap.org site. -->
<!-- @mainpage -->
# Drupal Bootstrap Documentation
{.lead} The official documentation site for the [Drupal Bootstrap] base theme
The majority of this site is automatically generated from source files
located through out the project's repository. Topics are extracted from Markdown
files and the rest is extracted from embedded PHP comments.
---
## Topics
Below are some topics to help get you started using the [Drupal Bootstrap] base
theme. They are ordered based on the level one typically progresses while using
a base theme like this.
#### [Contributing](<!-- @url contributing -->)
#### [Getting Started](<!-- @url getting_started -->)
#### [Theme Settings](<!-- @url theme_settings -->)
#### [Sub-Theming](<!-- @url sub_theming -->)
#### [Templates](<!-- @url templates -->)
#### [Utilities](<!-- @url utility -->)
#### [Plugin System](<!-- @url plugins -->)
- [@BootstrapAlter](<!-- @url plugins_alter -->)
- [@BootstrapForm](<!-- @url plugins_form -->)
- [@BootstrapPreprocess](<!-- @url plugins_preprocess -->)
- [@BootstrapPrerender](<!-- @url plugins_prerender -->)
- [@BootstrapProcess](<!-- @url plugins_process -->)
- [@BootstrapProvider](<!-- @url plugins_provider -->)
- [@BootstrapSetting](<!-- @url plugins_setting -->)
- [@BootstrapUpdate](<!-- @url plugins_update -->)
#### [Project Maintainers](<!-- @url maintainers -->)
---
## Terminology
The term **"bootstrap"** can be used excessively through out this project's
documentation. For clarity, we will always attempt to use this word verbosely
in one of the following ways:
- **[Drupal Bootstrap]** refers to the Drupal base theme project.
- **[Bootstrap Framework](https://getbootstrap.com/docs/3.4/)** refers to the
external front end framework.
- **[drupal_bootstrap](https://api.drupal.org/apis/drupal_bootstrap)** refers
to Drupal's bootstrapping process or phase.
When referring to files inside the [Drupal Bootstrap] project directory, they
will always start with `./themes/bootstrap` and continue to specify the full
path to the file or directory inside it. The dot (`.`) is representative of
your Drupal installation's `DOCROOT` folder. For example, the file that is
responsible for displaying the text on this page is located at
`./themes/bootstrap/docs/README.md`.
When referring to files inside a sub-theme, they will always start with
`./themes/THEMENAME/`, where `THEMENAME` is the machine name of your sub-theme.
They will continue to specify the full path to the file or directory inside it.
For example, the primary file Drupal uses to determine if a theme exists is:
`./themes/THEMENAME/THEMENAME.info.yml`.
{.alert.alert-info} **NOTE:** It is common practice to place projects found on
Drupal.org inside a sub-folder named `contrib` and custom/site-specific code
inside a `custom` folder. If your site is set up this way, please adjust all
paths accordingly (i.e. `./themes/contrib/bootstrap` and
`./themes/custom/THEMENAME`).
[Drupal Bootstrap]: https://www.drupal.org/project/bootstrap

View File

@@ -0,0 +1,153 @@
<!-- @file Instructions on how to sub-theme the Drupal Bootstrap base theme. -->
<!-- @defgroup sub_theming -->
# Sub-Theming
If you haven't already installed the Drupal Bootstrap theme, read the
[Getting Started](<!-- @url getting_started -->) topic. Below are instructions
on how to create a [Drupal Bootstrap] based sub-theme. There are several
different variations on how to accomplish this task, but this topic will focus
on the two primarily and most common ways.
You should never modify any theme or sub-theme that is packaged and released
from Drupal.org, such as Drupal Bootstrap. If you do, all changes you have made
will be lost once that theme is updated. Instead, you should create a sub-theme
from one of the provided starterkits (this is considered a best practice). Once
you've done that, you can override CSS, templates, and theme processing.
- [Using the Starterkit](#starterkit)
- [Using Source Files](#source)
- [LESS](#less)
- [SASS](#sass)
- [Compile](#compile)
- [Override Settings](#settings)
- [Override Templates](#templates)
## Using the Starterkit {#starterkit}
The starterkit provided by this base-theme supplies the basic file structure on
how to construct a proper Bootstrap based sub-theme for use with a [CDN
Provider] (like [jsDelivr]) or for use with compiling [Bootstrap Framework]
source files.
{.alert.alert-info} **NOTE:** Using a [CDN Provider] is the preferred method
for loading the [Bootstrap Framework] CSS and JS on simpler sites that do not
use a site-wide CDN. There are advantages and disadvantages to using a
[CDN Provider] and you will need to weigh the benefits based on your site's own
requirements. Using a [CDN Provider] does mean that it depends on a third-party
service. There is no obligation or commitment made by this project or these
third-party services that guarantees up-time or quality of service. If you need
to customize Bootstrap, you must compile the [Bootstrap Framework] source code
locally and disable the
[`cdn_provider` theme setting](<!-- @url theme_settings#cdn_provider -->).
{.alert.alert-warning} **WARNING:** All locally compiled versions of Bootstrap
will be superseded by any enabled [CDN Provider]; **do not use both**.
1. Copy `./themes/bootstrap/starterkits/THEMENAME` to `./themes`.
* Rename the `THEMENAME` directory to a unique machine readable name. This is
your sub-theme's "machine name". When referring to files inside a sub-theme,
they will always start with `./themes/THEMENAME/`, where `THEMENAME` is the
machine name of your sub-theme. They will continue to specify the full path
to the file or directory inside it. For example, the primary file Drupal
uses to determine if a theme exists is:
`./themes/THEMENAME/THEMENAME.info.yml`.
2. Rename `./themes/THEMENAME/THEMENAME.starterkit.yml` to match
`./themes/THEMENAME/THEMENAME.info.yml`.
* Open this file and change the name, description and any other properties
to suite your needs. Make sure to rename the library extension name as
well: `THEMENAME/framework`.
3. Rename `./themes/THEMENAME/THEMENAME.libraries.yml`.
* (Optional) If you plan on using a local precompiler (i.e., [Less] or
[Sass]) then uncomment the appropriate JavaScript entries inside this file
to enable the assets provided by the [Bootstrap Framework].
4. Rename `./themes/THEMENAME/THEMENAME.theme`.
5. Rename `./themes/THEMENAME/config/schema/THEMENAME.schema.yml`
* Open this file and rename `- THEMENAME.settings:` and `'THEMETITLE
settings'`
6. Rename `./themes/THEMENAME/config/install/THEMENAME.settings.yml`
* (Optional) If you plan on using a local precompiler (i.e., [Less] or
[Sass]) then you will need to disable the `cdn_provider`
[`cdn_provider` theme setting](<!-- @url theme_settings#cdn_provider -->).
You can do this several different ways, but it's recommended that you
uncomment the following line in this file so the [CDN Provider] is
automatically disabled when your sub-theme is installed:
```yaml
# Disable the CDN provider so compiled source files can be used.
cdn_provider: ''
```
{.alert.alert-warning} **WARNING:** Ensure that the `.starterkit` suffix is
not present on your sub-theme's `.info.yml` filename. This suffix is simply a
stop gap measure to ensure that the bundled starter kit sub-theme cannot be
enabled or used directly. This helps people unfamiliar with Drupal avoid
modifying the starter kit sub-theme directly and instead forces them to create
a new sub-theme to modify.
## Using Source Files {#source}
By default, the starterkit is designed to be used with a [CDN Provider] for
quick setup.
While there are a multitude of different approaches on how to actually compile
the [Bootstrap Framework] source files, this base-theme does not and will not
provide templates or suggest specific tools to use. It is up to you, the
developer, to figure out which solution is best for your particular needs.
### LESS {#less}
- You must understand the basic concept of using the [Less] CSS pre-processor.
- You must use a **[local Less compiler](https://www.google.com/search?q=less+compiler)**.
- You must use the latest `3.x.x` version of [Bootstrap Framework LESS Source
Files] ending in the `.less` extension, not files ending in `.css`.
- You must download a copy of [Drupal Bootstrap Styles] and copy over the `less`
folder located at `./drupal-bootstrap-styles/src/3.x.x/8.x-3.x/less`.
### SASS {#sass}
- You must understand the basic concept of using the [Sass] CSS pre-processor.
- You must use a **[local Sass compiler](https://www.google.com/search?q=sass+compiler)**.
- You must use the latest `3.x.x` version of [Bootstrap Framework SASS Source
Files] ending in the `.scss` extension, not files ending in `.css`.
- You must download a copy of [Drupal Bootstrap Styles] and copy over the `scss`
folder located at `./drupal-bootstrap-styles/src/3.x.x/8.x-3.x/scss`.
### Compile {#compile}
Download and extract the source files into the root of your new sub-theme:
`./themes/THEMENAME`. After it has been extracted, the directory should be
renamed (if needed) so it reads `./themes/THEMENAME/bootstrap`.
If for whatever reason you have an additional `bootstrap` directory wrapping
the first `bootstrap` directory (e.g. `./themes/THEMENAME/bootstrap/bootstrap`),
remove the wrapping `bootstrap` directory. You will only ever need to touch
these files if or when you upgrade your version of the [Bootstrap Framework].
{.alert.alert-warning} **WARNING:** Do not modify the files inside of
`./themes/THEMENAME/bootstrap` directly. Doing so may cause issues when
upgrading the [Bootstrap Framework] in the future.
Depending on which precompiler you chose, you should have a `less/style.less`
or `scss/style.scss` file respectively. This file is the main compiling entry
point. Follow further instructions provided by the `README.md` inside the
`less` or `scss` folder.
## Override Settings {#settings}
Please refer to the [Theme Settings](<!-- @url theme_settings -->) topic.
## Override Templates {#templates}
Please refer to the [Templates](<!-- @url templates -->) and
[Plugin System](<!-- @url plugins -->) topics.
## Enable Your New Sub-theme {#enable}
In your Drupal site, navigate to `admin/appearance` and click the `Enable and
set default` link next to your newly created sub-theme. Now that you've
enabled your starterkit, please refer to the starterkit's documentation page
to customize.
[Drupal Bootstrap](https://www.drupal.org/project/bootstrap)
[Drupal Bootstrap Styles](https://github.com/unicorn-fail/drupal-bootstrap-styles)
[Bootstrap Framework](https://getbootstrap.com/docs/3.4/)
[Bootstrap Framework LESS Source Files](https://github.com/twbs/bootstrap/releases)
[Bootstrap Framework SASS Source Files](https://github.com/twbs/bootstrap-sass)
[jsDelivr](http://www.jsdelivr.com)
[Less](http://lesscss.org)
[Sass](http://sass-lang.com)
[CDN Provider](<!-- @url plugins_provider -->)

View File

@@ -0,0 +1,5 @@
<!-- @file List of theme templates used in the Drupal Bootstrap base theme. -->
<!-- @defgroup -->
# Templates
List of theme templates used in the Drupal Bootstrap base theme.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
<!-- @file List of utility helper classes used in base theme. -->
<!-- @defgroup -->
# Utilities
List of theme utility helper classes used in the Drupal Bootstrap base theme.

View File

@@ -0,0 +1,137 @@
<!-- @file Documentation for the @BootstrapAlter annotated plugin. -->
<!-- @defgroup -->
<!-- @ingroup -->
# @BootstrapAlter
- [Pre-requisite](#prerequisite)
- [Supported alter hooks](#supported)
- [Form alter hooks](#form)
- [Create a plugin](#create)
- [Rebuild the cache](#rebuild)
---
## Pre-requisite {#prerequisite}
Due to the nature of how Drupal alter hooks work, there is no "catch all" alter
hook (like for forms with hook_form_alter). That means for you to use this
plugin, it must be invoked from inside each and every alter hook that lives in
`THEMENAME.theme`.
Luckily you don't have to worry about invoking the plugin directly. Instead,
all you have to do is call the `Bootstrap::alter` helper method and pass the
alter function name and parameters as arguments:
```php
<?php
use Drupal\bootstrap\Bootstrap;
/**
* Implements hook_HOOK_alter().
*/
function hook_some_hook_alter(&$data, &$context1 = NULL, &$context2 = NULL) {
Bootstrap::alter(__FUNCTION__, $data, $context1, $context2);
}
?>
```
## Supported alter hooks {#supported}
This base theme implements several of the most commonly used alter hooks in
themes and are automatically supported out-of-the-box.
Once a base theme has implemented an alter hook, like mentioned above, all
subsequent sub-themes will have the ability to implement a plugin for that
alter hook directly. All you have to do is simply create the plugin file in
`./themes/THEMENAME/src/Plugin/Alter`. No need to implement any code in
`THEMENAME.theme`:
- `hook_bootstrap_colorize_text_alter`
- `hook_bootstrap_iconize_text_alter`
- `hook_element_info_alter`
- `hook_js_settings_alter`
- `hook_library_info_alter`
- `hook_page_attachments_alter`
- `hook_theme_registry_alter`
- `hook_theme_suggestions_alter`
{.alert.alert-info}**Note:** if you do not see an alter hook here that you think
_should_ be here, please
[create an issue](https://www.drupal.org/node/add/project-issue/bootstrap)
## Form alter hooks {#form}
You were probably thinking: "Hey, where's `hook_form_alter`? Didn't you _just_
mention that above?"
As we all know, forms can be a tad more involved than just a simple "alter" and
we figured that we'd give you a little more power behind what you can actually
do with them. So if you're interested in those, please go see:
@link plugins_form @BootstrapForm @endlink
While, yes technically, `hook_form_system_theme_settings_alter` could also fall
under the form plugin, we decided to take those a step further as well, see:
@link plugins_setting @BootstrapSetting @endlink
## Create a plugin {#create}
We'll use `PageAttachments` implemented by this base theme as an example of
how to add a library from your sub-theme to every page request.
Replace all following instances of `THEMENAME` with the actual machine name of
your sub-theme.
Create a file at `./themes/THEMENAME/src/Plugin/Alter/PageAttachments.php` with the
following contents:
```php
<?php
/**
* @file
* Contains \Drupal\THEMENAME\Plugin\Alter\PageAttachments.
*/
namespace Drupal\THEMENAME\Plugin\Alter;
use Drupal\bootstrap\Plugin\Alter\PageAttachments as BootstrapPageAttachements;
/**
* Implements hook_page_attachments_alter().
*
* @ingroup plugins_alter
*
* @BootstrapAlter("page_attachments")
*/
class PageAttachments extends BootstrapPageAttachements {
/**
* {@inheritdoc}
*/
public function alter(&$attachments, &$context1 = NULL, &$context2 = NULL) {
// Call the parent method from the base theme, if applicable (which it is
// in this case because Bootstrap actually implements this alter).
parent::alter($attachments, $context1, $context2);
// Add your custom library.
$attachments['#attached']['library'][] = 'THEMENAME/my_library';
}
}
?>
```
## Rebuild the cache {#rebuild}
Once you have saved, you must rebuild your cache for this new plugin to be
discovered. This must happen anytime you make a change to the actual file name
or the information inside the `@BootstrapAlter` annotation.
To rebuild your cache, navigate to `admin/config/development/performance` and
click the `Clear all caches` button. Or if you prefer, run `drush cr` from the
command line.
Voilà! After this, you should have a fully functional `@BootstrapAlter` plugin!

View File

@@ -0,0 +1,110 @@
<!-- @file Documentation for the @BootstrapForm annotated discovery plugin. -->
<!-- @defgroup -->
<!-- @ingroup -->
# @BootstrapForm
- [Create a plugin](#create)
- [Rebuild the cache](#rebuild)
---
## Create a plugin {#create}
We'll use `SearchBlockForm` implemented by this base theme as an example of
how to remove `#input_group_button` from `search_block_form`.
Replace all following instances of `THEMENAME` with the actual machine name of
your sub-theme.
Create a file at `./themes/THEMENAME/src/Plugin/Form/SearchBlockForm.php` with the
following contents:
```php
<?php
namespace Drupal\THEMENAME\Plugin\Form;
use Drupal\bootstrap\Plugin\Form\SearchBlockForm as BootstrapSearchBlockForm;
use Drupal\bootstrap\Utility\Element;
use Drupal\Core\Form\FormStateInterface;
/**
* Implements hook_form_FORM_ID_alter().
*
* @ingroup plugins_form
*
* @BootstrapForm("search_block_form")
*/
class SearchBlockForm extends BootstrapSearchBlockForm {
/**
* {@inheritdoc}
*/
public function alterForm(array &$form, FormStateInterface $form_state, $form_id = NULL) {
// Call the parent method from the base theme, if applicable (which it is
// in this case because Bootstrap actually implements this alter).
parent::alterForm($form, $form_state, $form_id);
// Disable #input_group_button the normal way:
$form['keys']['#input_group_button'] = FALSE;
}
/**
* {@inheritdoc}
*/
public function alterFormElement(Element $form, FormStateInterface $form_state, $form_id = NULL) {
// This method is the same as above, except the the $form argument passed is
// an instance of \Drupal\bootstrap\Utility\Element for easier manipulation.
// Using this method is preferable and considered "Best Practice".
//
// Disable #input_group_button using the $form Element object:
// $form->keys->setProperty('input_group_button', FALSE);.
}
/**
* {@inheritdoc}
*/
public static function submitForm(array &$form, FormStateInterface $form_state) {
// This method is automatically called when the form is submitted.
}
/**
* {@inheritdoc}
*/
public static function submitFormElement(Element $form, FormStateInterface $form_state) {
// This method is the same as above, except the the $form argument passed is
// an instance of \Drupal\bootstrap\Utility\Element for easier manipulation.
// Using this method is preferable and considered "Best Practice".
}
/**
* {@inheritdoc}
*/
public static function validateForm(array &$form, FormStateInterface $form_state) {
// This method is automatically called when the form is validated.
}
/**
* {@inheritdoc}
*/
public static function validateFormElement(Element $form, FormStateInterface $form_state) {
// This method is the same as above, except the the $form argument passed is
// an instance of \Drupal\bootstrap\Utility\Element for easier manipulation.
// Using this method is preferable and considered "Best Practice".
}
}
?>
```
## Rebuild the cache {#rebuild}
Once you have saved, you must rebuild your cache for this new plugin to be
discovered. This must happen anytime you make a change to the actual file name
or the information inside the `@BootstrapForm` annotation.
To rebuild your cache, navigate to `admin/config/development/performance` and
click the `Clear all caches` button. Or if you prefer, run `drush cr` from the
command line.
Voilà! After this, you should have a fully functional `@BootstrapForm` plugin!

View File

@@ -0,0 +1,118 @@
<!-- @file Documentation for the @BootstrapPreprocess annotated plugin. -->
<!-- @defgroup -->
<!-- @ingroup -->
# @BootstrapPreprocess
- [Create a plugin](#create)
- [Rebuild the cache](#rebuild)
---
## Create a plugin {#create}
We'll use `Page` implemented by this base theme as an example of how to add
custom classes for the `page.html.twig` template that should only be added
under certain conditions.
Replace all following instances of `THEMENAME` with the actual machine name of
your sub-theme.
Create a file at `./themes/THEMENAME/src/Plugin/Preprocess/Page.php` with the
following contents:
```php
<?php
namespace Drupal\THEMENAME\Plugin\Preprocess;
use Drupal\bootstrap\Plugin\Preprocess\Page as BootstrapPage;
use Drupal\bootstrap\Utility\Element;
use Drupal\bootstrap\Utility\Variables;
/**
* Pre-processes variables for the "page" theme hook.
*
* @ingroup plugins_preprocess
*
* @BootstrapPreprocess("page")
*/
class Page extends BootstrapPage {
/*
* It should be noted that you do not need all three methods here.
* This is to just show you the different examples of how this plugin
* works and how they can be tailored to your needs.
*/
/**
* {@inheritdoc}
*/
public function preprocess(array &$variables, $hook, array $info) {
$value = isset($variables['element']['child']['#value']) ? $variables['element']['child']['#value'] : FALSE;
if (_some_module_condition($value)) {
$variables['attributes']['class'][] = 'my-theme-class';
$variables['attributes']['class'][] = 'another-theme-class';
$key = array_search('page', $variables['attributes']['class']);
if ($key !== FALSE) {
unset($variables['attributes']['class'][$key]);
}
}
// If you are extending and overriding a preprocess method from the base
// theme, it is imperative that you also call the parent (base theme) method
// at some point in the process, typically after you have finished with your
// preprocessing.
parent::preprocess($variables, $hook, $info);
}
/**
* {@inheritdoc}
*/
public function preprocessVariables(Variables $variables) {
// This method is almost identical to the one above, but it introduces the
// Variables utility class in the base theme. This class has a plethora of
// helpful methods to quickly modify common tasks when you're in a
// preprocess function. It also acts like the normal $variables array when
// you need it to in instances of accessing nested content or in loop
// structures like foreach.
$value = isset($variables['element']['child']['#value']) ? $variables['element']['child']['#value'] : FALSE;
if (_some_module_condition($value)) {
$variables->addClass(['my-theme-class', 'another-theme-class'])->removeClass('page');
}
parent::preprocessVariables($variables);
}
/**
* {@inheritdoc}
*/
protected function preprocessElement(Element $element, Variables $variables) {
// This method is only ever invoked if either $variables['element'] or
// $variables['elements'] exists. These keys are usually only found in forms
// or render arrays when there is a #type being used. This introduces the
// Element utility class in the base theme. It too has a bucket-load of
// features, specific to the unique characteristics of render arrays with
// their "properties" (keys starting with #). This will quickly allow you to
// access some of the nested element data and reduce the overhead required
// for commonly used logic.
$value = $element->child->getProperty('value', FALSE);
if (_some_module_condition($value)) {
$variables->addClass(['my-theme-class', 'another-theme-class'])->removeClass('page');
}
parent::preprocessElement($element, $variables);
}
}
?>
```
## Rebuild the cache {#rebuild}
Once you have saved, you must rebuild your cache for this new plugin to be
discovered. This must happen anytime you make a change to the actual file name
or the information inside the `@BootstrapPreprocess` annotation.
To rebuild your cache, navigate to `admin/config/development/performance` and
click the `Clear all caches` button. Or if you prefer, run `drush cr` from the
command line.
Voilà! After this, you should have a fully functional `@BootstrapPreprocess`
plugin!

View File

@@ -0,0 +1,119 @@
<!-- @file Documentation for the @BootstrapPrerender annotated plugin. -->
<!-- @defgroup -->
<!-- @ingroup -->
# @BootstrapPrerender
- [Create a plugin](#create)
- [Rebuild the cache](#rebuild)
---
## Create a plugin {#create}
We'll use `Link` implemented by this base theme as an example of how to add
custom classes and an icon to make the link look like a Bootstrap button. This
example will only work if the link is passed some sort of `#context` when the
render array is built, like the following:
```php
<?php
$build['my_button'] = [
'#type' => 'link',
'#title' => t('Download'),
'#url' => Url::fromUserInput('/download', [
'query' => ['item' => '1234'],
]),
'#context' => [
'downloadButton' => TRUE,
],
];
?>
```
Replace all following instances of `THEMENAME` with the actual machine name of
your sub-theme.
Create a file at `./themes/THEMENAME/src/Plugin/Prerender/Link.php` with the
following contents:
```php
<?php
namespace Drupal\THEMENAME\Plugin\Prerender;
use Drupal\bootstrap\Plugin\Prerender\Link as BootstrapLink;
use Drupal\bootstrap\Bootstrap;
use Drupal\bootstrap\Utility\Element;
/**
* Pre-render callback for the "link" element type.
*
* @ingroup plugins_prerender
*
* @BootstrapPrerender("link",
* action = @BootstrapConstant(
* "\Drupal\bootstrap\Bootstrap::CALLBACK_PREPEND"
* )
* )
*
* @see \Drupal\Core\Render\Element\Link::preRenderLink()
*/
class Link extends BootstrapLink {
/*
* It should be noted that you do not need both methods here.
* This is to just show you the different examples of how this plugin
* works and how it can be tailored to your needs.
*/
/**
* {@inheritdoc}
*/
public static function preRender(array $element) {
$context = isset($element['#context']) ? $element['#context'] : [];
// Make downloadButton links into buttons.
if (!empty($context['downloadButton'])) {
$element['#icon'] = Bootstrap::glyphicon('download-alt');
$element['#attributes']['class'][] = 'btn';
$element['#attributes']['class'][] = 'btn-primary';
$element['#attributes']['class'][] = 'btn-lg';
}
// You must always return the element in this method, as well as call the
// parent method when sub-classing this method as it is used to invoke
// static::preRenderElement().
return parent::preRender($element);
}
/**
* {@inheritdoc}
*/
public static function preRenderElement(Element $element) {
// Make downloadButton links into buttons.
// Same as above, just a little cleaner with the Element utility class.
if ($element->getContext('downloadButton')) {
$element->addClass(['btn', 'btn-primary', 'btn-lg'])->setIcon(Bootstrap::glyphicon('download-alt'));
}
// You don't always have to call the parent method when sub-classing, but
// it is generally recommended that you do (otherwise the icon that was
// just added wouldn't work).
parent::preRenderElement($element);
}
}
?>
```
## Rebuild the cache {#rebuild}
Once you have saved, you must rebuild your cache for this new plugin to be
discovered. This must happen anytime you make a change to the actual file name
or the information inside the `@BootstrapPrerender` annotation.
To rebuild your cache, navigate to `admin/config/development/performance` and
click the `Clear all caches` button. Or if you prefer, run `drush cr` from the
command line.
Voilà! After this, you should have a fully functional `@BootstrapPrerender`
plugin!

View File

@@ -0,0 +1,99 @@
<!-- @file Documentation for the @BootstrapProcess annotated plugin. -->
<!-- @defgroup -->
<!-- @ingroup -->
# @BootstrapProcess
- [Create a plugin](#create)
- [Rebuild the cache](#rebuild)
---
## Create a plugin {#create}
{.alert.alert-warning}**Note:** This plugin is _not_ a re-implementation of the
D7 `hook_process_HOOK` for theme hooks in anyway. That layer was removed from
the theme system in D8 and for good reason (see:
[Remove the process layer](https://www.drupal.org/node/1843650)). This plugin
is about automatically adding a `#process` callback for a form element `#type`.
This is especially useful when dealing with core elements that have implemented
their own callbacks; either to alter their output or remove entirely.
We'll use `TextFormat` implemented by this base theme as an example of how to
override the class entirely and remove this base theme's over-simplification
for the "format tips" section.
Replace all following instances of `THEMENAME` with the actual machine name of
your sub-theme.
Create a file at `./themes/THEMENAME/src/Plugin/Process/TextFormat.php` with the
following contents:
```php
<?php
namespace Drupal\THEMENAME\Plugin\Process;
use Drupal\bootstrap\Plugin\Process\TextFormat as BootstrapTextFormat;
use Drupal\bootstrap\Utility\Element;
use Drupal\Core\Form\FormStateInterface;
/**
* Processes the "text_format" element.
*
* @ingroup plugins_process
*
* @BootstrapProcess("text_format")
*
* @see \Drupal\filter\Element\TextFormat::processFormat()
*/
class TextFormat extends BootstrapTextFormat {
/*
* It should be noted that you do not need both methods here.
* This is to just show you the different examples of how this plugin
* works and how it can be tailored to your needs.
*/
/**
* {@inheritdoc}
*/
public static function process(array $element, FormStateInterface $form_state, array &$complete_form) {
// You must return the element immediately if this is TRUE.
if (!empty($element['#bootstrap_ignore_process'])) {
return $element;
}
// Technically this isn't the method that we need to achieve our goal.
// But showing it just for example sake.
//
// You must always return the element in this method, as well as call the
// parent method when sub-classing this method as it is used to invoke
// static::processElement();
return parent::process($element, $form_state, $complete_form);
}
/**
* {@inheritdoc}
*/
public static function processElement(Element $element, FormStateInterface $form_state, array &$complete_form) {
// Normally, we'd call the parent method here. But this is actually an
// instance where we know we don't want to use the alterations made by
// the base theme. So we just comment it out and leave the method empty.
// parent::processElement($element, $form_state, $complete_form);.
}
}
?>
```
## Rebuild the cache {#rebuild}
Once you have saved, you must rebuild your cache for this new plugin to be
discovered. This must happen anytime you make a change to the actual file name
or the information inside the `@BootstrapProcess` annotation.
To rebuild your cache, navigate to `admin/config/development/performance` and
click the `Clear all caches` button. Or if you prefer, run `drush cr` from the
command line.
Voilà! After this, you should have a fully functional `@BootstrapProcess`
plugin!

View File

@@ -0,0 +1,90 @@
<!-- @file Documentation for the @BootstrapProvider annotated plugin. -->
<!-- @defgroup -->
<!-- @ingroup -->
# @BootstrapProvider
- [Create a plugin](#create)
- [Rebuild the cache](#rebuild)
---
## Create a plugin {#create}
We'll use the `\Drupal\bootstrap\Plugin\Provider\JsDelivr` CDN Provider as an
example of how to create a quick custom CDN provider using its API URLs.
Replace all following instances of `THEMENAME` with the actual machine name of
your sub-theme.
You may also feel free to replace the provided URLs with your own. Most of the
popular CDN API output can be easily parsed, however you may need to provide
addition parsing in your custom CDN Provider if you're not getting the desired
results.
If you're truly interested in implementing a CDN Provider, it is highly
recommended that you read the accompanying PHP based documentation on the
classes and methods responsible for actually retrieving, parsing and caching
the data from the CDN's API.
Create a file at `./themes/THEMENAME/src/Plugin/Provider/MyCdn.php` with the
following contents:
```php
<?php
namespace Drupal\THEMENAME\Plugin\Provider;
use Drupal\bootstrap\Plugin\Provider\ApiProviderBase;
/**
* The "mycdn" CDN Provider plugin.
*
* @ingroup plugins_provider
*
* @BootstrapProvider(
* id = "mycdn",
* label = @Translation("My CDN"),
* description = @Translation("My CDN (jsDelivr)"),
* weight = -1
* )
*/
class JsDelivr extends ApiProviderBase {
/**
* {@inheritdoc}
*/
protected function getApiAssetsUrlTemplate() {
return 'https://data.jsdelivr.com/v1/package/npm/@library@@version/flat';
}
/**
* {@inheritdoc}
*/
protected function getApiVersionsUrlTemplate() {
return 'https://data.jsdelivr.com/v1/package/npm/@library';
}
/**
* {@inheritdoc}
*/
protected function getCdnUrlTemplate() {
return 'https://cdn.jsdelivr.net/npm/@library@@version/@file';
}
}
?>
```
## Rebuild the cache {#rebuild}
Once you have saved, you must rebuild your cache for this new plugin to be
discovered. This must happen anytime you make a change to the actual file name
or the information inside the `@BootstrapProvider` annotation.
To rebuild your cache, navigate to `admin/config/development/performance` and
click the `Clear all caches` button. Or if you prefer, run `drush cr` from the
command line.
Voilà! After this, you should have a fully functional `@BootstrapProvider`
plugin!

View File

@@ -0,0 +1,70 @@
<!-- @file Documents the Plugin System for the Drupal Bootstrap base theme. -->
<!-- @defgroup -->
<!-- @ingroup -->
# Plugin System
- [Overview](#overview)
- [Helpful Tips](#helpful-tips)
---
## Overview {#overview}
The [Drupal Bootstrap] base theme handles some very complex theme registry
alterations and annotated plugin discoveries to assist with the organization
and maintenance of its source code.
By leveraging OOP (object oriented programming) with PHP namespacing and
Drupal's autoloading, we garner the ability to include files only when a
theme hook is actually invoked. This allows the base theme to reduce its per
page PHP memory footprint as much as possible. It also allows for easier
maintenance and organization with as much customization this base theme
implements.
The data and display logic of the [Drupal Bootstrap] base theme has been
divided into what we call the "Plugin System". It's nearly identical to the
other plugin system(s) found through out Drupal, with the exception that these
plugins are not bound to the container in any way.
This is, in part, due to the fact that themes are not allowed to participate in
container construction since a theme could vary from page to page (in theory).
So, instead, this base theme implements its own annotated discovery plugins
to leverage the powerful inheritance capabilities of PHP class instances.
All of these plugins can be found in the following directories and are
discussed, in length, below in their respective sub-topics:
- `./themes/bootstrap/src/Plugin/Alter`
- `./themes/bootstrap/src/Plugin/Form`
- `./themes/bootstrap/src/Plugin/Preprocess`
- `./themes/bootstrap/src/Plugin/Prerender`
- `./themes/bootstrap/src/Plugin/Process`
- `./themes/bootstrap/src/Plugin/Provider`
- `./themes/bootstrap/src/Plugin/Setting`
- `./themes/bootstrap/src/Plugin/Update`
While sub-themes are not required to do so, they can easily emulate this same
type of file structure/workflow and take advantage of this base theme's unique
ability and power. All you have to do is make sure you extend from this base
theme's implementation, if it exists.
Rest assured though, there is no need to structure your sub-theme this way. If
you feel more comfortable storing everything in your sub-theme's
`THEMENAME.theme` file and invoking the "normal" Drupal hooks, please feel free
to do so. It will not impact your sub-theme one way or the other.
It is, however, highly recommended that you at least read through this a bit to
gain some understanding on how this base theme structures its PHP and template
components. This will allow you to more easily copy stuff over to your
sub-theme, should the need arise.
## Helpful tips {#helpful-tips}
All plugins, except those that only have static methods, have the active Theme
object available to them: e.g. `$this->theme`. This will allow you to do things
like get a theme setting very, very easily: e.g.
`$this->theme->getSetting('button_size')`.
A helpful primer on Annotation-based plugins can be found at:
https://www.drupal.org/node/1882526
[Drupal Bootstrap]: https://www.drupal.org/project/bootstrap

View File

@@ -0,0 +1,162 @@
<!-- @file Documentation for the @BootstrapSetting annotated plugin. -->
<!-- @defgroup -->
<!-- @ingroup -->
# @BootstrapSetting
- [Create a plugin](#create)
- [Rebuild the cache](#rebuild)
- [Public Methods](#methods)
## Create a plugin {#create}
We will use `SkipLink` as our first `@BootstrapSetting` plugin to create. In
this example we want our sub-theme to specify a different skip link anchor id
to change in the Theme Settings interface altering the default of
`#main-content`.
Replace all of the following instances of `THEMENAME` with the actual machine
name of your sub-theme.
Create a file at
`./themes/THEMENAME/src/Plugin/Setting/THEMENAME/Accessibility/SkipLink.php`
with the following contents:
```php
<?php
namespace Drupal\THEMENAME\Plugin\Setting\THEMENAME\Accessibility;
use Drupal\bootstrap\Plugin\Setting\SettingBase;
/**
* The "THEMENAME_skip_link_id" theme setting.
*
* @ingroup plugins_setting
*
* @BootstrapSetting(
* id = "THEMENAME_skip_link_id",
* type = "textfield",
* title = @Translation("Anchor ID for the ""skip link"""),
* defaultValue = "main-content",
* description = @Translation("Specify the HTML ID of the element that the accessible-but-hidden ""skip link"" should link to. (<a href="":link"" target=""_blank"">Read more about skip links</a>.)",
* arguments = { ":link" = "https://www.drupal.org/node/467976" }),
* groups = {
* "THEMENAME" = "THEMETITLE",
* "accessibility" = @Translation("Accessibility"),
* },
* )
*/
class SkipLink extends SettingBase {}
?>
```
Helpfully Bootstrap adds a global `theme` variable added to every template
in `Bootstrap::preprocess()`.
This variable can now simply be called in the `html.html.twig` file with the
following contents:
```twig
<a href="#{{ theme.settings.THEMENAME_skip_link_id }}"
class="visually-hidden focusable skip-link">
{{ 'Skip to main content'|t }}
</a>
```
In addition, the `page.html.twig` file will also need to be adjusted for this to
work properly with the new anchor id.
```twig
<a id="{{ theme.settings.THEMENAME_skip_link_id }}"></a>
```
## Rebuild the cache {#rebuild}
Once you have saved, you must rebuild your cache for this new plugin to be
discovered. This must happen anytime you make a change to the actual file name
or the information inside the `@BootstrapSetting` annotation.
To rebuild your cache, navigate to `admin/config/development/performance` and
click the `Clear all caches` button. Or if you prefer, run `drush cr` from the
command line.
Voilà! After this, you should have a fully functional `@BootstrapSetting`
plugin!
## Public Methods {#methods}
Now that we covered how to create a basic `@BootstrapSetting` plugin, we can
discuss how to customize a setting to fulfill a range of requirements.
The `@BootstrapSetting` is implemented through the base class `SettingBase`
which provides a variety of public methods to assist in the customization of
a plugin.
#### SettingBase::alterForm(array &$form, FormStateInterface $form_state, $form_id = NULL)
#### SettingBase::alterFormElement(Element $form, FormStateInterface $form_state, $form_id = NULL)
Both of these methods provide a way for you to alter the setting's form render
array element as well as the form state object.
The first method is similar to any standard `hook_form_alter`.
However, the second method passes the `$form` argument as an instance of the
`Element` utility helper class. This will allow easier manipulation of all the
elements in this method. Using this method is preferable and considered
"Best Practice".
Two useful examples to study:
- CDNProvider::alterFormElement
- RegionWells::alterFormElement
#### SettingBase::drupalSettings()
This method provides a way for you to determine whether a theme setting should
be added to the `drupalSettings` JavaScript variable. Please note that by
default this is set to `FALSE` to prevent any potentially sensitive information
from being leaked.
#### SettingBase::getCacheTags()
This method provides a way for you to add cache tags that when the instantiated
class is modified the associated cache tags will be invalidated. This is
incredibly useful for example with CDNCustomCss::getCacheTags() which returns an
array of `library_info`. So when a CdnProvider::getCacheTags() instantiated
plugin changes the `library_info` cache tag will be invalidated automatically.
It is important to note that the invalidation occurs because the base theme
loads external resources using libraries by altering the libraries it defines
based on settings in LibraryInfo::alter().
#### SettingBase::getGroupElement(Element $form, FormStateInterface $form_state)
This method provides a way for you to retrieve the last group (fieldset /
details form element) the setting is nested in; based on the plugin definition.
#### SettingBase::getGroups()
This method retrieves the associative array of groups; based on the plugin
definition. It's keyed by the group machine name and its value is the
translatable label.
#### SettingBase::getSettingElement(Element $form, FormStateInterface $form_state)
This method provides a way for you to retrieve the form element that was
automatically generated by the base theme for the setting; based on the plugin
definition.
#### SettingBase::submitForm(array &$form, FormStateInterface $form_state)
#### SettingBase::submitFormElement(Element $form, FormStateInterface $form_state)
Both of these methods provide a way for you to alter the submitted values
stored in the form state object before the setting's value is ultimately stored
in configuration by the base theme, which is performed automatically for you.
Two useful example to study:
- RegionWells::submitFormElement
#### SettingBase::validateForm(array &$form, FormStateInterface $form_state)
#### SettingBase::validateFormElement(Element $form, FormStateInterface $form_state)
Both of these methods provide a way for you to validate the setting's form.

View File

@@ -0,0 +1,9 @@
<!-- @file Documentation for the @BootstrapUpdate annotated plugin. -->
<!-- @defgroup -->
<!-- @ingroup -->
# @BootstrapUpdate
This plugin is a little too complex to explain (for now). If you would like to
help expand this documentation, please [create an issue](https://www.drupal.org/node/add/project-issue/bootstrap).
See the existing classes below on examples of how to implement your own.

View File

@@ -0,0 +1,59 @@
<!-- THEME SETTINGS GENERATION START -->
{% for heading, settings in groups %}
---
### {{ heading|raw }}
<table class="table table-striped table-responsive">
<thead>
<tr>
<th class="col-xs-3">{{ 'Setting name'|t }}</th>
<th>{{ 'Description and default value'|t }}</th>
</tr>
</thead>
<tbody>
{% for id, setting in settings %}<tr>
<td class="col-xs-3">
<span id="{{- id|clean_class -}}" data-anchor="true">{{- id -}}</span>
</td>
<td>
<div class="help-block">{{- setting.description -}}</div>
<pre class="language-yaml"><code>{{- setting.defaultValue -}}</code></pre>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endfor %}
{% if deprecated %}
---
### {{ 'Deprecated'|t }}
<table class="table table-responsive">
<thead>
<tr>
<th class="col-xs-3">{{ 'Setting name'|t }}</th>
<th>{{ 'Description and default value'|t }}</th>
</tr>
</thead>
<tbody>
{% for id, setting in deprecated %}<tr class="bg-warning">
<td class="col-xs-3">
<span id="{{- id -}}" data-anchor="true">{{- id -}}</span>
</td>
<td>
<div class="help-block">{{- setting.description -}}</div>
<pre class="language-yaml"><code>{{- setting.defaultValue -}}</code></pre>
<div class="alert alert-danger alert-sm">
<strong>{{ 'Deprecated since @version'|t({'@version': setting.deprecated.version }) }}</strong> - {{ setting.deprecated.reason }} ({{ 'see: @replacement'|t({'@replacement': setting.deprecated.replacement}) }})
</div>
</td>
</tr>
{% endfor -%}
</tbody>
</table>
{% endif %}
<!-- THEME SETTINGS GENERATION END -->