0

background

I run drush cget markdown.settings and see:

dependencies:
  module:
    - markdown
parser:
  id: michelf/php-markdown-extra
  render_strategy:
    type: none
  settings:
    code_attr_on_pre: false
    code_class_prefix: ''
    empty_element_suffix: ' />'
    enhanced_ordered_list: true
    fn_backlink_class: footnote-backref
    fn_backlink_html: '↩︎'
    fn_backlink_label: ''
    fn_backlink_title: ''
    fn_id_prefix: ''
    fn_link_class: footnote-ref
    fn_link_title: ''
    hard_wrap: false
    hashtag_protection: false
    no_entities: false
    no_markup: false
    omit_footnotes: false
    predef_abbr: {  }
    predef_titles: {  }
    predef_urls: {  }
    tab_width: 4
    table_align_class_tmpl: ''

I visit https://drupal8.example.org/admin/config/content/markdown

In the "Parser" tab, I select CommonMark (1.5.3).

In the "Render Strategy" tab, I select Filter Output.

I save the changes.

I run drush cget markdown.settings and see:

dependencies:
  module:
    - markdown
parser:
  id: league/commonmark
  render_strategy:
    type: filter_output
    allowed_html: '<a href hreflang> <abbr> <blockquote cite> <br> <cite> <code> <div> <em> <h2> <h3> <h4> <h5> <h6> <hr> <img alt height src width> <li> <ol start type=''1 A I''> <p> <pre> <span> <strong> <ul type>'
    plugins:
      - markdown
      - bootstrap
  settings:
    allow_unsafe_links: true
    enable_em: true
    enable_strong: true
    html_input: allow
    max_nesting_level: 0
    renderer:
      block_separator: \n
      inner_separator: \n
      soft_break: \n
    unordered_list_markers:
      - '-'
      - '*'
      - +
    use_asterisk: true
    use_underscore: true

Notice that parser.render_strategy.allowed_html and parser.render_strategy.plugins were added and that parser.settings has changed, even though I did not edit them in the web UI.


I revert the changes by visiting: https://drupal8.example.org/admin/config/content/markdown

In the "Parser" tab, I select PHP Markdown Extra (1.9.0).

In the "Render Strategy" tab, I select None.

I save the changes.

I run drush cget markdown.settings and see the original settings:

dependencies:
  module:
    - markdown
parser:
  id: michelf/php-markdown-extra
  render_strategy:
    type: none
  settings:
    code_attr_on_pre: false
    code_class_prefix: ''
    empty_element_suffix: ' />'
    enhanced_ordered_list: true
    fn_backlink_class: footnote-backref
    fn_backlink_html: '&#8617;&#xFE0E;'
    fn_backlink_label: ''
    fn_backlink_title: ''
    fn_id_prefix: ''
    fn_link_class: footnote-ref
    fn_link_title: ''
    hard_wrap: false
    hashtag_protection: false
    no_entities: false
    no_markup: false
    omit_footnotes: false
    predef_abbr: {  }
    predef_titles: {  }
    predef_urls: {  }
    tab_width: 4
    table_align_class_tmpl: ''

Notice that parser.render_strategy.allowed_html and parser.render_strategy.plugins were removed and that parser.settings has changed back, even though I did not edit them in the web UI.

the problem

However, these associated changes do not happen if I change with drush:

$ drush cset markdown.settings parser.id league/commonmark
$ drush cset markdown.settings parser.render_strategy.type filter_output
$ drush cget markdown.settings
dependencies:
  module:
    - markdown
parser:
  id: league/commonmark
  render_strategy:
    type: filter_output
  settings:
    code_attr_on_pre: false
    code_class_prefix: ''
    empty_element_suffix: ' />'
    enhanced_ordered_list: true
    fn_backlink_class: footnote-backref
    fn_backlink_html: '&#8617;&#xFE0E;'
    fn_backlink_label: ''
    fn_backlink_title: ''
    fn_id_prefix: ''
    fn_link_class: footnote-ref
    fn_link_title: ''
    hard_wrap: false
    hashtag_protection: false
    no_entities: false
    no_markup: false
    omit_footnotes: false
    predef_abbr: {  }
    predef_titles: {  }
    predef_urls: {  }
    tab_width: 4
    table_align_class_tmpl: ''
$

In particular, notice that parser.render_strategy.allowed_html and parser.render_strategy.plugins were not added and that parser.settings has not changed.

Using the web UI, these associated changes do not have to be specified explicitly.

Is there a way to make similar under-specified config changes by cli?

For clarification, I use drush simply as an example of a cli. Using other non-interactive commandline tools would be fine.

  • I think your question is “Can config:set do the same operations as what a module can do in its configuration form(s)?” – mradcliffe Jul 28 at 11:36
  • @mradcliffe not quite. I don't care what the commandline tool is, I just want it to be non-interactive so I can script it. However I don't want to have to explicitly specify all kinds of additional data that the interactive web ui doesn't require. – jhnc Jul 28 at 12:10
  • I guess I still don't understand what exactly you want to achieve and also why? – leymannx Jul 28 at 13:32
  • @leymannx I am writing a shell script to build a drupal 8 website from an existing drupal 6 website. Every time I notice something broken with the migration, I want to modify the script with non-interactive commands that fix the problem. Currently, configuring settings by web UI is not non-interactive. – jhnc Jul 28 at 13:46
3

Using Form API and Configuration are two fundamentally different things:

  1. A module configuration forms in Drupal are (usually) provided by that module extending ConfigFormBase. A “Form” is just a specially-crafted render array that on submit (and validate) calls methods on the Form controller class. A module author can do whatever they want in that submit/validate based on user's input. This can include calling set/get on Config objects as they need to, and then calling save. Form submit methods and callbacks can do any number of complexity rather than a simple operation on a config object.

  2. The Drush config:set (cset) command sets a value to a single config key. It does not do any logic or form submission. One needs to know exactly the configuration that needs to be saved. The config commands are doing create, read, update, and delete on the config object defined by the provided key.

The answer is no. There is not a way for Drush to determine what the module is actually doing in its form submit.

In order to replicate what a module does in logic, then the same logic must be traced and values changed accordingly before trying to save the configuration.

| improve this answer | |
  • Thanks. Doesn't have to be drush (that's just an obvious example of a cli). Given the web UI is an HTTP GET, manual modification of some of the data received, followed by a POST, I had hoped there was a simple way to cause the equivalent of this GET/modify/POST non-interactively. – jhnc Jul 28 at 12:04
  • 1
    Unfortunately not so simple. Every form/module can be different. As a module developer, I do the same thing and have some logic in my form submit that saves things. – mradcliffe Jul 28 at 14:25
  • please review my answer - in what situations may it fail? – jhnc Jul 28 at 16:36
1

This appears to update ancillary settings the same as the web UI:

drush php << 'EOD'
  use \Drupal\Core\Form\FormState;
  use \Drupal\Core\Render\RenderContext;

  $v['parser']['id'] = 'league/commonmark';
  $v['parser']['render_strategy']['type'] = 'filter_output';

  #$v['parser']['id'] = 'michelf/php-markdown-extra';
  #$v['parser']['render_strategy']['type'] = 'none';

  $s = new FormState();
  $s->setValues($v);
  $c = new RenderContext();
  $r = \Drupal::service('renderer');
  $r->executeInRenderContext($c, function() use ($s) {
    \Drupal::formBuilder()->submitForm(
      '\Drupal\markdown\Form\SettingsForm',$s
    );
  });
EOD
| improve this answer | |
  • I think that could fail for other forms that have required fields without default values set, but that's fairly impressive. You might create drush commands to get a form and set an arbitrary form. – mradcliffe Jul 29 at 12:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.