Upgrading to CTools 3.10.0 and/or various Symfony upgrades can break the simple task of adding content on your Drupal site.
Drupal\Component\Plugin\Exception\ContextException: The context is not a valid context. in Drupal\Core\Executable\ExecutablePluginBase->getContextDefinition() (line 184 …
Update: Seems confirmed this is CTools, see critical bug issue.
And this fixed it:
git revert 0fbbbaf [main 7be1cd2] Revert fatal error standard code update "Update composer lock" 1 file changed, 163 insertions(+), 220 deletions(-) saharareporters [main]$ dco install # that is, composer install - dco is my alias for ddev composer Gathering patches for root package. Installing dependencies from lock file (including require-dev) Verifying lock file contents can be installed on current platform. Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. It is recommended that you run `composer update` or `composer update <package name>`. Package operations: 0 installs, 27 updates, 1 removal - Removing drupal/entityqueue (1.2.0) Deleting web/modules/contrib/entityqueue - deleted Gathering patches for root package. Gathering patches for dependencies. This might take a minute. - Downgrading drupal/core-composer-scaffold (9.4.4 => 9.4.3): Extracting archive - Downgrading symfony/yaml (v4.4.44 => v4.4.43): Extracting archive - Downgrading symfony/translation (v4.4.44 => v4.4.41): Extracting archive - Downgrading symfony/event-dispatcher (v4.4.44 => v4.4.42): Extracting archive - Downgrading symfony/dependency-injection (v4.4.44 => v4.4.43): Extracting archive - Downgrading symfony/console (v4.4.44 => v4.4.43): Extracting archive - Downgrading symfony/filesystem (v5.4.11 => v5.4.9): Extracting archive - Downgrading symfony/config (v4.4.44 => v4.4.42): Extracting archive - Downgrading symfony/css-selector (v5.4.11 => v5.4.3): Extracting archive - Downgrading symfony/dom-crawler (v4.4.44 => v4.4.42): Extracting archive - Downgrading symfony/browser-kit (v4.4.44 => v4.4.37): Extracting archive - Downgrading symfony/finder (v6.1.3 => v6.1.0): Extracting archive - Downgrading symfony/validator (v4.4.44 => v4.4.43): Extracting archive - Downgrading symfony/serializer (v4.4.44 => v4.4.43): Extracting archive - Downgrading symfony/routing (v4.4.44 => v4.4.41): Extracting archive - Downgrading symfony/mime (v5.4.11 => v5.4.10): Extracting archive - Downgrading symfony/http-foundation (v4.4.44 => v4.4.43): Extracting archive - Downgrading symfony/process (v4.4.44 => v4.4.41): Extracting archive - Downgrading symfony/var-dumper (v5.4.11 => v5.4.9): Extracting archive - Downgrading symfony/debug (v4.4.44 => v4.4.41): Extracting archive - Downgrading symfony/error-handler (v4.4.44 => v4.4.41): Extracting archive - Downgrading symfony/http-kernel (v4.4.44 => v4.4.43): Extracting archive - Downgrading drupal/migmag (1.8.1 => 1.8.0): Extracting archive - Downgrading symfony/string (v6.1.3 => v6.1.2): Extracting archive - Downgrading drupal/noreferrer (1.14.0 => 1.13.0): Extracting archive - Downgrading drupal/ctools (3.10.0 => 3.9.0): Extracting archive - Downgrading symfony/mailer (v5.4.11 => v5.4.10): Extracting archive
And a drush cache-reload, of course.
Full error, for search engines:
The website encountered an unexpected error. Please try again later.
Drupal\Component\Plugin\Exception\ContextException: The context is not a valid context. in Drupal\Core\Executable\ExecutablePluginBase->getContextDefinition() (line 184 of core/lib/Drupal/Core/Plugin/ContextAwarePluginTrait.php).
Drupal\Core\Executable\ExecutablePluginBase->getContext(NULL) (Line: 116)
Drupal\Core\Executable\ExecutablePluginBase->getContextValue(NULL) (Line: 91)
Drupal\Core\Entity\Plugin\Condition\EntityBundle->evaluate() (Line: 77)
Drupal\Core\Condition\ConditionManager->execute(Object) (Line: 84)
Drupal\Core\Condition\ConditionPluginBase->execute() (Line: 376)
Drupal\pathauto\Entity\PathautoPattern->applies(Object) (Line: 320)
Drupal\pathauto\PathautoGenerator->getPatternByEntity(Object) (Line: 41)
Drupal\pathauto\PathautoWidget->formElement(Object, 0, Array, Array, Object) (Line: 353)
Drupal\Core\Field\WidgetBase->formSingleElement(Object, 0, Array, Array, Object) (Line: 220)
Drupal\Core\Field\WidgetBase->formMultipleElements(Object, Array, Object) (Line: 111)
Drupal\Core\Field\WidgetBase->form(Object, Array, Object) (Line: 181)
Drupal\Core\Entity\Entity\EntityFormDisplay->buildForm(Object, Array, Object) (Line: 121)
Drupal\Core\Entity\ContentEntityForm->form(Array, Object) (Line: 127)
Drupal\node\NodeForm->form(Array, Object) (Line: 106)
Drupal\Core\Entity\EntityForm->buildForm(Array, Object)
call_user_func_array(Array, Array) (Line: 531)
Drupal\Core\Form\FormBuilder->retrieveForm('node_article_form', Object) (Line: 278)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 97)
Drupal\autosave_form\Form\AutosaveFormBuilder->buildForm(Object, Object) (Line: 73)
Drupal\Core\Controller\FormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 564)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 709)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
The program for DrupalCon is evolving constantly. Among the changes for Nashville 2018 new tracks have been added and some have been merged. That is the case for the Symfony and PHP tracks.
Many topics clearly belong to a single track, but others could fit in more than one. When we had a dedicated Symfony track a session about Twig could be submitted to the Symfony or front end tracks. A session about Drupal Console could be submitted to the Symfony, the PHP, or back end tracks. In an effort to reduce confusion in the call for proposal process, the track team has agreed on the following:
Undoubtedly Symfony plays a key role in Drupal. Symfony 4 has just been released and it would be great to learn about what the future looks like. We want to learn about what is new in the latest version and what benefits adopting it would bring. We are also interested in sessions that would allow developers to learn from each other. What does a Symfony developer need to know to write Drupal code? What does a Drupal developer needs to know about Symfony to become a better developer? In other words - how to make proper use of Symfony components and related best practices.
Other session ideas include best practices on using Composer, PHPUnit, and third party libraries; new features in PHP 7; functional, asynchronous, and reactive programming; machine learning; micro services; etc.
If you want to attend DrupalCon Nashville, but the cost of attending is too high there are some ways to reduce the expenses:
The track team for DrupalCon Nashville 2018 is here to help you during the session submission process. We can help review proposals, suggest topics, and clear any doubt you might have. For the PHP track, Chad Hester, Tim Millwood, and myself are ready to help.
For people who have not presented before and for those of underrepresented groups, the Drupal Diversity and Inclusion Initiative has created a channel in Slack to help them with the proposal project. Mentoring is available at drupal.org/slack

LibrePlanet is an annual conference hosted by the Free Software Foundation for free software enthusiasts and anyone who cares about the intersection of technology and social justice. We've attended and spoken at LibrePlanet many times over the year. This year's theme is "Trailblazing Free Software" and in that spirit Micky is speaking on the Orwellian future that has arrived and what tech justice movements we should be supporting and joining to fight for a freedom-loving, solidarity-based future.
LibrePlanet Keynote: How can we prevent the Orwellian 1984 digital world?
Sunday, March 24th
5:15pm-6:00pm
Stata Center, Massachusetts Institute of Technology Room 32-123
Cambridge, MA
We are living in a society where -- as mere individuals -- it seems out of our control and in the hands of those who have the power to publish and distribute information swiftly and widely, or who can refuse to publish or distribute information. Algorithms now sort us into Global databases like PRISM or ECHELON, and there are devices such as StingRay cell phone trackers used to categorize our every movement. We may build our own profiles online, but we do not have access to the meta-profile built by the corporate entities that our queries traverse as we navigate online, purchasing goods and services as well as logging into sites where we have accounts. The level of intrusion into our most private thoughts should be alarming, yet most fail to heed the call as they feel small, alone, and unable to defy the scrutiny of disapproval from the powers that govern societal norms and their peers. Together, we can change this.
Micky will engage your mind on a journey to open an ongoing discussion to rediscover and reawaken your own creative thought processes. Together, we build a conversation that should never end as it will join us together transparently maintaining our freedoms, with free software as the foundation. Where do we find our personal power, and how do we use it as developers? Do we have a collective goal? Have you checked your social credit rating lately? Others have.
Portside’s advantage is a large moderator team. They have 20 dedicated volunteers who scour the web for the best reporting happening on the left. The technical background of the team spans the spectrum. It was imperative that we develop an authoring experience that was simple for anyone to use, without sacrificing functionality.
Building off the improved authoring experience offered by modern Drupal (beginning with Drupal 8), we tested the pasting of content from common sites Portside republishes, ensuring the various markup coming in from other sources had sensible tag and style removal rules in Drupal's text formatting so that articles display nicely within Portside.
When using dated software, we become adept at workarounds. An infamous one for Portside moderators was embedding tweets. Their old system did not support Twitter embed codes. The workaround was to take screenshots of tweets and link the image to the original tweet. We used the Media Entity Twitter module in concert with Drupal Core’s Media module to enable editors to seamlessly embed tweets in their articles. Goodbye workarounds.
One thing that did work well on their Drupal 7 site was embedding YouTube and Vimeo videos. With the WYSIWYG Media Embed module they simply needed to paste the url into their article and it would display properly. Unfortunately there was no Drupal 8 version of this module. So we helped port the WYSIWYG Media Embed module from Drupal 7 to Drupal 8. Now authors can easily embed videos from YouTube and Vimeo.
CKEditor allows for the defining of custom styles that authors can choose to apply to text. This was helpful for authors who aren’t as versed in HTML. Authors can now style text with terminology meaningful to them, but that uses semantically correct HTML under the hood.
We added custom style options to the WYSIWYG editor so moderators can style content using terms familiar to them, but producing standards-compliant HTML and CSS.
To further save editors’ time, we looked for ways to automate tasks. We identified three areas: publishing posts at a set time, easy posting to social media platforms, automated posting to listservs.
Portside publishes their articles each day at 8pm Eastern. This gives authors a grace period to fix any issues with their article before it publishes. We programmed this into the site so that when an author creates an article they can either save it as a draft, or save it as an article ready for publishing. Each day at 8pm Eastern Time articles in the Draft state remain so, while Articles in the Ready state are published.
Portside subscribers can stay current with content in several ways:
We built an integration between the website and their listserv software, Listserv, so that when an article is published it is sent to the appropriate listservs. For Portside Snapshot, all articles published on the previous day is aggregated into an email template and sent out.
With automation there is always the risk of human error. We built in safeguards for foreseeable mistakes. Each article is held in a queue which awaits moderator approval before being sent out. Also, if an article is published with an issue, an author can fix the mistake and then resend the article to the listserv. The moderator can then dismiss the first article with the error and accept the follow up corrected article to be sent out.
Moderators can resend an article to the listserv queue when they've made an update.
We streamlined their workflow further by equipping authors to post articles to Facebook and Twitter during the authoring process.
We did this by contributing to the Drupal Social Initiative, a working group harmonizing social networking functionality in Drupal. By making it easy for authors to post content from their website to social media platforms we intend to combat the disturbing trend of more and more content living behind walled gardens, a threat to the Open Web. Offering seamless “post to” workflows allows authors to keep control of their content while easily promoting it to their followers on social media platforms.
The Social Post Facebook and Social Post Twitter add a configuration page for users to link their website account with their respective social media accounts. Content published by a user is then automatically posted to their respective social media accounts.
For Portside, we took this one step further by adding a text field on the article content entry form. This field allows authors to enter the text they wish to post accompanying a link to the content they are publishing.
When moderators include text in the social media fields the article is automatically posted to Facebook and/or Twitter.
Twenty editors posting to the site, site visitors suggesting articles to be posted, multiple articles in draft while others are ready but yet to be published— there is a constant flurry of activity on portside.org; enough to make your head spin. Editors needed a dashboard to easily keep track of everything.
We enhanced Drupal’s default administrative page for content to show the article’s custom workflow state and the Portside Date (the date an article is set to be published). To help editors focus just on articles yet to be published we created a Moderated Content page and for articles queued up to be published they now have a Scheduled page.
We customized Drupal's default administrative content page to show the moderation state each article is in.
A custom administrative page shows which articles have yet to be published, but are scheduled to be.
A backlink analysis showed the World Wide Web had thousands of inbound links to Portside's internal pages (that is, pages other than the home page). Breaking these links or redirecting them to unrelated content would have profoundly damaged portside.org's ranking in search engines.
Tens of thousand more links to articles on the Portside website undoubtedly live in semi-private social networks (including Facebook), organization group chats (including Slack instances), browser bookmarks, notes, direct message chat, and e-mails that we cannot know about. Furthermore, Portside has sent tens of thousands of e-mails to their tens of thousands of subscribers including many links to portside.org that needed to be preserved.
Both public web links and these 'offline' links (the source of much of the traffic classified as 'direct' or 'no referrer' in web analytics software) are providing value to the people who use them, and removing that value would negatively affect people who may be significant stakeholders (journalists, researchers, potential partners, and others).
For this reason, it was imperative we migrate all of Portside's content (and probably yours too). Our migration of Portside from Drupal 7 to modern Drupal (Drupal 8 at the time, now Drupal 10) involved migrating more than ten thousand articles— though once we work out the kinks in the first twenty or one hundred of a given kind of content, the next thousand or hundred thousand usually import fine, and that was the case here. (All right, some of Portside's oldest content called for special tweaks to our migration scripts to handle an older way moderators had embedded images and videos.)
It is often enough throughout the journey of building websites that you will desire to create very specific lists of content. In my current endeavor, I am working in Drupal 9 with 2 content types: Office location and Event . Each Event occurs at an Office location, which is indicated by an Office location entity reference field on the Event. Note that any info in this blog will also be relevant to Drupal 8, Drupal 10, and beyond.
Here is the user story that we will be working through:
As a site visitor, when I view an Office location node, I should see a list of Events that are occurring at the location represented by the current node, so that I have an easy way to learn about events at locations relevant to me.
To keep this short and sweet, I am going to assume that you have already created a view. However, all views are not created equal, so if you are not seeing the options that you are looking for while editing your view, maybe try creating a new one. We will be working with a block display—other options are possible, but this is the standard "Drupal approach".
Once you are editing a block display for your view, open the Advanced dropdown on the right side. Here is what you will see:

Timeline of trainings
MASS Design Group is an innovative non-profit architecture firm that collaborates with the communities and individuals they serve. Their belief that “Architecture is never neutral. It either heals or hurts.” is a powerful parallel to our own assertion that digital architecture shapes how we communicate and congregate online.
We could also choose not to connect the final items with a comma, if we were ignoramuses unaware of the Oxford comma. In this case for our example we would see "By Clayton Dewey, Ben Melançon and David Valdez." We are aware, however, so we would enable the series comma option in the In Other Words formatter configuration.
Editor's note: The extreme partisanship in favor of the serial comma is all that Ben contributed to this blog post, but this same unreasoning fervor contributed to starting the module in the first place and creating a PHP package for making lists using the Oxford comma, which the module relies upon.
If we want text before or after, that is also an option. In this case, preceding the authors with "By " is a nice way to denote attribution.
It is worth noting, though, that In Other Words module can count! To display different preceding or following text if only one item is present, put the plural version first and then a | (pipe symbol) and the singular version. We could have configured the field display to hide the "Author(s)" label and configured the field format to have Text before of "Authors: |Author: " if we wanted to keep a more regimented style while including the nicety of precise labels. This feature can also be used for subject-verb agreement, "Jim and Steph are the authors" and "Steph is the author" could be achieved by configuring the Text after to be " are the authors| is the author". (This is a place where we could improve how intuitive the interface is, for sure.)