Uploaded image for project: 'CFEngine Community'
  1. CFEngine Community
  2. CFE-3129

It should be possible in a mustache template to guard a block to be expanded only if a variable is defined



    • Type: Story
    • Status: Open
    • Priority: (None)
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: cf-agent
    • Labels:


      Also see: CFE-3124, CFE-3128, CFE-2189

      Motivating example:

      Consider the case of managing /etc/resolv.conf contents with a mustache template. This may have multiple options (to be defined all on one line), multiple nameservers (defined each on a separate line), and one single search path (with multiple space-separated components all on one line).

      Here is a functional mustache template for this file:

      # This file is managed by CFEngine
      options {{{.}}}
      search {{{searchlist}}}

      Here is an example of data that might be passed in:

            "resolv[nameservers]" slist => { "", "" };
            "resolv[options]" slist => { "timeout:1" };
            "resolv[searchlist] string => "prod.example.com example.com";

      Now, quiz question: What do you do if you want another option defined, such as "rotate"?

      If you thought that you should add it to the "resolv[options]" slist as a new element, surprise! You're wrong. You should instead change the single value in that slist from "timeout:1" to "timeout:1 rotate".

      Which should raise the question, why are we using an slist there instead of a string?

      I'll come to that, but first here is another related quiz question: What if you have a server that shouldn't have a searchlist defined?

      Answer: This design doesn't support that at all.

      These two questions are actually closely related. The reason why an slist is used for options even though it should only ever have ONE element (one string, which may or may not contain spaces), is because the mustache template is designed to work whether there should or shouldn't be an "options" line in the rendered file.


      Accept the following in CFEngine mustache templates:

      Conditional text

      Note that this DOES work already for NON-scalar names (slists or data containers); for slists it will show as many copies of "Conditional text" as there are elements in the slist, which makes sense. (The fact that data containers will only show one copy of "Conditional text" regardless of how many key-value pairs they contain is the subject of bug report CFE-3128.)


      I believe that if the special "." syntax is used within such a conditional block, it should be replaced by the scalar value named in the block tags.

      The value of the variable named in the surrounding tags is: {{{.}}}

      Again, this would only render if the variable were defined.

      This proposal would make a string variable and a list with one value effectively equivalent for mustache template purposes, which I think is very desirable. Perhaps more importantly, it would make an undefined scalar variable match with the behavior already present for an empty or undefined list as far as mustache rendering is concerned.

      This proposal would not violate the mustache template documentation and would greatly increase the usability of mustache templates when working with scalar data.

      (Currently, we have several places in our code where we have to set a boilerplate "have_such_and_so_variable" class so that we can conditionally include or not include a line in a rendered config file, depending on whether the variable to include is actually defined. We could do away with such boilerplate if this proposal were implemented.)




            • Assignee:
              mweilgart Mike Weilgart
            • Votes:
              1 Vote for this issue
              2 Start watching this issue


              • Created:

                Summary Panel