diff options
Diffstat (limited to 'nixos/doc/manual/from_md/configuration/abstractions.section.xml')
-rw-r--r-- | nixos/doc/manual/from_md/configuration/abstractions.section.xml | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/nixos/doc/manual/from_md/configuration/abstractions.section.xml b/nixos/doc/manual/from_md/configuration/abstractions.section.xml new file mode 100644 index 00000000000..c71e23e34ad --- /dev/null +++ b/nixos/doc/manual/from_md/configuration/abstractions.section.xml @@ -0,0 +1,101 @@ +<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-module-abstractions"> + <title>Abstractions</title> + <para> + If you find yourself repeating yourself over and over, it’s time to + abstract. Take, for instance, this Apache HTTP Server configuration: + </para> + <programlisting language="bash"> +{ + services.httpd.virtualHosts = + { "blog.example.org" = { + documentRoot = "/webroot/blog.example.org"; + adminAddr = "alice@example.org"; + forceSSL = true; + enableACME = true; + enablePHP = true; + }; + "wiki.example.org" = { + documentRoot = "/webroot/wiki.example.org"; + adminAddr = "alice@example.org"; + forceSSL = true; + enableACME = true; + enablePHP = true; + }; + }; +} +</programlisting> + <para> + It defines two virtual hosts with nearly identical configuration; + the only difference is the document root directories. To prevent + this duplication, we can use a <literal>let</literal>: + </para> + <programlisting language="bash"> +let + commonConfig = + { adminAddr = "alice@example.org"; + forceSSL = true; + enableACME = true; + }; +in +{ + services.httpd.virtualHosts = + { "blog.example.org" = (commonConfig // { documentRoot = "/webroot/blog.example.org"; }); + "wiki.example.org" = (commonConfig // { documentRoot = "/webroot/wiki.example.com"; }); + }; +} +</programlisting> + <para> + The <literal>let commonConfig = ...</literal> defines a variable + named <literal>commonConfig</literal>. The <literal>//</literal> + operator merges two attribute sets, so the configuration of the + second virtual host is the set <literal>commonConfig</literal> + extended with the document root option. + </para> + <para> + You can write a <literal>let</literal> wherever an expression is + allowed. Thus, you also could have written: + </para> + <programlisting language="bash"> +{ + services.httpd.virtualHosts = + let commonConfig = ...; in + { "blog.example.org" = (commonConfig // { ... }) + "wiki.example.org" = (commonConfig // { ... }) + }; +} +</programlisting> + <para> + but not <literal>{ let commonConfig = ...; in ...; }</literal> since + attributes (as opposed to attribute values) are not expressions. + </para> + <para> + <emphasis role="strong">Functions</emphasis> provide another method + of abstraction. For instance, suppose that we want to generate lots + of different virtual hosts, all with identical configuration except + for the document root. This can be done as follows: + </para> + <programlisting language="bash"> +{ + services.httpd.virtualHosts = + let + makeVirtualHost = webroot: + { documentRoot = webroot; + adminAddr = "alice@example.org"; + forceSSL = true; + enableACME = true; + }; + in + { "example.org" = (makeVirtualHost "/webroot/example.org"); + "example.com" = (makeVirtualHost "/webroot/example.com"); + "example.gov" = (makeVirtualHost "/webroot/example.gov"); + "example.nl" = (makeVirtualHost "/webroot/example.nl"); + }; +} +</programlisting> + <para> + Here, <literal>makeVirtualHost</literal> is a function that takes a + single argument <literal>webroot</literal> and returns the + configuration for a virtual host. That function is then called for + several names to produce the list of virtual host configurations. + </para> +</section> |