Add a ContextProvider for Feeds

Created on 12 August 2015, over 9 years ago
Updated 1 December 2023, about 1 year ago

This is a spin off of #2377757: Expose Block Context mapping in the UI β†’ (and depends on that issue in order to work, so "Postponed")

Problem/Motivation

Context is frequently used to pass an entity to a block, as this allows you to do cool things like (a) place a block that shows the feed for the entity currently being displayed, or (b) show the feed for a referenced entity, as well as just (c) showing the feed for a specifically selected entity.

Using configuration only allows you to do (c) but not (a) or (b).

0) Apply the patch from #2377757: Expose Block Context mapping in the UI β†’
1) Apply the latest patch
2) drush si
3) drush en aggregator
4) admin/config/services/aggregator
5) Add a feed to http://rss.cbc.ca/lineup/topstories.xml (Canada FTW)
6) admin/structure/block
7) Add the "Aggregator feed" block

Proposed resolution

Modify the aggregator block to use context rather than configuration.

Remaining tasks

  1. RTBC
  2. Get someone to commit it!

User interface changes

After installing Aggregator, we visit the block layout admin w/o creating a feed yet and we are treated to this:

If we attempt to configure this block without having created a Feed yet, we get this:

This is kind of ridiculous because there are no feeds, and we're placing a block that cannot even function yet. Once we create feeds we get:


for 1 feed and:


for N feeds respectively.

Summary of HEAD:

We have the ability to place aggregator feed blocks before they're useful. This can lead to misconfigured blocks that don't function.

After Patch:

Leveraging the context system brings some uniform benefits to the UI, first on the list is that before you've created any feed entities, the block layout system won't even give you the erroneous option of placing feed blocks:

After we've created feeds, the block system shows us that we can actually use the block:

If we've only created a single feed, the block doesn't prompt the user for unnecessary configuration, it knows there's only one possible feed to use, and it just auto-configures that single value:

Once multiple Feeds have been created, the user interface expands accordingly:

and

API changes

None.

πŸ“Œ Task
Status

Needs review

Version

2.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States dsnopek USA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MariaDB 10.3.22
    last update over 1 year ago
    149 pass
  • πŸ‡ΊπŸ‡ΈUnited States dcam

    I'm repurposing this issue. I believe that πŸ“Œ Convert the feed block into a view Postponed is the way forward for this module's blocks and I want to eliminate the block plugin. So I don't want to use some of the work that was done here. But the great thing is that we'll still need the ContextProvider that was written for Views blocks! So I rerolled that part of the patch and added a test.

    I thought about going ahead and changing the block plugin. But I don't want to worry about upgrading blocks given that they could be placed with Layout Builder or some other means. And I don't want to worry about backward compatibility for the proposed change either. Let's leave the plugin-generated blocks alone for now and only worry about BC when we add the view.

  • πŸ‡ΊπŸ‡ΈUnited States dcam

    I added the test trait with the eventual goal of moving more test helper functions into it. The functional tests have a lot of that in the base class, but there's nothing for kernel tests. I would have already started work on it, but the functional base class is heavily dependent on the frontpage view as a convenient RSS feed to test against. I haven't figured out a plan for replacing that yet.

  • Status changed to Postponed over 1 year ago
  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    I think we should postpone this on the views block
    The concern I have here is we're adding every feed as a context which on a site with a lot of feeds is a major performance issue.

    If we contrast this with how node works, there's a 'current node' context only, i.e. the current node being viewed.

    I'm not convinced using context in this way is the correct approach here.

    Consider e.g. Drupal.org's planet - it would have 100s of feeds loaded on every page load.

  • πŸ‡ΊπŸ‡ΈUnited States dcam

    @larowlan My expectation is that getAvailableContexts() which is the function that loads all feeds would only be called at configuration time. Then getRuntimeContexts() only loads the configured feeds. Am I mistaken about my assumptions and getAvailableContexts() gets called before getRuntimeContexts()?

    The intended use of this would be for the sake of replacing the existing Aggregator blocks which display single feeds. We need a way to people to be able to select which feed they want to display when they configure the block. For something like Drupal Planet or any situation where you're displaying Items from multiple feed sources, then using context wouldn't even be the most efficient way to build a block. A person would want to build a custom view and use standard Views filters on the fid value.

    Am I wrong about this?

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    I think that is how it is supposed to work, but I have a vague recollection of it not working that way in practice.

    At one point there were some places in core that called the wrong method. If that's since fixed then we might be ok.

    +++ b/src/ContextProvider/AggregatorFeedContext.php
    @@ -0,0 +1,59 @@
    +    $this->feedStorage = $entity_type_manager->getStorage('aggregator_feed');
    

    We shouldn't do this, accessing the storage handler in a constructor can cause data loss if done too early.

    We should inject the entity type manager as is, and get the storage handler in the actual methods.

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10
  • πŸ‡ΊπŸ‡ΈUnited States dcam

    Thanks for letting me know. I'm going to do some digging on my own to try and find out what happened.

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    \Drupal\layout_builder\Context\LayoutBuilderContextTrait::getPopulatedContexts is one point where all available contexts are requested at run time.

    This called when showing a list of blocks to display to a content editor in layout builder.

  • πŸ‡ΊπŸ‡ΈUnited States dcam

    @larowlan What do you think about doing a simple database query for all the Feed uuids and titles in getAvailableContexts() instead of loading the entities?

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    @dcam we shouldn't use DB queries for entities, we can use entity query though

    \Drupal::entityTypeManager()->getStorage('aggregator_feed')->getAggregateQuery()->groupBy('uuid')->groupBy('title')->execute();

    Should be able to use array_combine and array_column on that and get what you need

  • Status changed to Needs review over 1 year ago
  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MariaDB 10.3.22
    last update over 1 year ago
    159 pass
  • πŸ‡ΊπŸ‡ΈUnited States dcam

    > we shouldn't use DB queries for entities

    Yeah, I know. I think I once heard Crell say that if you're writing a DB query in D8+ then you're probably doing something wrong. And true to that I could probably count on one or two hands the number of queries I've written since 2015 aside from those in migration source plugins.

    I knew nothing about aggregate entity queries though, let alone that you can use them to return entity values. Thank you for showing me that. This updated context class still passes the test and works to allow me to select the feed when placing a Views block.

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MariaDB 10.3.22
    last update over 1 year ago
    159 pass
  • πŸ‡ΊπŸ‡ΈUnited States dcam

    We should inject the entity type manager as is, and get the storage handler in the actual methods.

    Sorry, I forgot to do that. Here's a new patch.

  • Merge request !10Add a ContextProvider for Feeds β†’ (Open) created by dcam
  • πŸ‡ΊπŸ‡ΈUnited States dcam

    I moved the latest patch into GitLab since Drupal CI testing has been shut off.

Production build 0.71.5 2024