Merge Requests

Recent comments

And because it's not fair to talk in public about people without their knowledge, I informed Rajan about this thread in #3445444-10: Unit/Kernel tests are incompatible with Drupal 11 .

@rajan-kumar2026: This still doesn't fix anything. You can't just randomly change version numbers and expect to fix incompatibilities between versions.

I'm not in the mood right now to teach you the very basics of composer version constraints, how .info.yml files act as an abstraction for composer usage in Drupal land, how PHP and Drupal work in general and what unit tests are. Please ask your coworkers to give you some basic tutorials.

I assigned myself now to make it clear, that I want to fix this issue myself. But I'm not in a hurry, because there are more than two months left before Drupal 11 will be released.

After properly testing this module for compatibility, it's time to update composer.json and .info.yml with the new version constraint.

Besides that: I don't think it's fair to talk publicly about you without your knowledge. Because of your low quality contributions, I thought you would try to game the system for credit farming. Now I think, that you just want to help, but that Drupal is a bit too complicated for your first steps in open source contributions. See: #3445549: Credit farming of rajan-kumar2026

While skimming some more issues I also found a few, that looked valid or where Rajan actually reacted to feedback. When I opened this issue, I was sick and in a bad mood, so I didn't even see good intentions as an option. Now I share @adaperno's and @vishalkadam's conclusion.

I still think, that Rajan's contributions do more harm than good, but I also don't have a better idea for handling such cases other than teaching.

I want to avoid public shaming and it doesn't look like abusive behavior anymore. So... How to move on? Should I change the issue title and summary?

I had a quick look at todays actions. The user continues to post random screenshots and core_version_requirement merge requests without reading the issue. It's not "only" gaming the system. This is harmful spam and a lot of noise in a huge amount of projects.

I also thought again about the very low quality contributions (CSS and PHP) I saw yesterday. It always does something, but never the right thing. My guess: This person is not employed for programming and it smells hard like chatbot usage.

The page should have a section about how to flag/report abusive behavior. Is it the same as reporting spam via site moderator's issue queue?

Like here: https://www.drupal.org/docs/develop/issues/issue-procedures-and-etiquett...

Background: I have a strong evidence about a user, I want to avoid public shaming and I expected to find some information about how to handle such cases on this page.

@rajan-kumar2026: Well... Thanks for your effort, I guess?

You created a merge request with the automatically generated patch from 📌 Automated Drupal 11 compatibility fixes for disable_libraries Active , which marks this module as compatible with Drupal 11. But this issue is about incompatible unit tests with extracted notes from the linked patch and diff files in that issue.

Before I mark this module as compatible with v11, I have to manually test it and I have to fix at least the two mentioned issues.

I'm sorry, if this sounds rude, but... Are you credit farming? Because you obviously didn't read the issue summary.

I know, but I was in cleanup mode :-)

> This gives interested parties time to reactivate the issue if they see a problem with the fix and also allows time to see that a change has been made.

This is a good point to keep future issues open for a while... But the color coding is confusing. On Github and Gitea/Forgejo (and I think Gitlab, too) green is open and red is closed. So everytime I see a non-red issue, it looks like it needs work. With Drupal's color coding and fixed, but open issues, the list becomes too cluttered. Closing manually helps getting things out of sight and out of my head.

I'm sorry, but this is not possible right now and I don't want to implement it.

It would in a first step also help to get a list of all detected external libraries.

I can imagine two ways for this list:

  1. Create log while disabling external libraries during initial load (before caching)
  2. Parse all modules and active themes on a settings page (after caching)

I'm against 1, because I want to avoid a database write during initialization (for performance). Point 2 would require a lot of work, but could be useful. I have to think about...

It would be great if I could convert fixed CDN use of contrib modules into a local call to a folder where I downloaded the libraries - without having to change the code of the module/theme itself.

I'm against this option for a few reasons:

There are modules already for library management, e. g. Libraries API or Library Manager . But I didn't test any of these modules, so I can't tell if they are compatible with this module.

My main motivation for writing this module was to prevent the insane amount of random CSS files or jQuery sneaking into my theme. Globally disabling external libraries is only a safety measure against modules, that enable CDNs by default. If I ever want to manage or replace external libraries, I would first try one of the existing modules. If they don't work, I could write a new module named "replace_libraries", so the "disable_libraries" module won't get bloated.

Besides that, I don't want to fix symptoms. If you use modules, that enable CDNs by default, you should open an issue and explain, why this is bad. Maybe the author just never thought about the privacy and security impacts and is willing to learn. If not, you should ask yourself, if you can trust code from authors, who don't value consent.

For example the PhotoSwipe module version 4 enables CDNs by default (and disable_libraries disables them). Since version 5.0, it is opt-in, so they appear trustworthy.

The webform module tells a different story. GDPR and CDN related issues are known for years and I would never recommend using it. But it is the de facto standard form builder module for Drupal and I have to use it until an alternative exists. With disable_libraries I have a safety net during this time frame.

Did you find a solution? I'm stuck at the same point right now.

> Changing to 11.x as the current development branch.

What's the recommended way to work with a changed dev branch? Should I merge the 11.x branch into my current issue fork or should I create a new issue fork?

> This may be border if it needs test coverage but the scenario makes me feel it may

OK. I have to learn, how to write JS tests for Drupal first. So this may take a while...

## Notes to myself

### Possible JS test solutions:

* https://www.drupal.org/docs/develop/automated-testing/types-of-tests#s-f...
* https://www.drupal.org/docs/develop/automated-testing/browser-testing-us...
* https://www.drupal.org/docs/develop/automated-testing/javascript-testing...

### Tutorial:

* https://www.drupal.org/docs/automated-testing/phpunit-in-drupal/phpunit-...

### Test cases

* required modules: "announcements"
* run test as authenticated user
* run test on page, where the current theme is not the admin theme, e. g. `<front>`
* either create click event on "Announcements" button before JS tests or run JS directly
* test default setup with default theme (stable9 or stark should work) --> assert `document.querySelector('[data-off-canvas-main-canvas]') !== null`
* dynamically inject theme, that disables `off_canvas_page_wrapper` via `MY_THEME_element_info_alter`
* test default setup with injected theme --> assert JS error thrown
* test changed behaviour with my fix --> assert `document.querySelector('[data-off-canvas-main-canvas]') === null` && assert no JS error thrown

Maybe I get some attention after discovering the "Needs review" status update feature :-)

Today I finally understood the contribution system and what the heck this "Marketplace" thingy is. Watching the keynote from 2014 helped a lot to get a basic understanding.

and you should also grant yourself credit

This feels weird. I'm the maintainer and the one who has the power to click that "Merge" button. I won't bloat the commit message with my own name.

@ressa: Thanks. I'll merge your changes tomorrow.

And I have no idea, how the credit system works, yet... I assume, that you are credited automatically without me clicking anything...

I digged a bit deeper and wrote a module to disable libraries in general. As a bonus feature it disables the CDN usage of webform, too. Feel free to check it out: https://www.drupal.org/project/disable_libraries/

@Anybody Your workaround in #8 re-introduced "No such file or directory in _locale_parse_js_file()" warnings in multilingual setups - see: 🐛 disabling CDN causes php warnings with webform in multilingual setup Fixed . I published a different method in my new disable_libraries module.

I had a quick look using the dev release. Now pressing Enter works as expected and the repair button is much more understandable with the added context. Thanks for the fix.

Nice.

One last recommendation: Make notes. Drupal is very complicated (mostly for good reasons). When you revisit the project in a few weeks or months the weird bugs and Drupalisms won't be obvious anymore.

Now don't forget to check for the correct write permissions after all these tests - https://www.drupal.org/docs/administering-a-drupal-site/security-in-drup...

And please prepend "[Solved] " to the title of this thread - https://www.drupal.org/docs/administering-a-drupal-site/troubleshooting-...

composer.json is in the same folder where web or your renamed www folder is. Also run the composer commands from the same folder where your composer.json is. I would recommend to experiment a bit with composer first to get a feeling about the folder structure. Install a fresh drupal, update it, change it and inspect the folder structure. Then use this knowledge to update the existing installation.

You already found the bug with the missing write permission, which is complicated for experienced users, too.

And I would recommend to test the symlink variant, which avoids changing any default folders.

Any other ideas?

I forgot about the installer-paths section.

    "extra": {
        "drupal-scaffold": {
            "locations": {
                "web-root": "www/"
            },
            /* ... */
        },
        "installer-paths": {
            /* change "web/..." to "www/..." */
            "web/core": [
                "type:drupal-core"
            ],
            /* ... */
        },
    },

Not sure, if something breaks when you change this with an existing installation. When you install Drupal with composer create-project --no-install drupal/recommended-project . you can change all the settings in composer.json to match your setup and to e. g. remove unused modules before downloading them. When everything is correct, run composer install --no-dev.

Alternatively you could keep the original folder structure and use symlinks to prevent messing things up. I use one setup on a shared host with:

root folder www or in my case /var/www/virtual/$USER/ (not publicly accessible, but Apache has read/write access)

html/ (DOCUMENT_ROOT, publicly accessible, symlink to drupal-setup/web)
drupal-setup/
            config/
            web/
                index.php
                ...
            tmp/
            vendor/
            composer.json
            update.sh
            ...

On a different shared host I had to use a graphical user interface to point a domain to a folder, but the setup is pretty much the same:

home folder (~)

default-website/ (DOCUMENT_ROOT of example-a.com, publicly accessible)
drupal-setup/
            config/
            web/ (DOCUMENT_ROOT of example-b.com, publicly accessible)
                index.php
                ...
            tmp/
            vendor/
            composer.json
            update.sh
            ...

Can you share (parts of) your composer.json?

Just guessing... if you have "drupal/core-recommended": "10.2.3" in your required section without the ^ character, the version is fixed and won't update. Using "drupal/core-recommended": "^10.2.3" instead will update to versions >=10.2.3, <11.0.0. See also: https://getcomposer.org/doc/articles/versions.md#writing-version-constra...

I do not have a web folder but a www instead. Is that part of the problem?

Maybe... Did you change the scaffold mapping in your composer.json?

    "extra": {
        "drupal-scaffold": {
            "locations": {
                /* original */
                /*"web-root": "web/"*/
                /* change to new location */
                "web-root": "www/"
            },
        },
    }

If not, you probably installed the update into the (not used) web folder.

Yes, but I want to receive updates for scaffolding files. So I use a combination of all methods already. My current composer.json looks like this (comments are added for clarity, JSON files don't allow comments):

{
    /* ... */
    "require": {
        "composer/installers": "^2.0",
        "drupal/core-composer-scaffold": "^10.1",
        "drupal/core-recommended": "^10.2",
        "drush/drush": "^12.4",
        /* ... */
    },
    /* ... */
    "config": {
        "allow-plugins": {
            "composer/installers": true,
            "drupal/core-composer-scaffold": true,
        /* ... */
        },
        /* ... */
    },
    "extra": {
        "drupal-scaffold": {
            "locations": {
                "web-root": "web/"
            },
            "file-mapping": {
                /* disable overwriting dev file */
                "[web-root]/sites/development.services.yml": false,
                /* add content from local file to web/.htaccess after receiving updated scaffolding file */
                "[web-root]/.htaccess": {
                    "append": "patches/htaccess-append-deflate"
                }
            }
        },
    /* ... */
    }
}

The missing piece is the hardening of web/sites/default with the workaround of adding the write permission before updating.

In a comment inside update.sh above is a link to the docs with this workaround:

https://www.drupal.org/docs/develop/using-composer/starting-a-site-using...

which in turn links to the related issue 🐛 Composer scaffolding fails when permissions on default.settings.yml or default.settings.php is not writable. Needs work

This comes from the core scaffolding files, which are replaced when running updates. I only disabled the overrides for a few files via composer.json.

You have to add the write permission to web/sites/default instead of web/sites/default/files. Than composer is able to write into that folder.

While developing I use $settings['skip_permissions_hardening'] = TRUE; in my web/sites/default/settings.local.php to keep the current write permissions.

For updating I use a small bash script update.sh in the root folder that takes care of the write permission before running composer:

#!/bin/bash

# enable maintenance mode
drush state:set system.maintenance_mode 1 --input-format=integer
drush cache:rebuild

# prevent `Could not delete .../web/sites/default/default.services.yml`
# see https://drupal.stackexchange.com/questions/290296/composer-require-fails-because-it-cant-delete-default-services-yml/290297#290297
# see https://www.drupal.org/docs/develop/using-composer/starting-a-site-using-drupal-composer-project-templates#s-workaround
chmod u+w web/sites/default

# update dependencies
composer update

# re-harden site folder after update
chmod u-w web/sites/default

# run pending updates
drush updatedb --yes

# disable maintenance mode
drush state:set system.maintenance_mode 0 --input-format=integer
drush cache:rebuild

@ressa, @anybody: I agree, that these changes should be part of the webform module, but I don't see this coming:

  1. From looking at the history of the issue queue, I deduced that the core maintainer/owner @jrockowitz doesn't see loading third party code (from venture capital backed ad companies) as a problem.
  2. Multiple GDPR related issues were closed as "won't fix" or as "works as designed".
  3. The config form to opt-out is hidden in a sub tab. While navigating to this page, the third party providers are already contacted. Also that form has bugs, which makes it appear unimportant ( 🐛 Pressing Enter key on config/advanced form causes repair instead of save Active ).
  4. Disabling CDN usage broke over and over again in the past (e. g.: #3199336: Tippy 6 is always loaded from the CDN even if there is a local copy, because webform_library_info_alter is not rewriting its directory from the 5 version to the 6 version , #3254856: CKEditor Codemirror is still loaded from the CDN even if the library exists in /libraries. , #3316667: Tippy.js is loaded via CDN even when disabled ).
  5. To be honest: I don't care about GDPR. But I care about privacy and consent. Personally I can protect myself by using Firefox addons like uBlock Origin and LocalCDN. When running code on client projects it's another story. Now I have to protect the privacy of my clients and of their website visitors. And my clients have to care about GDPR. Using code from people, who don't value consent means, that I have to be very careful with every update. Otherwise some new code with GDPR violations could sneak in.
  6. Disabling CDN usage by default would be a breaking change. It would involve a config change to use included_libraries instead of excluded_libraries and the CDN keys would move from webform.libraries.yml to a preprocess or alter hook.
  7. The whole module feels a bit bloated: too much JavaScript, 1346 lines of code in webform.libraries.yml, thousands of files (to be fair, the biggest footprint are the tests folders)

From there I concluded, that it's not worth investing my time in improving this module. It just happens to be the de facto standard form builder module and I have to use it until an alternative exists. Because I can't trust code from developers who don't value consent, I decided to reduce the risks with config overrides via contrib module.

If there was a clear statement from @jrockowitz, that privacy has a high value, I might come back and could help fixing these issues.

After sending a merge request, all tests are passed, but there is one warning I don't understand:

If the last pipeline ran in the fork project, it may be inaccurate. Before merge, we advise running a pipeline in this project. Learn more

I skimmed the linked help page, but it just looks like generic information about how to setup CI pipelines.

Can I ignore it? If not, I need some guidance on how to resolve it.

@ressa convinced me in the forum to give this module a second try. After finding a few bugs and another GDPR violation ( 🐛 YouTube thumbnails are embedded on help page (performance, low bandwidth, GDPR compliance) Closed: works as designed ), I started to set some sane defaults via contrib module. This module acts as my learning module right now and it is hosted outside of drupal.org, but maybe it's interesting for others how I reduced the risk of GDPR violations.

The module: rljutils

The interesting bits (commits):

More fixes and overrides might follow soon...

Side note: I added the webform module to the list of problematic modules for GDPR compliance: #3075653-26: Drupal modules that may require extra work to be GDPR compliant

I had another look. This time with an open dev console in my Firefox and many errrors. For some reason the errors are only on the English version, not in the German one.

Uncaught TypeError: drupalSettings.user is undefined
     http://localhost:8080/core/modules/contextual/js/contextual.js?v=10.2.3:23
     http://localhost:8080/core/modules/contextual/js/contextual.js?v=10.2.3:314
contextual.js:23:27
Uncaught TypeError: Drupal.contextual is undefined
     http://localhost:8080/core/modules/contextual/js/models/StateModel.js?v=10.2.3:17
     http://localhost:8080/core/modules/contextual/js/models/StateModel.js?v=10.2.3:130
StateModel.js:17:49
Uncaught TypeError: Drupal.contextual is undefined
     http://localhost:8080/core/modules/contextual/js/views/AuralView.js?v=10.2.3:11
     http://localhost:8080/core/modules/contextual/js/views/AuralView.js?v=10.2.3:59
AuralView.js:11:47
Uncaught TypeError: Drupal.contextual is undefined
     http://localhost:8080/core/modules/contextual/js/views/KeyboardView.js?v=10.2.3:11
     http://localhost:8080/core/modules/contextual/js/views/KeyboardView.js?v=10.2.3:62
KeyboardView.js:11:50
Uncaught TypeError: Drupal.contextual is undefined
     http://localhost:8080/core/modules/contextual/js/views/RegionView.js?v=10.2.3:11
     http://localhost:8080/core/modules/contextual/js/views/RegionView.js?v=10.2.3:75
RegionView.js:11:48
Uncaught TypeError: Drupal.contextual is undefined
     http://localhost:8080/core/modules/contextual/js/views/VisualView.js?v=10.2.3:11
     http://localhost:8080/core/modules/contextual/js/views/VisualView.js?v=10.2.3:109
VisualView.js:11:48
Uncaught TypeError: drupalSettings.path is undefined
     http://localhost:8080/core/modules/toolbar/js/toolbar.menu.js?v=10.2.3:15
     http://localhost:8080/core/modules/toolbar/js/toolbar.menu.js?v=10.2.3:256
toolbar.menu.js:15:31
Uncaught TypeError: pathInfo is undefined
     http://localhost:8080/core/modules/toolbar/js/escapeAdmin.js?v=10.2.3:16
     http://localhost:8080/core/modules/toolbar/js/escapeAdmin.js?v=10.2.3:45
escapeAdmin.js:16:5
Unknown property ‘enable-background’.  Declaration dropped. advanced:1:19
Unknown property ‘-moz-osx-font-smoothing’.  Declaration dropped. advanced:1:3006
Uncaught TypeError: path is undefined
    attach http://localhost:8080/core/misc/active-link.js?v=10.2.3:25
    attachBehaviors http://localhost:8080/core/misc/drupal.js?v=10.2.3:166
    attachBehaviors http://localhost:8080/core/misc/drupal.js?v=10.2.3:162
     http://localhost:8080/core/misc/drupal.init.js?v=10.2.3:32
    listener http://localhost:8080/core/misc/drupal.init.js?v=10.2.3:20
    domReady http://localhost:8080/core/misc/drupal.init.js?v=10.2.3:26
     http://localhost:8080/core/misc/drupal.init.js?v=10.2.3:31
     http://localhost:8080/core/misc/drupal.init.js?v=10.2.3:34
active-link.js:25:42
Uncaught SyntaxError: "" string literal contains an unescaped line break advanced:1:88

Some broken HTML markup caused all the contextual errors.

web/modules/contrib/webform/src/Form/AdminConfig/WebformAdminConfigAdvancedForm.php

Line 103 (unclosed "a" tag):

- 'This behavior is disabled when the <a href=":href">Tippy.js library is disabled</a.'
+ 'This behavior is disabled when the <a href=":href">Tippy.js library is disabled</a>'

Of course now the German translation is missing, because it was translated from the broken markup, but with correct closing tag. Now also all the fancy options aren't displayed italic anymore. Nice.

Now I'm left with

Uncaught SyntaxError: "" string literal contains an unescaped line break advanced:1:88

in the English and the German version.

web/modules/contrib/webform/src/Form/AdminConfig/WebformAdminConfigAdvancedForm.php

Line 319:

- . PHP_EOL
+ . '\r\n'

Now both, the English and the German page ask for confirmation (with line break). Pressing the Enter key triggers that confirmation message.

This only fixes the broken HTML. Triggering the confirm alert prevents damage, but is completely out of context. The actual issue should be resolved by moving the repair step into a different form.

This also shows why relying purely on JavaScript isn't the best idea. It can break and than native HTML should do the job.

Side note: This broken code is just another example why enabling all JS libraries by default is a bad idea and enabling CDN usage by default is an even worse idea.

Today this problem happened to me as well.

Setup: Drupal 10.2.3
Languages: de, en
Default language: de
Urls have language code prefixes, e. g. /en/admin/structure/types/manage/issue
Initial installation via drush (Drupal 10.1.?):

drush site:install --yes --db-url="..." --locale="de" --site-name="..." --config-dir="..." --site-mail="..." --account-mail="..." --account-name="..."

I created the content type with the /en/... route and tried to translate the body afterwards. I also created a field with the /en/... route and tried to translate that afterwards.

Both variants resulted in the mentioned error message: "The configuration objects have different language codes so they cannot be translated".

Deleting the new content type and the new field and recreating them with the /de/... route worked.

Now I know, that I must configure such things in the default language. But I actually like using the user interface in German to know how it looks to clients, but always configure in English to get untranslated error messages, that can be copied into a search engine.

The webform module has CDNs enabled by default to load multiple JavaScript libraries. Disabling CDN usage in general is not possible without a custom module. Installing libraries locally disables the CDN usage, but if a future update adds a new CDN based library, there is a risk, that it will be loaded from a CDN by accident. Possibly anonymous users and registered users are affected.

It also loads many YouTube thumbnails on it's help page by default. Disabling is possible, but hidden in sub tab "Advanced" under the "Config" tab. It doesn't affect anonymous users, but registered users.

While trying to opt-out on the config pages, data from third party providers is already loaded. So configuring via drush config:set or via settings.php is necessary before opening any webform route after a fresh installation.

So both violations are opt-out instead of opt-in. Opting out is hidden in nested config pages and/or need workarounds with custom modules and config overrides to reduce the risk of exposing personal data from anonymous and registered users.

GDPR related issues were closed as "won't fix" or as "works as designed" in the past, e. g. 🐛 YouTube thumbnails are embedded on help page (performance, low bandwidth, GDPR compliance) Closed: works as designed and 📌 Allow to disable (dynamic) CDN loading of libraries in general Active . So it doesn't look like the author is interested in GDPR compliance. After skimming more issues, it looks like there actually was some work already to improve GDPR compliance in certain cases. But partially compliant equals to not compliant in this case.

Privacy invasive settings should be opt-in instead of opt-out.

And as mentioned above, the help text makes no sense anymore.

Workaround:

set "Video display" to "hidden" in "Advanced" sub tab under "Configuration" tab (admin/structure/webform/config/advanced). Now the lines "This screencast..." without the "Watch video" button below don't make any sense anymore, but at least the third party content is gone.

Setting "Video display" to "link" still loads all YT thumbnails and the "Watch video" button is a link now, that opens the YT video on the same page.

To make sure, that nobody enables it again in the future, a config override in settings.php helps:

$config['webform.settings'] = [
  'ui' => [
    // prevent loading YT thumbs on help tab
    'video_display' => 'hidden',
  ],
];

Thanks for clarifying in the docs.

If you use the order of elements as a guide, since Composer is mentioned first, before CDN -- my take would be that Composer was recommended over CDN.

This still doesn't solve the problem, that composer is a bad choice for managing JS libs. If I go that route, I'll probably try to add some logic to my update.sh, which already takes care of fixing write permissions before running composer update or running drush updatedb --yes and drush cache:rebuild afterwards. This way I could use npm for JS lib version management or delete all unneded files after downloading repositories.

changed id "summary-resolution-discovery" (duplicate) to "summary-resolution-onboarding"

Today I found some existing REST API functionality: https://www.drupal.org/drupalorg/docs/apis/rest-and-other-apis

Only read access is allowed.

So the docs and #2857160: Allow POST via RestWS API say, that It's read-only. But even if write access was enabled, this wouldn't solve the password management problem (no access token support).

But the api is really interesting for debugging and to get a better understanding of the internal field structure.

Side note: Both api endpoints for a project page contain user ids in the flag_project_star_user field, which should be hidden for privacy reasons:

https://www.drupal.org/api-d7/node/3419729.json
https://www.drupal.org/api-d7/node.json?field_project_machine_name=theme...

Thanks. Your tip with the BUEditor pointed me in the right direction. The route of all evil is the codefilter module or rather it's prism submodule, which changes the behaviour of the native <code> html element.

to drive discussion of change to features on drupal.org , you'd generate an issue.

Sure. But I needed a conversion script before opening an issue to be able to convert private notes in markdown to something that is compatible with drupal.org.

Now I'm not sure, if this issue belongs to the codefilter module or to the infrastructure issue queue... I have a feeling, that restoring native HTML functionality is a breaking change with millions of existing posts and issues, that have wrong markup.

Unlike the other services, we do not allow deleting or replacing releases, so you know you will be able to deploy the same code indefinitely.

Just tested it with git push origin :0.1.2 and broke my complete git access. No git push or git clone to any repo was possible anymore. Logging in and accepting the ToS fixed the broken git access. The error message could have been a bit more elaborative.

git push origin :0.1.2
remote:
remote: ========================================================================
remote:
remote: You (@raffaelj) must accept the Terms of Service in order to perform this action. To accept these terms, please access GitLab from a web browser at https://git.drupalcode.org.
remote:
remote: ========================================================================
remote:
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Good to know.

We do get occasional support requests for deleting accidental releases, which we do not allow. If everything were more automated, I expect there would be more accidental releases.

I get the point. But configuring the webhook is a decision (with somewhat advanced knowledge) to care about git tags and to automate the release process. With some fine tuning, only tags with version strings on branches with version strings could be released automatically.

It doesn't have to be fully automated. Running two different commands would be fine too. Any alternative, that doesn't require logging in and filling out a form (without markdown support and with non-conformant html support) would be great.

git push origin 0.1.3
./deploy.sh
# either with OS key ring integration or
# with manually entering password e. g. via auto type feature from KeePassXC

Besides calling a curl command to trigger a new release, deploy.sh could also contain some logic to parse CHANGELOG.md with the help of md2drupal.sh . .gitattributes takes care about removing that file from packages/releases.

I use the technique above for a WordPress plugin I maintain to convert git tags to SVN branches.

added link to missing notes section, that was mentioned in the initial post

converted markdown lists in initial post to html lists for better readability

About using CDN's, it is actually recommended to NOT use them on several Drupal documentation pages [...] Please correct it, where you found the opposite recommendation for CDN's, or supply a link here.

I was a bit suprised and glad to read this and I wondered, where I read it in the first place a few months ago... Now I found a reference:

Bundling or duplicating third party libraries into Drupal.org repositories is strongly discouraged – see Policy on 3rd party assets on Drupal.org for clarification of policy.

Instead, you should include third party libraries through either Composer, by using a CDN (Content Delivery Network), or by using the Libraries API module.

https://www.drupal.org/docs/develop/git/setting-up-git-for-drupal/drupal...

I think, I read about it while doing research about MIT and SIL Open Font License compatibility with GPL-2.0-or-later. Bundling JS libraries with a theme or a module is a licensing problem.

Composer is not designed to work well with JS libs. It's a php package manager. All variants I found are workarounds. Maintenance and version management becomes more complicated and/or complete git repositories are downloaded into web/libraries.

Somehow I overlooked the Libraries API module - probably because I confused it with the module.libraries.yml api. Or maybe I skipped it as an option, because it doesn't provide an automated workflow for version management of JS libs.

So it is not recommended to use CDNs. But I understand discouraging bundling of JS libs as an implicit recommendation to provide and use CDN based solutions by default.

About Webform being bloated ... Well, this is open source, and no one is stopping you from creating a few MRs, and start slimming it down :)

A fresh installation comes with 17,1 MiB, 2.187 files, 672 sub-folders. Using the variant with wikimedia/composer-merge-plugin added another 29MB of JS folders (tested 2023-09, numbers may differ today). webform.libraries.yml has 1346 lines of code with 13 CDN based libraries. With each new update I must be afraid that some random new library will be added, that isn't installed downloaded already via composer or Library API - and is now loaded via CDN.

Good luck slimming this down.

To be able to communicate with users on drupal.org without headaches I wrote a markdown to drupal conversion script.

input.md:

# Issue title

I found a bug.

* list
  * with nested list

[link text_with_underscores should not become emphasis]()

```
code with default highlighting
```

```text
code with text highlighting
```

```js
code with js highlighting
```

```html
code with html highlighting
```

It’s a multi step process:

  1. Basic markdown conversion
  2. prevent double encoding of code blocks and inline code
  3. fix syntax highlighting for JS

Basic markdown conversion

  • -task_lists - Drupal doesn’t support <input type="checkbox" />
  • -auto_identifiers - prevent headline ids <h2 id="markdown">Markdown</h2>
  • --no-highlight - prevent converting code to <span> elements
  • --wrap=none - Drupal doesn’t support \n inside <a> tags
pandoc -r markdown-task_lists-auto_identifiers --no-highlight --wrap=none -w html input.md > output.html

prevent double encoding of code blocks and inline code

For some reason Drupal changed the behavior of the native html element <code> to something weird with syntax highlighting. To restore the native behaviour, it must be converted to <code class="language-php">. Disabling syntax highlighting is not possible (or gets overwritten when switching between plain text and rich text editor).

# <pre class="html"><code> --> <pre><code class="language-html language-php">
sed -E 's/<pre class="([a-z]+)"><code>/<pre><code class="language-\1 language-php">/g' output.html > output2.html

# <code> --> <code class="language-php">
sed -E 's/<code>/<code class="language-php">/g' output2.html > output3.html

fix syntax highlighting for JS

sed -E 's/<code class="language-js/<code class="language-javascript/g' > final.html

As a one liner:

pandoc -r markdown-task_lists-auto_identifiers --no-highlight --wrap=none -w html input.md | sed -E 's/<pre class="([a-z]+)"><code>/<pre><code class="language-\1 language-php">/g' | sed -E 's/<code>/<code class="language-php">/g' | sed -E 's/<code class="language-js/<code class="language-javascript/g' > output.html

As a build command for kate editor:

pandoc -r markdown-task_lists-auto_identifiers --no-highlight --wrap=none -w html "%f" | sed -E 's/<pre class="([a-z]+)"><code>/<pre><code class="language-\1 language-php">/g' | sed -E 's/<code>/<code class="language-php">/g' | sed -E 's/<code class="language-js/<code class="language-javascript/g' > "%n".html

As a bash script named md2drupal.sh:

#!/bin/bash

# usage: ./md2drupal.sh input.md > output.html

pandoc -r markdown-task_lists-auto_identifiers --no-highlight --wrap=none -w html "$1" | sed -E 's/<pre class="([a-z]+)"><code>/<pre><code class="language-\1 language-php">/g' | sed -E 's/<code>/<code class="language-php">/g' | sed -E 's/<code class="language-js/<code class="language-javascript/g'

Now the content of output.html can be copied into a plain text editor field of Drupal. Issues don’t have a rich text editor option, so plain text is the default. For forum posts click on “Switch to plain text editor” below the text field, then copy the code.

Checking the preview before saving a post looks good for forum posts. Issue post previews have a CSS bug with ul {padding:0;list-style:none}, so it looks broken. The actual saved post has the right markup and is displayed with the correct CSS.

The text above was generated from a markdown file.

Generated output from input.md:

Issue title

I found a bug.

  • list
    • with nested list

link text_with_underscores should not become emphasis

code with default highlighting
code with text highlighting
code with js highlighting
code with html highlighting

It looks like lists actually work, but the CSS for unordered lists in the issue preview is broken.

  • test
  • test
  • test

Thanks for the hint, but I'm talking about the forum we are using right now.

Sorry, but there is not much I can do about that.

This happens when the http server of the git host is down due to maintenance or denial of service. If composer fails to download from https://codeberg.org/raffaelj/drupal-theme-drinimal.git, it falls back to using git with git@codeberg.org:raffaelj/drupal-theme-drinimal.git. In that case you would need an account on codeberg.org and either login with username and password or skip that step with a SSH key.

So normally - in case of a short maintance downtime - try it again after a few minutes.

If it doesn't fix itself, check the Codeberg status page or their Mastodon account to see if they are hit by a DDoS or if there is a planned downtime.

The real fix might be to move the repository from codeberg.org to git.drupalcode.org. But I still don't know, how to automate the release process.

I didn't look through the whole list yet, but devel and webprofiler are definitely game changers.

@joseph.olstad Yeah, I also hope that this is just a forgotten issue and drupal.org runs on modern systems. This issue being open just leaves too much room for speculation...

Just to be sure - is this the module that powers everything on https://www.drupal.org/project/*?

And if so, does this mean, that drupal.org still runs on PHP 5.6, which reached EOL on 2018-12-31?

Initially I was testing and digging how to automate a module release. Than I noticed, that the project module needs v7 and that drupal.org still runs with v7. Now I'm a little bit concerned about security issues...

Thanks. This sounds interesting. For hiding regions or blocks based on conditions I would have used twig templates of preprocess functions. Good to know, that there are other options.

Can you eleborate on use cases for the context module? I read the project description multiple times and I don't get it. It looks like the visibility rules of blocks. Is it maybe obsolete in current Drupal versions?

Some people may need some XML sitemap module but I prefer manual crawling requests in Google Search Console over relying on a sitemap but if you have more than 100 webpages yeah in many cases a sitemap is nice and can help.

Sure, it depends on the size of your site. But it's also useful for automated and manual tests. I have a script that runs a lighthouse test on all pages listed in the sitemap so I can fix errors on localhost before publishing. But I'm actually rethinking how useful a XML sitemap is. To match WCAG AA and AAA, a site map should be provided. To avoid duplication, a HTML sitemap might be the better choice.

Some people may need some meta tags module but in many cases I think a good <H1> tag and a good opener passage and a good URL alias are enough. I think metatags are to some extent a thing of the past with all the artificial intelligence anlysis of webpages from search engines nowadays.

I agree on using semantic markup and text written for humans instead of duplicating content in <meta> tags. But I strongly disagree on the "AI" part. Google and Bing are eating themselve by subsidizing expensive and energy hungry chat bots, that are heavily used for polluting the internet with SEO spam and misinformation. Providing machine readable markup and meta tags helps curating the web with alternative software.

The link to Advanced CSS/JS Aggregation is broken. You wrote dgo.ti instead of dgo.to.

Also it looks like advagg is mostly obsolete (and partially incompatible) since Drupal 10.1.0 - see: 📌 Document which parts of the module are still relevant after aggregation changes in 10.1.0 Needs review

I played a bit with test projects - and again documented all quirks and confusing settings. My current conclusion: Releasing on drupal.org needs too much manual work.

Initial test in a sandboxed project with some notes in `README.md`: https://git.drupalcode.org/sandbox/raffaelj-3419542

Second test as full project with many notes in `README.md`: https://git.drupalcode.org/project/theme_test_not_sandboxed

Anyways - I reserved the project name, so nobody can grab "drinimal" before I finish the first release.

The docs of the sandbox feature are a bit confusing and it feels wrong to pollute the drupal.org registry with a test theme and a planned theme. But I guess, it's good enough for now. When I find some more time during the next weeks I'll open a few issues with my findings.

I don't know if "too much" got removed for others to use your Drinimal theme ... maybe some parts or components were removed, because you didn't need them, but others might expect them to be there?

Maybe I removed too much, maybe some core markup is just some D7 legacy code and maybe the current twig architecture doesn't match the modularity enough to inject markup only if needed... I'll use it as a base for future projects and try to investigate if it breaks something.

But if it could be usable for a wider audience, you might even consider sharing it under Drinimal , which is available

I already thought about publishing it on drupal.org and I checked if the name is available before deciding about the final name "drinimal". I also spent hours on reading about GPL and how licensing works in the Drupal eco system. So it should be ready to be published in the official repository.

But:

  • The theme still has some opinionated changes (e. g. the language switcher), that should be moved to a module.
  • Drupal issues don't have markdown support.
  • I don't fully understand how the patch and contribution system works. I'm more familiar with the "Merge Request" (or in Github slang "Pull Request") workflow, with the @mention system and with automatic linking of git commit messages and the issue tracker.

For now I'm happy with a simple composer require "raffaelj/drupal-theme-drinimal:@dev" (It is published on packagist.org). After testing it for a few more weeks, doing some more cleanup and setting an initial version to 0.1.0 I'll think again about publishing it on drupal.org.

@ressa Thanks again for your help. You were interested in the resulting HTML and I finished moving to Drupal a few days ago. The old site is offline now, so a comparison isn't possible anymore. But I documented and published nearly everything I've changed.

Current website: https://www.rlj.me/en

Source code of

@Kent8 From your description it is impossible to guess, if it has anything to do with this issue. So you should solve that one first (and maybe open a new issue for this case) to be able to read the missing error message.

Uncaught TypeError: Cannot read properties of null

This means that no <div data-drupal-messages> and no <div data-drupal-messages-fallback> exists. Besides that core/misc/message.js should check for the existence of the fallback this could be because (just guessing):

  • Your theme or a module disabled these message placeholders (like I did in a minimal base theme)
  • You disabled "Primary admin actions" or "status messages" in your block layout

I can also confirm that patch #39 solves the issue.

In my case I experienced redirects for aggregated CSS an JS files from `/sites/default/files/css/css_{hash}` to `/de/sites/default/files/css/css_{hash}` with a 301 status code after rebuilding the cache on a multilingual site - only on front page, that is redirected from `/` to `/{lang}`.

Because I don't want to wait (and 301s are browser cached), I added the code from #39 to a custom module and use it in production now. Thanks @jhuhta.

Thanks @alexpott - You saved my day.

After adding your change to \Drupal\editor\Entity\Editor::calculateDependencies() (and adding a missing ")") I was able to debug my test setup:

[notice] Update started: ckeditor5_post_update_list_multiblock
>  [error]  The editor "webform_default" has the filter format "webform_default" but the filter format does not exist 
>  [error]  Update failed: ckeditor5_post_update_list_multiblock 
 [error]  Update aborted by: ckeditor5_post_update_list_multiblock 
 [error]  Finished performing updates. 

So it was an editor format from an uninstalled module, that I tested a while ago.

After running drush config:delete editor.editor.webform_default I was able to run drush updatedb without errors.

Related issues:

* url() should return / when asked for the URL of the frontpage 🐛 url() should return / when asked for the URL of the frontpage Needs work
* Unable to save '/' root path alias 🐛 Unable to save '/' root path alias Postponed (duplicate)
* Front Page canonical is Incorrect (duplicate)

This issue still persists, because PHP8 deprecated null values in string functions, which will become errors instead of notices sooner or later.

To "fix" my initial motivation to set the path alias of my front page to /, I might install the Metatag module . I'm not happy with adding 1,9 MiB/522 files/231 sub-folders just to set the correct canonical and shortlink tags, but it might be a workaround to get started.

The only difference between your minimal example and my "more minimal" example is dropping the core CSS.

The difference with my other example (with drush) is only some boilerplate code.

The intetesting bit is the decision to set stable9 or false as base theme, which results in different markup.

Thanks for the flowers :-)

I don't really like the swiss army knife image, but never found the time to paint an alternative. Also updating my own site is always harder than working on others' sites... And it's implemented as <img> with TinyMCE instead of the other svg, that is hardcoded as inline <svg> into my theme. So animating it becomes more complcated...

But I plan to rebuild my site with Drupal and I normally publish most of my work under MIT license - not sure, how well this works with the GPL2 eco system yet - so you can expect to see a minimal theme in production soon.

To be even more minimal, you can use this:

stablemain/
├── css
│   └── style.css
├── stablemain.info.yml
└── stablemain.libraries.yml

stablemain.info.yml

name: Stable Main
type: theme
description: A theme using Stable 9 templates as base, but without core or stable9 css.
base theme: stable9
core_version_requirement: ^10
libraries:
  - stablemain/global-styling
libraries-override:
  # disable core css, make sure to reimplement at least `.visually-hidden`
  system/base: false

stablemain.libraries.yml

global-styling:
  css:
    layout:
      css/style.css: {}

css/style.css

.visually-hidden {
  position: absolute !important;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
  width: 1px;
  height: 1px;
  word-wrap: normal;
}
.visually-hidden.focusable:active,
.visually-hidden.focusable:focus {
  position: static !important;
  overflow: visible;
  clip: auto;
  width: auto;
  height: auto;
}

After thinking some more about it, I really like this minimal and manual approach, because it also skips the step of removing/disabling boilerplate code like in my conclusion from:

https://www.drupal.org/forum/support/theme-development/2023-10-16/how-to...

 I digged a bit deeper and I have a much better understanding now.

Than I tried php ./web/core/scripts/drupal generate-theme rljstarter. Now I have a lot of CSS and some twig templates from stable9, some JS from core/misc and jQuery. I know, how to overwrite the stable9 templates, but I'm not sure, how to remove all the unneccessary JS and how to reduce the loaded CSS.

I found the source of the core/misc JS and jQuery. After uninstalling the core statistics module, they are gone. I'm not sure, if it was enabled by default or if I enabled it for testing. But I didn't activate any logging in the settings of the statistics module. I wrongly assumed, that these random JS dependencies were introduced by stable9 - or by the starterkit theme, which is a child of stable9.

The libraries-override section in stable9.info.yml in combination with the amount of code in my_starterkit_theme.libraries.yml as well as libraries: and libraries-extend: in my_starterkit_theme.info.yml aren't very intuitive for beginners, so backtracing random CSS and JS dependencies was quite hard.

Now I found another missing piece to disable css dependencies via libraries-override in my_starterkit_theme.info.yml.

libraries-override:
  # Disable all core system css files
  # system/base: false

  # Disable only some core system css files
  system/base:
    css:
      component:
        css/components/ajax-progress.module.css: false
        css/components/align.module.css: false
        css/components/autocomplete-loading.module.css: false
        css/components/fieldgroup.module.css: false
        css/components/container-inline.module.css: false
        css/components/clearfix.module.css: false
        css/components/details.module.css: false
        # css/components/hidden.module.css: false
        css/components/item-list.module.css: false
        css/components/js.module.css: false
        css/components/nowrap.module.css: false
        css/components/position-container.module.css: false
        css/components/progress.module.css: false
        css/components/reset-appearance.module.css: false
        css/components/resize.module.css: false
        css/components/sticky-header.module.css: false
        css/components/system-status-counter.css: false
        css/components/system-status-report-counters.css: false
        css/components/system-status-report-general-info.css: false
        css/components/tabledrag.module.css: false
        css/components/tablesort.module.css: false
        css/components/tree-child.module.css: false

One of my questions in my inital thread wasn't answered, yet:

Should I use stable9 as base theme when starting with Drupal 10? Or is stable9 the fallback when upgrading from Drupal 9 to 10?

I assumed, that stable9 is outdated in Drupal 10 and that I should rely on the latest templates (core/modules/system/templates/*, eventually in combination with core/themes/starterkit_theme/templates/*) instead. This is why I came to the conclusion, that copying the core templates into a fresh theme folder might be a good idea. After reading the docs I also assumed, that either the starterkit theme is a copy of the latest core template files or that a theme named "stable10" exists. Both assumptions were false.

After copying all nested files into single folders and running diffs on

  • core/modules/system/templates/ vs core/themes/stable9/templates/
  • core/modules/system/templates/ vs core/themes/starterkit_theme/templates/
  • core/themes/stable9/templates/ vs core/themes/starterkit_theme/templates/

I have a much better understanding now:

  • system provides 64 templates, stable9 has 177 templates and starterkit has 85 templates (Drupal 10.1.5)
  • system templates are mostly for admin related pages
  • system templates provide some fallback templates (e. g. field.html.twig, page.html.twig) with minimal markup
  • stable9 has a lot of duplicates from system
  • stable9 adds many variants for e. g. fields and views
  • stable9 replaces some system templates with minor changes
  • stable9 adds a lot of templates, that I don't understand, yet
  • starterkit adds a lot of div wrappers and css classes
  • starterkit adds some new templates (some are empty as placeholders for customization)
  • starterkit adds some css dependencies through templates, e. g. {{ attach_library('starterkit_theme/file') }}
  • starterkit improves some markup from stable9

Conclusion

Because starterkit adds a lot of the wrapper divs and css classes, I won't use it as a base. Instead I might cherry-pick some improvements into my new theme.

I'm not sure, yet, if I want to set 'base theme': false or if I want to use stable9 as base theme. Because I want a stable theme, using stable9 feels like the right choice.

In a post above I created a task list:

  1. use drush generate theme to create a basic struture
  2. set 'base theme': false
  3. optional: enable a few hand-picked css libraries like core/normalize
  4. copy and modify a few twig files from core to reduce div soup
  5. add my own CSS/JS
  6. add changelog and security advisories to my rss feed reader
  7. set 'base theme': stable10 when I upgrade to Drupal 11

Looks like a simple and solid way. Did I miss something?

 My new task list looks like this:

  1. use drush generate theme to create a basic structure (using drush instead of drupal generate-theme my_theme_name, so no starterkit is involved)
  2. set 'base theme': stable9 (or maybe false - still not 100% sure)
  3. disable core css in my_theme.info.yml:
    libraries-override:
      system/base: false
    
  4. simplify/clean boilerplate code and folders, e. g. my_theme.libraries.yml, delete/fix my_theme/js/my_theme.js (generates JS error if window.Drupal is not defined)
  5. optional: enable a few hand-picked css libraries in my_theme.info.yml (e. g. core/normalize)
  6. copy and modify a few twig files from system/stable9/starterkit as inspiration and to reduce div soup
  7. add my own CSS/JS
  8. add changelog and security advisories to my rss feed reader
  9. when upgrading to Drupal 11: check for changes and if a new theme "stable10" exists - if so, eventually set 'base theme': stable10

I think, my initial questions are answered, but I won't mark this thread as solved for now. Too much theory and too little tests, yet...

Have you seen the  Starterkit theme page?

Yes. I read that a while ago, but reading your linked resources (partly for the second time) didn't hurt. Now I also understand, that the starterkit is not just a minimal default theme, but a whole concept to use other themes as starterkit.

Also I wrote in my intial post, that I tried php ./web/core/scripts/drupal generate-theme rljstarter, which in my brain implied some knowledge about the starterkit theme. I should have been more elaborately.

For sub-theming (Edit: I was mistaken, it is a sub-theme)

From reading the docs I also thought, that starterkit is a base theme and that it might be the successor of stable9 (because of the non-existent stable10 theme). Now I know, that it is a child of stable9.

Many use a sub-theme based on one of these Bootstrap based themes:

I'm not a big fan of bootstrap or frameworks in general - too much bloat. My plan is to reduce the markup to a minimum and to write my own CSS.

I'm aware of this page (I linked to it in my initial post). The problem is the "minimal markup and styling". I want minimal markup and no styling. I may have found the solution already - coming in a longer answer to my initial post soon.

Thanks for the suggestion. I read the - surprisingly short - source code, but didn't test the module, yet. In any case it's good to know how to change template behaviour with a single preprocess hook and a second hook to switch the default twig template now.

I'm not sure, if I like it:

  1. I don't want to click through config forms for every field. I would prefer writing template files with well arranged article/section/figure/div wrappers per content type once.
  2. Finding the right template file for manual changes or debugging in general becomes harder if more hooks and filters are involved.
  3. The module breaks when overwriting field.html.twig in a theme. This feels a bit fragile. See: https://www.drupal.org/project/fences/issues/3306130 🐛 Doesn't work with themes overwriting field.html.twig (also core like Bartik) RTBC

Thanks for your feedback. I guess, I'll try the following procedure next:

  1. use drush generate theme to create a basic struture
  2. set 'base theme': false
  3. optional: enable a few hand-picked css libraries like core/normalize
  4. copy and modify a few twig files from core to reduce div soup
  5. add my own CSS/JS
  6. add changelog and security advisories to my rss feed reader
  7. set 'base theme': stable10 when I upgrade to Drupal 11

Looks like a simple and solid way. Did I miss something?

I still don't understand why the starterkit theme exists.

I think it would be more correct to copy templates as needed.

Sounds plausible, but I had bad experiences with WordPress child themes, where Gutenberg updates broke the layout multiple times. I want to avoid such failures with Drupal.

I can't asses the stability of core templates (yet). So if I would copy all core templates, I could be pretty sure about a stable markup (besides changing filters, that affect templates).

If this not intended, than setting a node as home/front page in system settings should change the canonical/alternate links automatically.

@gisle Thanks for the fast review and for upgrading my role.

And it's good to know, that Akismet is used. In a different forum, where I have moderator rights, I often tried to understand the reasons for flagging posts as spam. It always felt random...

Production build 0.69.0 2024