Hi!
I was wondering what is the correct workflow to add your own theme settings to a bootstrap derived sub theme? I was thinking something similar to below would work but it isn't.
<?php
/**
* @file
* theme-settings.php
*
* Theme settings file for Bootstrap.
*/
function wxt_bootstrap_form_system_theme_settings_alter(&$form, $form_state) {
$form['tweaks'] = array(
'#type' => 'fieldset',
'#title' => t('Tweaks'),
);
}
I notice that bootstrap is doing the following:
/**
* {@inheritdoc}
*
* @see \Drupal\bootstrap\Plugin\Form\SystemThemeSettings::alterForm()
*/
function bootstrap_form_system_theme_settings_alter(&$data, &$context1 = NULL, &$context2 = NULL) {
Bootstrap::alter(__FUNCTION__, $data, $context1, $context2);
}
If I want to add my own vertical tabs alongisde the "Bootstrap Settings" + "Override Global Settings" what is the best way? Thanks for any help!
Comments
Comment #2
sylus commentedApologies if missing something trivial. ^_^
Comment #3
sylus commentedBah nevermind it was working as expected ^_^.
Comment #4
markhalliwellActually, the easiest way is to just create a @BootstrapSetting plugin. That page is lacking some "official docs", but you can look at how this base theme implements all of its settings by the classes mentioned, for example: ButtonSize.
The reason this is the easiest is because the base theme will then handle the storage. You don't have to actually worry about any alters or form submits. Just specify the groups they setting should belong in and it will automatically render it in that tab/detail.
Comment #5
markhalliwellLet's go ahead and leave this open because that page eventually does need walk through example(s), like @BootstrapPreprocess currently has.
Comment #6
sylus commentedHere is a rough first attempt at documenting this. I also added how to create a custom group as was relevant in my particular case.
Comment #7
sylus commentedSure there is still a lot of corrections to be made but moving to needs review for now :)
Comment #8
markhalliwellGenerally speaking, I find that it's easiest to just name it the same as the base theme. In this case we'd likely want it to read:
class SystemThemeSettings extends \Drupal\bootstrap\Plugin\Form\SystemThemeSettings {---
Also, I'm a little confused. What is the "Custom grouping"? Do you mean to create a second vertical tabs? By default, it will create any tab/details (aka "group") for you in the existing "Bootstrap Settings" vertical tabs. If this is the case, then I would recommend putting this as the second section in the documentation and maybe rename as "Advanced: create custom vertical tabs", or something to that effect. I do not imagine that will be a common use case and would prefer to just have people create their own "THEMENAME" tab in the bootstrap settings for custom content as a typical rule of thumb.
Comment #9
sylus commentedThanks for the quick overview.
I can remove the custom grouping as your right it probably won't be a very common use case to add your own vertical tabs and might end up confusing the issue. Would you prefer I remove it or just to have it as the last section?
I can try to update this doc later tonight. ^_^
Comment #10
markhalliwellAwesome :D
Other than the basic documentation of how to create a plugin, there's also all the public methods that I'd like to document to show how to really customize a setting to your need, specifically:
SettingBase::alterForm
SettingBase::drupalSettings
SettingBase::getCacheTags
SettingBase::getElement
SettingBase::getGroup
SettingBase::getGroups
SettingBase::submitForm
SettingBase::validateForm
Good examples of these would probably be on:
http://drupal-bootstrap.org/api/bootstrap/src%21Plugin%21Setting%21Advan...
http://drupal-bootstrap.org/api/bootstrap/src%21Plugin%21Setting%21Compo...
http://drupal-bootstrap.org/api/bootstrap/src%21Plugin%21Setting%21JavaS...
http://drupal-bootstrap.org/api/bootstrap/src%21Plugin%21Setting%21JavaS...
Comment #11
sylus commentedI have updated the document a bit, removed the groups section and also discussed how to leverage the @BootstrapSetting all the way up to the twig layer.
Next I will update the customization section.
Just uploading current progress.
Comment #12
markhalliwellWe probably show that you can create a top level tab for your sub-theme's specific settings. I would just do
"THEMENAME" = "THEMETITLE"here.Actually, creating a preprocess is an unnecessary step. There is now a global "theme" variable added to every template in Bootstrap::preprocess().
So simply doing
{{ theme.settings.THEMENAME_skip_link }} in the template would work.Comment #13
markhalliwellAlso, if you could keep the verbiage based lines limited to 80 characters, that would be fantastic.
It just helps with readability and reviews.
Comment #14
markhalliwell@sylus, I really do appreciate you doing this! You're doing an amazing job! This helps me understand how others are interpreting the code and also gives me the ability to see how things need to be documented.
Comment #15
sylus commentedAh that is incredibly cool I love all of these developer improvements!
Will update that in the next revision. Thank you! ^_^
Comment #16
sylus commentedAh sorry about the line limit I should have caught that.
Updating just based on feedback and fixing the line limit so is readable in dreditor.
Happy to help was really appreciative of the Drupal core fix :)
Comment #17
markhalliwelltwighere, notphppage.html.twigtemplate to change the actual anchor ID as well for this to work properly:<a id="{{ theme.settings.THEMENAME_skip_link }}"></a>Comment #18
markhalliwellThe ID here should be
#customizeComment #19
sylus commentedDid the fixes mentioned and started to expand to the public methods. ^_^
Comment #21
markhalliwellThis is awesome work!! TY!
I went ahead and committed #19 and credited you.
Below is really just some of my raw/uncensored thoughts, mostly for myself. There's quite a bit of verbiage that needs to be iterated on, but I'll probably do that as a follow up commit. So I'm assigning to myself for now.
---
I'm actually thinking maybe this should be renamed to something like
## Public Methods {#methods}since that's what the section is really about.I was originally thinking maybe it should just be called "Advanced", but some settings will need these methods, even if they're not considered as "advanced".
I'm wondering if this section should come before all the public methods. It seems to have gotten lost towards the bottom and feels odd that you have all these public methods, that describe advanced configuration/use cases, when it's meant to be part of the initial creation (even for a simple setting plugin).
Not really sure we should add this to the individual plugin documentation as this pertains to all plugins and should probably be moved to the "Helpful tips" (that really should be named something else) on the parent topic "Plugin System".
Just a nit, but perhaps (since this is documentation), we should be following "Best Practices™" and name this
THEMENAME_skip_link_idsince this setting is actually just changing the ID being used, not anything else.Nit:
The arguments should be on the next line.
Also, should probably add
target="_blank"here so it opens a new window and doesn't take people away from any changes they may have made on this settings page.I know this is trivial, but this page will also be a way to document "Best Practices™" and should reflect that.
Should probably use backticks (`) around "theme" instead of quotes to give it the inline code look.
No need to add the parenthesis or backticks (inline code). The API module should automatically link any found
Class::methodthat has been parsed.Don't need extension for "SettingBase", it should automatically link via the API module.
Each of these public methods should be using h3s (###)... perhaps even h4s (####).
Allows altering of the
$formrender array as well as the$formStateobject.CDN should always be capitalized as it is an acronym.
Should also probably mention that this is related to JavaScript, even though that it's implied by
drupalSettings.Starting each section with "The `X` public method feels a little redundant when the header for each section has it. We can probably just simply each starting with "This method...".
It's actually
CdnProvider::getCacheTagsthat implements this method.Also, this doesn't really explain why it invalidates the
library_infocache. It invalidates it because the base theme loads external resources using libraries by altering the libraries it defines based on settings in LibraryInfo::alter.I like how this gives an example. I think each public method should give an example (a short one) like this.
This actually just retrieves the form element that was automatically generated by the base theme; based on the plugin definition.
It's more useful called inside the
alterFormmethod as such:This is actually a way to retrieve the last group (fieldset/details form element), as defined by the "groups" plugin definition, that this setting lives in.
This retrieves the associative array of groups as defined in the plugin definition. It's keyed by the group machine name and it's value is the translatable label.
Actually this method is a way to alter the submitted values stored in
$formStatebefore the setting's "value" is stored in configuration, automatically, for you by the base theme.It's also a way to do whatever else after a user has clicked the "Save configuration" button (i.e. show an additional message to the user based on a value or something).
Comment #22
markhalliwellUnless you feel like making another patch. I actually probably won't get to this until later this weekend/next week.
Comment #23
sylus commentedJust to ease your work a bit I made most of the corrections except for #15 (though added a few sections) and attaching a new patch based on latest dev.
Thanks a bunch!
Comment #24
sylus commentedJust read through it a couple more times and did some more grammar corrections.
Comment #26
markhalliwell