Quantcast
Channel: Issues for Drupal core
Viewing all 295251 articles
Browse latest View live

The Header H2 Search results title doesn't have any class for theming

$
0
0

Problem/Motivation

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

The docroot/core/modules/search/src/Controller/SearchController.php Line 102 , should have any class for

to get selected by css
if (count($results)) {
$build['search_results_title'] = [
'#markup' => '

' . $this->t('Search results') . '

',
];
}


Breadcrumb render cache not invalidated when entity label changes

$
0
0

Problem/Motivation

Cache of entities are not invalidated when the entity label changes.

Steps to reproduce for nodes & breadcrumbs (from #3):

  1. Create a node with title 'Title A'.
  2. Change the title to 'Title B' and check the 'Create new revision'.
  3. Open the Revisions tab > Breadcrumb shows the right title (Title B).
  4. Change the title to 'Title C' and check the 'Create new revision'.
  5. Open the Revisions tab.

Expected: The title in the breadcrumb is 'Title C'.
Actual: the title in the breadcrumb is 'Title B'.

Steps to reproduce for users (from #48):

  1. Log in
  2. Edit your username and save.
  3. Return to the edit screen for your user account.

Expected: Breadcrumb shows your new username
Actual: You'll see your old username is still utilised in the breadcrumb.

Proposed resolution

Allow attaching cacheability metadata to titles with a new CacheableTitleResolverInterface that returns a static or dynamic title (with cacheable metadata).

upgrade from 10.3.10 to 10.4.0 failed

$
0
0

Problem/Motivation

Your requirements could not be resolved to an installable set of packages.

Problem 1
- Root composer.json requires drupal/core-recommended 10.4.0 -> satisfiable by drupal/core-recommended[10.4.0].
- drupal/core-recommended 10.4.0 requires guzzlehttp/guzzle ~7.9.2 -> found guzzlehttp/guzzle[7.9.2] but these were not loaded, likely because it conflicts with another require.

Steps to reproduce

1. install drupal core 10.3.10
2. upgrade it to 10.4.0 with composer:
composer require drupal/core-recommended:10.4.0 drupal/core-composer-scaffold:10.4.0 drupal/core-project-message:10.4.0 --update-with-all-dependencies

upgrade failed with the above error

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Olivero default welcome page needs link removed

$
0
0

Drupal core's default welcome page located in web/core/themes/olivero/templates/includes/get-started.html.twig links to a page that does not get updated. Let's just yank this bullet point out.

Deprecate TestDiscovery test file scanning, use PHPUnit API instead

$
0
0

Problem/Motivation

Drupal is using its own code to discover tests to be executed, which along time lead to discrepancies in the tests executed betwen PHPUnit CLI and run-tests.sh.

PHPUnit 10 (Feb 2023) introduced an API to discover the test suites, that can be used instead. Also, PHPUnit 10 introduced attributes to replace the annotations that were previously used to indicate test configuration to PHPUnit. PHPUnit 11 (Feb 2024) is triggering deprecations if it detects tests that use annotations. PHPUnit 12 (Feb 2025) will no longer parse annotations.

Drupal's TestDiscovery class, that builds the tests to be executed by run-tests.sh, mandates tests to use @group annotations. It fails if only #[Group(...)] attributes are used.

Proposed resolution

  • Deprecate TestDiscovery::getTestClasses() and related methods.
  • Introduce a like-for-like replacement that uses PHPUnit's API for the discovery, and enriches the information returned by the API to provide same info as TestDiscovery::getTestInfo().
  • Make the new code ready for PHpUnit's 10+ attributes instead of annotations.
  • In the process, fix some bugs of TestDiscovery::getTestClasses() that were identified:
    • for each test class, it only reports groups present in the class-level annotations: this means that method level annotations do not qualify test classes for a group, potentially missing the execution of some tests. PHPUnit is more accurate in bubbling up method-level annotations/attributes to the class
    • it does not check duplication of @group annotations that specify the same group. PHPUnit make them unique.
    • when filtering by test suite, it reports some test groups with an empty array, since in any case it iterates all test directories and files. PHPUnit only scans the directories indicated in phpunit.xml for each test suite, providing more accurate results.

Remaining tasks

User interface changes

nope

API changes

nope

Data model changes

nope

Release notes snippet

Drupal tests now can use PHPUnit's 10+ attributes instead of the legacy annotations. New tests MUST use attributes.

Introduce entity permission providers

$
0
0

Problem/Motivation

Right now each content entity type needs to define its set of permissions from scratch, then declare a matching access handler. This is pure boilerplate, an entity type's permissions can very precisely be guessed based on the interfaces it implements and the permission granularity it specifies. Furthermore, requiring each developer to create a new access handler each time leaves room for frequent bugs, such as wrong cacheability metadata.

Proposed resolution

The permissions currently vary based on two factors:

  • EntityOwnerInterface
  • Permission granularity (bundle / entity_type)

Future iterations of the patch / issue followups would also take into account EntityPublishedInterface.

Generated permissions:

  • "administer $entity_type_id" (god mode permission)
  • "access $entity_type_id overview" (the basic permission for listings)
  • "view $entity_type_id" OR "view own $entity_type_id" / "view any $entity_type_id" depending on EntityOwnerInterface
  • create/update/delete permissions per bundle or per entity type, also taking into account EntityOwnerInterface

Note that view permissions are never per-bundle cause we have no way to enforce it, we'd need query access for that (ala node access).

Just like we did for route providers, we introduce the concept of permission providers. That makes this generation opt-in.
Each participating entity type would define the core's permission provider, and the matching access handler. Core calls the permission provider of each entity type when building permissions.

The proposed solution was implemented in the Entity API contrib module (#2801031: Provide a generic entity access handler and permissions) and is used by Commerce and other contrib modules.

Remaining tasks

Roll the patch

ConfirmFormInterface::getFormName() serves no purpose in ConfirmFormBase

$
0
0

Problem/Motivation

ConfirmFormInterface::getFormName() is only called by ConfirmFormBase. The return value, a string, is used to build a hidden form element:

    $form[$this->getFormName()] = ['#type' => 'hidden', '#value' => 1];

The form value is not used by ConfirmFormBase's submit handler, although one subclass in core, UserMultipleCancelConfirm does check it.

However, because this form element uses the #value property, its value will ALWAYS be 1 according to the docs for Drupal\Core\Render\Element\Hidden:

 * - #value: The value of the form element. The Form API ensures that this
 *   value remains unchanged by the browser.

Therefore, AFAICT it doesn't serve any purpose and both the element and the ConfirmFormInterface::getFormName() could be removed.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Url only outputs the last value of a query parameter

$
0
0

Problem/Motivation

Drupal uses PHP's parse_str function to parse querystrings in multiple places. This function incorrectly assumes that a parameter name can occur only once and returns just the last value.

Example with drush php:

>>> print \Drupal\Core\Url::fromUri('https://example.com/page?tag=one&tag=two')->toString();
https://example.com/page?tag=two

This behavior is a PHP-ism and is not a web standard. Other platforms may and do use the format of repeated param name to pass multiple values.

Further reading:

Proposed resolution

Implement a version of parse_str that is backwards compatible, i.e. treats ?tag=one&tag=two the same way as ?tag[0]=one&tag[1]=two.

Remaining tasks

  • Decide if this ticket should be for internal and external URLs, or external URLs only. See #31 and #41.
  • Add a way to control the output of query arguments.

User interface changes

None

API changes

New static method Drupal\Core\Url::parseString($string).

Data model changes

None.

Release notes snippet

Fixed a bug in parsing query strings with repeated param names.


Fix not loading CKEditor 5 and Tour with BigPipe enabled after Drupal 10.4 update

$
0
0

Problem/Motivation

Hi,
My site was working perfectly well with Drupal 10.3 and CKEditor 5
After updating the site to Drupal 10.4 the entire site still works fine but when I edit existing content the CKEditor Wysiwyg editor no longer loads. The error in the console is: (Also attached a screenshot)

Uncaught TypeError: Cannot read properties of undefined (reading 'attach')
at Object.editorAttach (editor.js?v=10.4.0:304:37)
at editor.js?v=10.4.0:228:18
at Array.forEach ()
at Object.attach (editor.js?v=10.4.0:211:52)
at drupal.js?v=10.4.0:166:24
at Array.forEach ()
at Drupal.attachBehaviors (drupal.js?v=10.4.0:162:34)
at big_pipe.js?v=10.4.0:153:10
at big_pipe.js?v=10.4.0:184:3

When I add new content the editor is loaded initially but when I want to edit that content or other content the editor does not load.

I have uninstalled the CKEDitor and re-installed and reassigned it to the text format. Did not help
I cleared my cache in case javascript files were cached. Did not help.

So I'm stuck and hope someone can help.

#3294720: The attachBehaviors() for document is only called after Big Pipe chunks are processed
#3467860: Ensure consistent ordering when calculating library asset order

Steps to reproduce

Given that a Drupal 10 site was installed with the minimal profile ( not the standard profile )
And later on the BigPipe and CKEditor5, Tour modules were installed
Then the wight of the BigPipeJavaScript library will affect the CKEditor 5, Tour, Maybe other modules.

Big Pipe is attempting to attach behaviors too early, and it’s affecting the Tour module as well.

Proposed resolution

  • Find a better way to Attach behaviors in Big Pipe
  • Add header: true to the drupal/big_pipe library.
  • Switch to use a custom domReady in the BigPipe script to let work as Drupal init to Attach behaviors early, if possible without errors
  • Suggestion for further improvement: Have advanced config settings for BigPipe:
    • Limit to selected themes - Example: only load in the front-end themes.
    • Limit by user role - Example: only autonomous users.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Datetime fields should utilise #required_error

$
0
0

Problem/Motivation

If we set #required_error on the render array for a datetime element it doesn't use it. It should use it.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Better warning message when variation cache detects an incompatible CacheRedirect

$
0
0

Short summary of what's going on

When people do not take care of the consistency of their cache contexts, incomplete or wildly different cache redirects may be attempted to be written. At best these lead to uncacheable items, at worst they lead to security issues. This is why D10.4 and D11 shipped with new hardening that throws an E_USER_WARNING when something wrong is detected.

This makes tests fail if the module has insecure code, which is what we want. But the message being shown could be more informative, so the MR in this issue adds the cache ID of the entry where the flaw is detected.

Original report

i have cache problem after i updated to 10.4.0

always getting this message :

User warning: Trying to overwrite a cache redirect with one that has nothing in common, old one at address "languages:language_interface, theme, user.permissions" was pointing to "url", new one points to "url.path.parent, url.path.is_front, route". in Drupal\Core\Cache\VariationCache->set() (line 143 of core/lib/Drupal/Core/Cache/VariationCache.php)

[PP-1] Introduce a StatementBase abstract class

$
0
0

Problem/Motivation

Introduce an abstract StatementBase class, common to both StatementWrapperIterator and StatementPrefetchIterator classes.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Views UI sometimes fails to set overridden display to "All displays"

$
0
0

Problem/Motivation

When trying to set part of an overridden display's configuration, the user ends up with broken configuration.

Steps to reproduce:

  1. Create a view with a display (A) with overridden filters
  2. Save
  3. Edit the view to make A's filters the default filters, e.g. via "Rearrange filters" dialog (ie on the Rearrange Filters dialog, select 'All Displays' in the For option.)
  4. Notice that A's filters have changed, instead of the default display's

Expected result:
Display A's filters are set as default. Display A no longer uses overridden filters.

Actual result:
Display A uses the filters of the default display. Display A no longer uses overridden filters.

This means, that upon saving the view, A's filters are lost irreversibly.
If both the default and the overridden display used filters of the same names, this will be hard to spot and lead to confusion and possibly errors later on, as filter values are changed behind the scenes. If A used additional filters, these will all be changed to "Broken handler".

The "Use as default" behavior effectively duplicates the "Revert to default" behavior, with the added bonus of unexpectedly altering the view. This broken behavior has been around for quite a while, and also happened in D7 (see https://www.drupal.org/node/2313791).

Proposed resolution

Upon closer inspection, it seems that views_ui never actually passes the display's configuration to the default display, even though the code comments state it does. So we have to properly implement this de-override behavior.

Remaining tasks

Write tests to reproduce, review suggested patch.

Require dedicated permission(s) to set aliases pointing to existing or reserved paths

$
0
0

Problem/Motivation

In Drupal 8 and earlier, it is possible for a user to create a path alias that clobbers an essential core route such as "admin" or "user/login". For example, a malicious user with permission to create content using an unfiltered text format and to "Create and edit URL aliases" could override the "user/login" path with a node crafted to look like it but with an HTML form that posted the submission to another URL that harvested the login credentials. Of course less serious abuses can be easily imagined, such as merely rendering certain admin pages inaccessible.

Proposed resolution

  • Adds a setting for restricted path alias patterns
  • Adds a validation constraint to enforce it
  • Adds a permission to bypass it that admins can use

Remaining tasks

  • Decide if this is a bug or a task, the presence of new API makes me think its a task
  • Reroll the patch at #67 as an MR
  • Document the new setting in default.settings.php
  • Add test coverage
  • Review
  • Commit

User interface changes

None

API changes

New validation constraint and permission

Release notes snippet

Todo

[PP-1] Validate alternate domain for oEmbed iFrame

$
0
0

Problem/Motivation

This is issue is spun off from UX team feedback on #2831944-203: Implement media source plugin for remote video via oEmbed.

For security reasons, the oEmbed system uses an iframe to serve content from a third-party oEmbed provider. By default. the iframe is served from the same domain as the main Drupal site, but this is not secure. Therefore, Media introduced a setting, exposed in a configuration form, which allows site builders/admins to set up an alternate domain from which to serve the iframe.

In order to serve oEmbed content more securely, the iFrame domain needs to point to the Drupal site. This is explained on the form, but not validated in any way.

Proposed resolution

It would be nice to add some sort of validation to ensure that the iFrame domain is actually pointing to the Drupal site, because if it isn't, then almost all oEmbed content on the site will break (404 errors or worse), which scare the pants off of our users.

Remaining tasks

  1. Discuss if we should even do this, and if so, how to do it in a way that will please the security team.
  2. Write a patch
  3. Review it until we're all sick of looking at it
  4. Commit it

User interface changes

TBD, but probably none.

API changes

TBD, but probably minimal or none.

Data model changes

None anticipated.


Add a cache prewarm API

$
0
0

Problem/Motivation

After a full cache clear, Drupal has to build up various caches before it can serve a request. Element info, route preloading, menu links, library info, various plugin registries, theme registry, twig templates, CSS assets (#1014086: Stampedes and cold cache performance issues with css/js aggregation) etc.

This both takes a long time, and massively increases the memory usage of a request.

Steps to reproduce

drush cr, load a heavy-ish page, watch that spinny wheel / check mem_get_usage()

Proposed resolution

PHP 8.1 adds Fibers https://php.watch/versions/8.1/fibers / https://wiki.php.net/rfc/fibers

In DrupalKernel::handle(), execute HttpKernerl::handleRequest()in a fiber. This allows any code, anywhere in core, to suspend itself using Fiber::suspend(), the place we suspend is for now after entering lock wait or getting a cache miss in particular services - this should only be done for cache items that are used to build most pages - plugins and registries, but not render caching or anywhere like that. But it could also be after executing an async query once we have a database driver that supports it.

At the same time, services can tag themselves using the cache_prewarmable service tag and implement PreWarmableInterface. This is not mutually exclusive with calling suspend on a cache miss, some services can do both.

When a fiber has suspended, DrupalKernel is then able to call the cache_prewarmer service, which gets a list of tagged service IDs. It calls the ::prewarm() method of one of these services at random, then resumes the original fiber and the request continues as normal. The prewarm method will usually just call a different method on the service, this needs to be one that both checks and sets the cache - we always want to assume it might have been set before we got there.

If the fiber gets suspended again later in the request, we'll go back to the cache prewarmer service and pick a different one.

This is complementary to #3377570: Add PHP Fibers support to BigPipe and in general is designed to speed up the part of request handling that precedes having bigpipe placeholders to render, but since different pages hit different caches at different times, sometimes the 'same' Fiber::suspend() call will result in going back to DrupalKernel and warming a cache, sometimes it will result in moving onto a different BigPipe placheholder. This is fine and by design, the code inside the fiber doesn't care what happens in between suspending itself and being resumed, it's just anticipating that something might be able to happen and then bigpipe and the prewarmer service take care of what that 'something' is.

The big advantage of Fibers is that as long as the code executing a fiber handles them correctly, and as long as the code that might be executing inside a fiber checks its inside a fiber first before suspending, they don't need to know anything about each other at all. The 'parent' starts and resumes, and the 'child' suspends, and it doesn't need to be any more entangled than that.

Here's a very simplified visual indication of what stampedes look like in terms of service cache get misses, building, and setting:

Each letter represents a service.
Aget (cache get)
A-set (build and cache set).

Extra hyphens means a longer period of time building the cache item.

C and D are nested services with one calling the other, equivalent to the views examples above. When C is warm, D doesn't get requested.

When we have one request, it just builds each service sequentially.

AgetA-set[NO-PRE-WARMING-]BgetB--------setCgetDgetD-setC--setEgetE----setFget-Fset

In HEAD, when we get a stampede. All the requests build and set each cache sequentially. The requests with Z and F at the end represent different pages (node vs. front vs. user or whatever), which may have different caches to build.

[NO-PRE-WARMING-] is a space filler because suspend and resume take up space on the line..

[NO-PRE-WARMING-]
[SUSPEND][RESUME]
<code>
AgetA-set[NO-PRE-WARMING-]BgetB--------setCgetDgetD-setC--setEgetE----setFgetF-set
AgetA-set[NO-PRE-WARMING-]BgetB--------setCgetDgetD-setC--setEgetE----setFgetF-set
AgetA-set[NO-PRE-WARMING-]BgetB--------setCgetDgetD-setC--setEgetE----setFgetF-set
AgetA-set[NO-PRE-WARMING-]BgetB--------setCgetDgetD-setC--setEgetE----setZgetZ-set
AgetA-set[NO-PRE-WARMING-]BgetB--------setCgetDgetD-setC--setEgetE----setZgetZ-set

With the patch, if we get two requests at the same time, we start to see a benefit (without any async):

AgetA-set[SUSPEND]BgetB--------set[RESUME]BgetCgetDgetC--setEgetFgetF-set
AgetA-set[SUSPEND]DgetD-set[RESUME]BgetCgetDgetC--setEgetE---setFgetF-set

Now with five requests, it's making much more difference:

AgetA-set[SUSPEND]BgetB--------set[RESUME]BgetCgetEgetZget
AgetA-set[SUSPEND]FgetF-set[RESUME]BgetCgetEgetZgetZ-set
AgetA-set[SUSPEND]FgetF-set[RESUME]BgetCgetEgetFget
AgetA-set[SUSPEND]CgetDgetD-setC--Set[RESUME]CgetEgetFget
AgetA-set[SUSPEND]EgetE---set[RESUME]BgetCgetEgetFget

Note also that because B and D take different amounts of time, in this case even though Z isn't prewarmed, the two requests that need it get there at different times, so only one builds it and the other gets a cache hit - this is an effect of the offsetting/shuffling that the prewarmer does. Say one prewarmable cache takes 800ms to build and the other takes 8ms, the one that's done with prewarming after 8ms will get a lot more done before the 800ms prewarming is finished.

Remaining tasks

Once there are enough prewarmable services defined, we should be able to manually test this by clearing the cache then using ab -n1 -c10, probably with the standard profile, to see if there's a measurable performance improvement.

Once the API is in core, we can potentially add full async cache prewarming support to drush. I think drush could then build all the prewarmable caches at the same time immediately after a cache clear.
https://github.com/drush-ops/drush/issues/5724

User interface changes

API changes

Adds PreWarmableInterface

Data model changes

Release notes snippet

Create hook_requirements_check

$
0
0

Problem/Motivation

Hook requirements uses phase right now to manage whether it is runtime, install, or update.

This leads to significant complexity. As it stands runtime and update can easily be an OOP hook.

Let's create a new hook_requirements_check to combine update and runtime.
We will also create a hook_requirements_check_alter.

Steps to reproduce

N/A

Proposed resolution

Create hook_requirements_check
Create hook_requirements_check_alter

Invoke hook_requirements_check after hook_requirements during runtime and update.
Merge results
Run hook_requirements_check_alter after hook_requirements_alter during runtime and update.

Remaining tasks

N/A

User interface changes

N/A

Introduced terminology

hook_requirements_check
hook_requirements_check_alter

API changes

hook_requirements_check
hook_requirements_check
Can be implemented to provide or alter requirements on status report.
Can be implemented to provide or alter requirements before updating.

Data model changes

Release notes snippet

New non translatable field on translatable content throws error

$
0
0

Problem/Motivation

Even when access is denied to a widget, the value submitted propagates to the entity built from the sum of widgets.

Steps to reproduce

  1. Enable at least content translation and content moderation modules and some entity providing module, node is typical.
  2. Set Hide non translatable fields on translation forms on the content translation admin form.
  3. Create an entity.
  4. Now add a nontranslatable field with a non-null default value.
  5. Try to add a non-default revision translation of the entity.
  6. Kaboom courtesy of EntityUntranslatableFieldsConstraint as the non-null value changes to the default. (error message "Non-translatable fields can only be changed when updating the original language.")

Proposed resolution

Don't let widgets pass their values when access is denied to them.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Original report by pavlosdan

We use *Paragraphs + Content Moderation + Translations*. We have a lot of content that is moderated and translated. We've added a new field in one of the paragraphs that did not need to be translatable (it's a checkbox that should be the same across translations) but we noticed that if a user attempts to edit existing published translated content holding said paragraph type prior to the original having a value for that field then the system throws a "Non translatable fields can only be changed when updating the current revision" error.

So far the only workarounds we could think of was to make the field translatable even though it didn't need to be.

Another possibility would be to remove the constraint as suggested here: https://www.drupal.org/project/drupal/issues/2955321#comment-12541730 but we didn't test this.

Your thoughts on this would be greatly appreciated. :)

Create hook_update_requirements

$
0
0

Problem/Motivation

Hook requirements uses phase right now to manage whether it is runtime, install, or update.
Let's move the update portion.

Create a new hook_update_requirements.

It is currently invoked in update.inc

function update_check_requirements() {
  // Because this is one of the earliest points in the update process,
  // detect and fix missing schema versions for modules here to ensure
  // it runs on all update code paths.
  _update_fix_missing_schema();

  // Check requirements of all loaded modules.
  $requirements = \Drupal::moduleHandler()->invokeAll('requirements', ['update']);
  \Drupal::moduleHandler()->alter('requirements', $requirements);
  $requirements += update_system_schema_requirements();
  return $requirements;
}

Steps to reproduce

N/A

Proposed resolution

Create hook_update_requirements
Create hook_update_requirements_alter

Invoke hook_update_requirements after hook_requirements
Merge results
Run hook_requirements_alter
Run hook_update_requirements_alter

Remaining tasks

N/A

User interface changes

N/A

Introduced terminology

hook_update_requirements
hook_update_requirements_alter

API changes

hook_update_requirements
hook_update_requirements_alter
Can be implemented to set or alter requirements during update.

Data model changes

N/A

Release notes snippet

Create hook_runtime_requirements

$
0
0

Problem/Motivation

Hook requirements uses phase right now to manage whether it is runtime, install, or update.

This leads to significant complexity. As it stands hook_runtime can easily be an OOP hook.

Let's create a new hook_runtime_requirements so we can start moving those.

Steps to reproduce

N/A

Proposed resolution

Create hook_runtime_requirements
Create hook_runtime_requirements_alter

Invoke hook_runtime_requirements after hook_requirements
Merge results
Run hook_requirements_alter
Run hook_runtime_requirements_alter

Remaining tasks

N/A

User interface changes

N/A

Introduced terminology

hook_runtime_requirements
hook_runtime_requirements_alter

API changes

hook_runtime_requirements
hook_runtime_requirements_alter
Can be implemented to provide our alter requirements on status report.

Data model changes

Release notes snippet

Viewing all 295251 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>