0

I have a content type that has 3 term reference fields:

  • Field A, required, is a term reference using a vocabulary with machine name vocabulary_a.
  • Field B, required, is a term reference using a vocabulary with machine name vocabulary_b.
  • Field C, is a term reference using a vocabulary with machine name vocabulary_c and is generated automatically.

When creating or updating a node, values are entered for field A and B. I want to have a rule (using the Rules module) with some Rules Action to set a data value for field C, equal to the concatenation of the value entered for field A and B. Here is a picture of what I'm trying to achieve:

enter image description here

When I use a Rules Action of "Set a data value" (for field C), I can only refer to one value (eg the token from Field A), and not to the tokens from both Fields (A and B).

So how can I get this to work somehow?

Note that this is a followup to these prior questions (which are not duplicates ...):

So this question here is about (a) those 3 fields which each have their own taxonomy and (b) at the same time avoiding the duplicate terms to be created.

1
  • 1
    Comments are not for extended discussion; this conversation has been moved to chat.
    – Clive
    Dec 7, 2016 at 17:35

2 Answers 2

2

My previous answer is based on using Rules Event "View a node of content type Article".

However (as confirmed by OPer after I posted a comment about that, in a comment deleted by a moderator), I think it should be (1) When a node of that content type is created and also (2) When a node of that content type is updated. But (3) when a rules event like "View a node of that content type" happens, I think that should NOT trigger any Rules Action (because viewing should not change any of those values).

Here is a variation of the previous rule, which takes the above into account:

{ "rules_combine_taxonomy_terms_in_a_3rd_taxonomy_for_create_and_up" : {
    "LABEL" : "Combine taxonomy terms in a 3rd taxonomy for create and update",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "rules_conditional" ],
    "ON" : { "node_presave--article" : { "bundle" : "article" } },
    "DO" : [
      { "drupal_message" : { "message" : "Value of term for Field C has to be set to \u003Cstrong\u003E[node:field-a][node:field-b]\u003C\/strong\u003E, i.e. the combination of the value of Field A (= \u003Cstrong\u003E[node:field-a]\u003C\/strong\u003E) and the value of Field B (= \u003Cstrong\u003E[node:field-b]\u003C\/strong\u003E)." } },
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[node:field-a][node:field-b]" },
          "PROVIDE" : { "variable_added" : { "combined_term" : "Combined Term" } }
        }
      },
      { "entity_query" : {
          "USING" : {
            "type" : "taxonomy_term",
            "property" : "vocabulary",
            "value" : "vocabulary_c"
          },
          "PROVIDE" : { "entity_fetched" : { "existing_terms" : "Existing Terms" } }
        }
      },
      { "variable_add" : {
          "USING" : { "type" : "boolean", "value" : "0" },
          "PROVIDE" : { "variable_added" : { "new_term_exist" : "New term exists" } }
        }
      },
      { "LOOP" : {
          "USING" : { "list" : [ "existing-terms" ] },
          "ITEM" : { "current_term" : "Current term" },
          "DO" : [
            { "CONDITIONAL" : [
                {
                  "IF" : { "text_matches" : { "text" : [ "current-term:name" ], "match" : "[combined-term:value]" } },
                  "DO" : [
                    { "data_set" : { "data" : [ "new-term-exist" ], "value" : "1" } },
                    { "data_set" : { "data" : [ "node:field-c" ], "value" : [ "current-term" ] } },
                    { "drupal_message" : { "message" : "Term \u003Cstrong\u003E[node:field-a][node:field-b]\u003C\/strong\u003E already existed and will be used to automatically set the value for Field C to this term also." } }
                  ]
                }
              ]
            }
          ]
        }
      },
      { "CONDITIONAL" : [
          {
            "IF" : { "data_is" : { "data" : [ "new-term-exist" ], "value" : "0" } },
            "DO" : [
              { "entity_create" : {
                  "USING" : {
                    "type" : "taxonomy_term",
                    "param_name" : "[combined-term:value]",
                    "param_vocabulary" : "vocabulary_c"
                  },
                  "PROVIDE" : { "entity_created" : { "term_created" : "Created term" } }
                }
              },
              { "entity_save" : { "data" : [ "term-created" ], "immediate" : "1" } },
              { "data_set" : { "data" : [ "node:field-c" ], "value" : [ "term-created" ] } },
              { "drupal_message" : { "message" : "Term \u003Cstrong\u003E[node:field-a][node:field-b]\u003C\/strong\u003E did not yet exist and was created just now. It will be used to automatically set the value for Field C to this term also." } }
            ]
          }
        ]
      }
    ]
  }
}

To import it in your own site (using the Rules UI), use the same trick as in my prior answer.

The difference with my previous answer is (a) another Rules Event and (b) the messages that are simplified now.

Probably most important is that there is no more page refresh needed (you see the result right away).

Demo

Some messages that will be shown, depending on the scenario used:

  • Update an existing node, or create a new node, with a term for field C that already existed:

    Value of term for Field C has to be set to Term A6Term B1, i.e. the combination of the value of Field A (= Term A6) and the value of Field B (= Term B1).

    Term Term A6Term B1 already existed and will be used to automatically set the value for Field C to this term also.

  • Update an existing node, or create a new node, with a term for field C that did not yet exist:

    Value of term for Field C has to be set to Term A3Term B1, i.e. the combination of the value of Field A (= Term A3) and the value of Field B (= Term B1).

    Term Term A3Term B1 did not yet exist and was created just now. It will be used to automatically set the value for Field C to this term also.

Done ...

0

Below is a variation of the rule that I already posted in my answer in the related question. The Rules Event used in this answer, is (still) related to "when viewing content (of type article)", as was (also) the question in the related questions. In another answer, I'll add some details about not using this event, but some other event(s) instead (and a variation of this rule for that scenario). This rule here will display specific Drupal messages, to indicate what has happened, and what still needs to happen (to have Field C show the requested value).

In my own setup (where I QA-tested this ...) it's using 3 fields (as in the question here):

  • Field A, machine name field_a, a term reference using a vocabulary with machine name vocabulary_a, which has terms Term A1, Term A2 and Term A3.
  • Field B, machine name field_b, a term reference using a vocabulary with machine name vocabulary_b, which has terms Term B1, Term B2 and Term B3.
  • Field C, machine name field_c, a term reference using a vocabulary with machine name vocabulary_c.

But there are a few things about this rule to be aware off (more details on that below the rule). Here is my rule:

{ "rules_combine_taxonomy_terms_in_a_3rd_taxonomy" : {
    "LABEL" : "Combine taxonomy terms in a 3rd taxonomy",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "rules_conditional" ],
    "ON" : { "node_view--article" : { "bundle" : "article" } },
    "DO" : [
      { "drupal_message" : { "message" : "Value of term for Field C has to be set to \u003Cstrong\u003E[node:field-a][node:field-b]\u003C\/strong\u003E, i.e. the combination of the value of Field A (= \u003Cstrong\u003E[node:field-a]\u003C\/strong\u003E) and the value of Field B (= \u003Cstrong\u003E[node:field-b]\u003C\/strong\u003E). However the page is already rendered BEFORE subsequent Rules Actions will be executed. So to actually see the new value for Field C, an extra page refresh is needed." } },
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[node:field-a][node:field-b]" },
          "PROVIDE" : { "variable_added" : { "combined_term" : "Combined Term" } }
        }
      },
      { "entity_query" : {
          "USING" : {
            "type" : "taxonomy_term",
            "property" : "vocabulary",
            "value" : "vocabulary_c"
          },
          "PROVIDE" : { "entity_fetched" : { "existing_terms" : "Existing Terms" } }
        }
      },
      { "variable_add" : {
          "USING" : { "type" : "boolean", "value" : "0" },
          "PROVIDE" : { "variable_added" : { "new_term_exist" : "New term exists" } }
        }
      },
      { "LOOP" : {
          "USING" : { "list" : [ "existing-terms" ] },
          "ITEM" : { "current_term" : "Current term" },
          "DO" : [
            { "CONDITIONAL" : [
                {
                  "IF" : { "text_matches" : { "text" : [ "current-term:name" ], "match" : "[combined-term:value]" } },
                  "DO" : [
                    { "data_set" : { "data" : [ "new-term-exist" ], "value" : "1" } },
                    { "data_set" : { "data" : [ "node:field-c" ], "value" : [ "current-term" ] } },
                    { "drupal_message" : { "message" : "Term \u003Cstrong\u003E[node:field-a][node:field-b]\u003C\/strong\u003E already existed and will be used to automatically set the value for Field C to this term also ... But only \u003Cstrong\u003Enext time this node is viewed\u003C\/strong\u003E (as per the used Rules Event ...)!!! If you\u0027re in a hurry to see the new value for Field C, just refresh this page." } }
                  ]
                }
              ]
            }
          ]
        }
      },
      { "CONDITIONAL" : [
          {
            "IF" : { "data_is" : { "data" : [ "new-term-exist" ], "value" : "0" } },
            "DO" : [
              { "entity_create" : {
                  "USING" : {
                    "type" : "taxonomy_term",
                    "param_name" : "[combined-term:value]",
                    "param_vocabulary" : "vocabulary_c"
                  },
                  "PROVIDE" : { "entity_created" : { "term_created" : "Created term" } }
                }
              },
              { "entity_save" : { "data" : [ "term-created" ], "immediate" : "1" } },
              { "data_set" : { "data" : [ "node:field-c" ], "value" : [ "term-created" ] } },
              { "drupal_message" : { "message" : "Term \u003Cstrong\u003E[node:field-a][node:field-b]\u003C\/strong\u003E did not yet exist and was created just now. It will be used to automatically set the value for Field C to this term also ... But only \u003Cstrong\u003Enext time this node is viewed\u003C\/strong\u003E (as per the used Rules Event ...)!!! If you\u0027re in a hurry to see the new value for Field C, just refresh this page." } }
            ]
          }
        ]
      }
    ]
  }
}

Things to be aware of:

For reasons I don't know (yet), you cannot simply "import" the above rule, using the typical Rules UI to do so. Try to import it somewhere, I bet you'll run into an import error which looks pretty similar (or "exactly"?) to this one:

Integrity check for the imported configuration failed. Error message: The data type of the configured argument does not match the parameter's <em class="placeholder">value</em> requirement..

But there is a work around for this import "issue", based on a similar trick I found in this Group Module issue (ie comment #6 which is similar and comment #12 which describes the work around), which is to delete the Rules Action that may be causing the import problem, and then after the import succeeded, you just add those Rules Actions manually again.

In this specific case, you have to delete these lines from the above rule (in export format) before trying to import the remaining part of it (both are located within the "Loop" Rules Action, they start with data_set):

    { "data_set" : { "data" : [ "new-term-exist" ], "value" : "1" } },
    { "data_set" : { "data" : [ "node:field-c" ], "value" : [ "current-term" ] } },

After you removed those 2 lines, retry your Rules import (in my case it works then). Next you need to manually (using the Rules UI) edit that rule and add these 2 Rules Actions right before the "Show a message on the site" again (using "Add Action"-link, locate to the right of "If: Text comparison"). These actions look like so:

  • "Set a data value", with Data Selector = new-term-exist and Data Value = True. Next "move" that action before the "Show a message on the site", and "Save changes".
  • "Set a data value", with Data Selector = node:field-c and Data Value = current-term. Next "move" that action before the "Show a message on the site", and "Save changes".

To check if you didn't introduce any mistakes with this special editing, export your rule, and compare it to the original rule in my answer here. They should match exactly (if you're using the same machine names, etc).

Scenario for creating a new Article

This Rule does work now also as I would like (expect), in the scenario where you're creating a new Article. However, to make this possible, in the entity_query I had to "hardcode" the machine name of the vocabulary used for Field C (= vocabulary_c).

If you use [ "node:field-c:vocabulary" ] instead, you run into some rules errors (starting with "Unable ...") that you can see if you enable Rules Debugging (in the Rules Log). Here is an example of such Rules Log, containing those unable-messages:

0 ms Rule Combine taxonomy terms in a 3rd taxonomy fires.
4.244 ms Evaluating the action drupal_message. [edit]
5.009 ms Evaluating the action variable_add. [edit]
5.055 ms Added the provided variable combined_term of type text [edit]
5.988 ms Unable to get the data value for the variable or parameter value. Error: Unable to get the data property vocabulary as the parent data structure is not set.
6.421 ms Unable to evaluate action entity_query. [edit]
6.52 ms Evaluating the action variable_add. [edit]
6.559 ms Added the provided variable new_term_exist of type boolean [edit]
7.031 ms Unable to get variable existing_terms, it is not defined.
7.459 ms Unable to evaluate loop. [edit]
9.287 ms The condition data_is evaluated to TRUE [edit]
10.428 ms Evaluating the action entity_create. [edit]
10.637 ms Added the provided variable term_created of type taxonomy_term [edit]
10.734 ms Evaluating the action entity_save. [edit]
10.781 ms Saved term_created of type taxonomy_term.
12.934 ms Evaluating the action data_set. [edit]
15.147 ms Evaluating the action drupal_message. [edit]
15.34 ms Rule Combine taxonomy terms in a 3rd taxonomy has fired.

Demo

Here are some samples (demos) of the kind of messages shown, depending on the used scenario:

  1. If the combination of terms in Field A and Field B already exists as a term in vocabulary_c (which is the vocabulary used by Field C):

    Value of term for Field C has to be set to Term A2Term B3, i.e. the combination of the value of Field A (= Term A2) and the value of Field B (= Term B3). However the page is already rendered BEFORE subsequent Rules Actions will be executed. So to actually see the new value for Field C, an extra page refresh is needed.

    Term Term A2Term B3 already existed and will be used to automatically set the value for Field C to this term also ... But only next time this node is viewed (as per the used Rules Event ...)!!! If you're in a hurry to see the new value for Field C, just refresh this page.

  2. If the combination of terms in Field A and Field B does NOT YET exist as a term in vocabulary_c (which is the vocabulary used by Field C):

    Value of term for Field C has to be set to Term A2Term B1, i.e. the combination of the value of Field A (= Term A2) and the value of Field B (= Term B1). However the page is already rendered BEFORE subsequent Rules Actions will be executed. So to actually see the new value for Field C, an extra page refresh is needed.

    Term Term A2Term B1 did not yet exist and was created just now. It will be used to automatically set the value for Field C to this term also ... But only next time this node is viewed (as per the used Rules Event ...)!!! If you're in a hurry to see the new value for Field C, just refresh this page.

5
  • Pierre.Vriens I have a good news, Combined with everyone's program, I pass fetched to judge, the success of the production of a rule for me to work.Thank you very much for your help in these days .and No Sssweat
    – LIUJIAHUI
    Dec 9, 2016 at 4:43
  • Yes, I have a rule for my work now.The rules I use are like this.1.variable_add""type" : "text","value" : "[node:field-a][node:field-b]"PROVIDE" : {"variable_added" 2.entity_query""type" : "taxonomy_term", "property" : "name","value" : [ "variable-add-juhe" ], 3."CONDITIONAL" :"IF" : entity-fetched_is_empty" "DO" entity_create" "entity_save" "data_set" : { "data" : [ "node:field-c" ], "value" : [ "entity-created" ] } } "ELSE" :"data_set" : { "data" : [ "node:field-c" ], "value" : [ "entity-fetched:0" ]
    – LIUJIAHUI
    Dec 9, 2016 at 7:26
  • 1
    Pierre.Vriens,You have helped me a lot these days, I refer to your program and Niall Murphy and No Sssweat,Thank you very much!
    – LIUJIAHUI
    Dec 9, 2016 at 9:55
  • @LIUJIAHUI merci (= thank you) for the accept! Next question ... Maybe? Dec 9, 2016 at 10:24
  • Pierre.Vriens,There is no problem, thank you very much for your help these days!Sorry just to see, the original thought, set to the best answer will not be able to reply, I am now the site also used the answer module。
    – LIUJIAHUI
    Dec 9, 2016 at 23:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.