Access Computed Field in Views

Created on 20 March 2023, over 1 year ago
Updated 28 June 2023, about 1 year ago

I know this was talked about in another issue, but I wanted to make a separate post because it wasn't actually related to that issue and others might be looking as well.

I looked into the patch discussed at 📌 Allow adding computed bundle fields in Views Fixed but it's very confusing if any of that will work on a 9.5.x site. Is there a way to get the Computed Field to be used in Views? I tried a test using the example test plugins and what I read in the README, but it didn't work.

💬 Support request
Status

Active

Version

4.0

Component

Code

Created by

🇺🇸United States wxman

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

Comments & Activities

  • Issue created by @wxman
  • 🇬🇧United Kingdom joachim

    📌 Allow adding computed bundle fields in Views Fixed would allow bundle fields to be output. Base fields apparently already can be output.

    However, currently no kind of computed field is picked up automatically by Views data.

    I'm pondering how best to fix this.

    Probably a core patch for base fields & module code for bundle fields.

  • 🇬🇧United Kingdom joachim

    I've made a core patch that declares base computed fields to views: 📌 Automatically declare computed base fields to Views Needs work .

  • 🇺🇸United States wxman

    joachim - I checked on #3 and am I missing seeing the patch? I don't have a lot of experience with core patches so maybe I'm just missing it?

  • 🇬🇧United Kingdom joachim

    It's a merge request rather than a patch.

  • 🇬🇧United Kingdom joachim

    I can report that computed fields added in the UI work fine with the patch from 📌 Allow adding computed bundle fields in Views Fixed -- though you need to declare them in code as well.

  • 🇺🇸United States wxman

    @joachim I have set up two test sites, one running D9.x and the other 10.x. The 9.x site I installed Version: 4.0.0-alpha3 of Computed Field, and it's working as designed, except for not being accessible in Views.
    I have applied patch: https://git.drupalcode.org/project/drupal/-/merge_requests/2511.patch.
    Above you say "-- though you need to declare them in code as well". Where do I declare the field in code? If I figure that out is that going to make it able to be used in Views?

  • 🇺🇸United States wxman

    Do I add that to a new custom module, or to the custom module I made at /web/modules/custom/buy_amazon?
    /web/modules/custom/buy_amazon/src/Plugin/ComputedField/Computedbuyamazon.php

  • 🇬🇧United Kingdom joachim

    It makes sense to put it in the same module as your computed field plugin, as both are required to make the field work.

  • 🇺🇸United States wxman

    I guess I'm going to have to wait till it gets fixed in Views. No matter what I try it still will not show in my View.

  • 🇦🇹Austria maxilein

    I could not wrap my head around building a plugin. Since I needed a solution a went back to a more traditional approach:

    1. create a core field

    2. create code in mmodule_ ...

    mymodule_node_presave($entity) {
     switch ($entity->bundle()) {
        // Here you modify only your day content type
        case 'entity_machine_name':
            if (!empty($entity->field_name->value)) {
                       ... do some custom calculation stuff 
    
    

    3. Make the field readonly in the form edit using Readonly Field Widget →

    It is not as elegant as computed_field, but to me it was less time consuming, because I just did not comprehend the requirements and options for a plugin.

  • 🇬🇧United Kingdom joachim

    > I just did not comprehend the requirements and options for a plugin.

    Could you explain more about the problem in a separate issue please? The plugins for computed fields are really pretty simply as plugins go, and there are examples in the module to draw from.

  • 🇦🇹Austria maxilein

    That is not a problem only of this module. It is a fundamental problem of Drupal. That's why I try to help with explanations wherever I can.
    It may be pretty obvious for someone who programs Drupal for years. I could not get a proper article that leads me step by step. The explanations are extremely short.

    I try to avoid customizations, for easier upgrades. I do not want to read the source code in order to understand the basic purpose or principle of a module. At least not until I decided that a module could fit my purpose.

    In this case: if I have to do coding anyway, why shouldn't I do in a way that seems less complex?
    No offense!

  • 🇬🇧United Kingdom joachim

    I really REALLY suggest you all use Module Builder. It will generate the plugin class for you.

  • 🇦🇹Austria maxilein

    joachim, please don't get me wrong. You are outstanding in all your efforts! And documenting much better than most of Drupal developers!

  • 🇬🇧United Kingdom joachim

    Thanks! :)

    I've started some docs - https://www.drupal.org/docs/extending-drupal/contributed-modules/contrib... →

    Incomplete, but will add to them when I have time.

  • 🇺🇸United States wxman

    Here is the module I made to go with my "computed_buy_amazon" computer field. It's at: buy_amazon\src\Plugin\ComputedField\ComputedField.php

    namespace Drupal\buy_amazon\Plugin\ComputedField;
    
    use Drupal\Component\Datetime\TimeInterface;
    use Drupal\computed_field\Field\ComputedFieldDefinitionWithValuePluginInterface;
    use Drupal\computed_field\Plugin\ComputedField\ComputedFieldBase;
    use Drupal\Core\Cache\CacheableMetadata;
    use Drupal\Core\Entity\EntityInterface;
    use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
    use Symfony\Component\DependencyInjection\ContainerInterface;
    
    /**
     * @ComputedField(
     *   id = "buy_amazon_computedbuyamazon",
     *   label = @Translation("Computed buy Amazon"),
     *   field_type = "text",
     *   attach = {
     *     "scope" = "base",
     *     "field_name" = "buy_amazon_computedbuyamazon",
     *     "entity_types" = {
     *       "entity_test" = {},
     *     },
     *   }
     * )
     */
    class Computedbuyamazon extends ComputedFieldBase {
    
      /**
       * {@inheritdoc}
       */
      public function ComputeValue(EntityInterface $host_entity, ComputedFieldDefinitionWithValuePluginInterface $computed_field_definition): array {
    	if(!empty($host_entity->field_isbn10->value)) {
    		$ISBN = $host_entity->field_isbn10->value;
    	}else{
    		if(!empty($host_entity->field_amazon_asin->value)) {
    			$ISBN = $host_entity->field_amazon_asin->value;
    		}else{
    			$ISBN = '';
    		}
    	}
    	if(!empty($ISBN)) {
    		$value = '<a href="http://www.amazon.com/gp/product/'.$ISBN.'" alt="" style="border:none !important; margin:0px !important;" />';
            return [
                0 => [
                'value' => $value,
                'format' => 'full_html',
                ],
            ];    
    	}
      }
    
    }
    

    I'm guessing it's somewhere in here I need to add a hook to make it seen in Views? I tried following the Drupal site information but nothing worked.

  • 🇬🇧United Kingdom joachim

    No, the hook goes in the .module file.

    Again, again - USE MODULE BUILDER. It will put all the things in the right places for you.

    BTW, I don't think this will work:

    > if(!empty($host_entity->field_isbn10->value)) {

    IIRC you need to use $entity->field->isEmpty()

  • 🇬🇧United Kingdom joachim

    An example of how to declare the field to Views in hook_views_data(), from my comment on 📌 Allow adding computed bundle fields in Views Fixed :

      $data['node_field_data']['test_2981047_base'] = [
        'title' => t('Test computed base field 2981047'),
        'entity field' => 'test_2981047_base',
        'field' => [
          'id' => 'field',
        ],
      ];
    
      $data['node_field_data']['test_2981047_bundle'] = [
        'title' => t('Test computed bundle field 2981047'),
        'entity field' => 'test_2981047_bundle',
        'field' => [
          'id' => 'field',
        ],
      ];
    
  • 🇬🇧United Kingdom joachim
     *     "entity_types" = {
     *       "entity_test" = {},
     *     },
    

    Do you actually want to attach this field to the 'entity_test' entity type?

  • 🇮🇹Italy MarcoPBazz

    An example of how to declare the field to Views in hook_views_data(), from my comment on #2981047: Allow adding computed bundle fields in Views:

    It's working form me (Drupal 9.5x + computed 4.0.0-alpha2) as I can show my computed field, but if I try to filter but I get "missing or broken handler for this element" as message.

    Here's my code in my .views.inc file

    function mymodule_views_data_alter(&$data) {
    
      $data['node_field_data']['myfield'] = [
        'title' => 'Myfield title',
        'entity field' => 'myfield',
        'field' => [
          'id' => 'field',
        ],
        'filter' => [
          'title' => t('Myfield title'),
          'field' => 'id',
          'id' => 'myfield',
        ],
      ];
    
    }

    What am I missing?

  • 🇬🇧United Kingdom joachim

    You can't filter by a computed field, as there is no data in the database for SQL to query.

Production build 0.69.0 2024