{"result":{"depiction_url":null,"edges":{"in_module":{"objects":[{"created":"2026-09-09T13:48:11Z","object_id":{"id":335,"is_a":["text","documentation","reference","module"],"name":"doc_core","title":"Zotonic Core","uri":"https:\/\/zotonic.com\/id\/335"},"seq":1}],"predicate":{"id":333,"is_a":["meta","predicate"],"name":"in_module","title":{"_type":"trans","tr":{"en":"In module"}},"uri":"https:\/\/zotonic.com\/id\/in_module"}},"references":{"objects":[{"created":"2020-05-30T05:48:21Z","object_id":{"id":1728,"is_a":["text","documentation","reference"],"name":"doc_developerguide_configuration_site_configuration","title":"Site configuration","uri":"https:\/\/zotonic.com\/id\/1728"},"seq":1000000},{"created":"2020-05-30T05:48:21Z","object_id":{"id":1768,"is_a":["text","documentation","reference","model"],"name":"doc_model_model_site","title":"site","uri":"https:\/\/zotonic.com\/id\/1768"},"seq":1000000}],"predicate":{"id":332,"is_a":["meta","predicate"],"name":"references","title":{"_type":"trans","tr":{"en":"References"}},"uri":"https:\/\/zotonic.com\/id\/references"}},"refers":{"objects":[{"created":"2026-09-09T13:48:11Z","object_id":{"id":1768,"is_a":["text","documentation","reference","model"],"name":"doc_model_model_site","title":"site","uri":"https:\/\/zotonic.com\/id\/1768"},"seq":1000000}],"predicate":{"id":2409,"is_a":["meta","predicate"],"name":"refers","title":{"_type":"trans","tr":{"en":"Refers"}},"uri":"https:\/\/zotonic.com\/id\/refers"}},"subject":{"objects":[{"created":"2026-09-09T13:48:11Z","object_id":{"id":2555,"is_a":["categorization","keyword","keyword_information_type"],"name":"zotonic_topic_reference","title":"Reference","uri":"https:\/\/zotonic.com\/id\/2555"},"seq":1},{"created":"2026-09-09T13:48:11Z","object_id":{"id":2564,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_backend_developer","title":"Backend developer","uri":"https:\/\/zotonic.com\/id\/2564"},"seq":2},{"created":"2026-09-09T13:48:11Z","object_id":{"id":2603,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_configuration","title":"Configuration","uri":"https:\/\/zotonic.com\/id\/2603"},"seq":3},{"created":"2026-09-09T13:48:11Z","object_id":{"id":2625,"is_a":["categorization","keyword","keyword_architecture"],"name":"zotonic_topic_model","title":"Model","uri":"https:\/\/zotonic.com\/id\/2625"},"seq":4},{"created":"2026-09-09T13:48:11Z","object_id":{"id":2636,"is_a":["categorization","keyword","keyword_task"],"name":"zotonic_topic_configure","title":"Configure","uri":"https:\/\/zotonic.com\/id\/2636"},"seq":5}],"predicate":{"id":308,"is_a":["meta","predicate"],"name":"subject","title":{"_type":"trans","tr":{"en":"Keyword"}},"uri":"http:\/\/purl.org\/dc\/elements\/1.1\/subject"}}},"id":1729,"is_a":["text","documentation","reference","model"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1729"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_model_model_config","page_url":{"en":"https:\/\/zotonic.com\/docs\/1729\/config","x-default":"https:\/\/zotonic.com\/docs\/1729\/config"},"preview_url":null,"resource":{"version":4049,"pivot_location_lat":null,"title":"config","is_authoritative":true,"body":"<p>Zotonic has two places where a site&#39;s configuration is kept:<\/p>\n<ul><li>the site&#39;s <a href=\"\/id\/doc_developerguide_configuration_site_configuration#ref-site-configuration\">config file<\/a> (accessible through <a href=\"\/id\/doc_model_model_site\" class=\"doc-reference doc-reference-model\"><code>model#site<\/code><\/a>)<\/li><li>the site&#39;s <code>config<\/code> database table. Entries in the config table overrule any module settings from the config file.<\/li><\/ul>\n<div class=\"admonition note\"><p class=\"first admonition-title\">Note<\/p><p class=\"last\">Configuration keys are only accessible from templates using <code>{{ m.config }}<\/code> for users with administrator rights. To\naccess other configs, use or add specific models.<\/p><\/div>\n<p>All m_config keys can be thought of as tuples <code>{Module, Key, Value}<\/code>, where Value is a complex value that can have a text value but also any other properties. Only configuration\nwith text values can be edited in admin.<\/p>\n<p>The config model table has different access methods. Below are examples of what is possible and how to access the configuration.<\/p>\n<h2>Fetch the value of a config key<\/h2>\n<p>Example, fetching the config key value of mod_emailer.from_email:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">{{ m.config.mod_emailer.email_from.value }}\n<\/code><\/pre>\n<p>Or, from Erlang:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">m_config:get_value(mod_emailer, email_from, Context).\n<\/code><\/pre>\n<p>Where m.config.mod_emailer.email_from returns a property list which is much like:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">[\n    {id,5},\n    {module,&lt;&lt;&quot;mod_emailer&quot;&gt;&gt;},\n    {key,&lt;&lt;&quot;email_from&quot;&gt;&gt;},\n    {value,&lt;&lt;&quot;no-reply@example.com&quot;&gt;&gt;},\n    {props,undefined},\n    {created,{{2009,11,7},{20,48,27}}},\n    {modified,{{2009,11,7},{20,48,27}}}\n]\n<\/code><\/pre>\n<p>If the database does not contain a <code>mod_email.email_from<\/code> configuration parameter, Zotonic falls back to the <a href=\"\/id\/doc_developerguide_configuration_site_configuration#ref-site-configuration\">site\nconfig file<\/a> and tries to find the\nparameter there.<\/p>\n<p>When the config key would have any extra value (besides the value property) then they would be visible as extra\nproperties and the property &quot;props&quot; would not have been present.<\/p>\n<p>When the configuration comes from the site config then the id property is not present.<\/p>\n<h2>Fetching all configurations of a module<\/h2>\n<p>This only returns configurations from the config table; configuration keys from the site config are not mixed in. This\nmight change in the futurr:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">{% for key, value in m.config.mod_emailer %}\n    ...\n{% endfor %}\n<\/code><\/pre>\n<h2>Fetching all configurations<\/h2>\n<p>This only returns configurations from the config table. Configurations from the site config are not mixed in. This might\nchange in the future:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">{% for mod,keys in m.config %}\n    {% for key,value in keys %}\n    ...\n    {% endfor %}\n{% endfor %}\n<\/code><\/pre>\n<h2>Listening for config changes<\/h2>\n<p>m_config uses z_notifier to broadcast events when values are changed or deleted:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">#m_config_update{module=Module, key=Key, value=Value}\n<\/code><\/pre>\n<p>for &quot;complex&quot; property value updates\/inserts a slighly different notification is used:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">#m_config_update_prop{module=Module, key=Key, prop=Prop, value=Value}\n<\/code><\/pre>\n<p>For config key deletes, the <code>#m_config_update{}<\/code> record is broadcast with <code>undefined<\/code> for the value:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">#m_config_update{module=Module, key=Key, value=undefined}\n<\/code><\/pre>\n<h2>Available Model API Paths<\/h2>\n<table class=\"table\"><thead><tr><th>Method<\/th><th>Path pattern<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td><code>get<\/code><\/td><td><code>\/<\/code><\/td><td>Return all site config values grouped by module (admin only). No further lookups.<\/td><\/tr><tr><td><code>get<\/code><\/td><td><code>\/+module<\/code><\/td><td>Return all site config key\/value pairs for module <code>+module<\/code> (admin only). No further lookups.<\/td><\/tr><tr><td><code>get<\/code><\/td><td><code>\/+module\/+key\/...<\/code><\/td><td>Return site config value for key <code>+key<\/code> in module <code>+module<\/code> (admin only).<\/td><\/tr><\/tbody><\/table>\n<p><code>\/+name<\/code> marks a variable path segment. A trailing <code>\/...<\/code> means extra path segments are accepted for further lookups.<\/p>","slug":"config","is_protected":false,"visible_for":0,"tz":"UTC","language":["en"],"doc_source_hash":"5c5c2bd077701c39ad5ffff439bf79337aee2c4d7828bff95e42aa8fc4d0687b","is_featured":false,"content_group_id":{"id":2551,"is_a":["meta","content_group"],"name":"content_group_imported_docs","title":"Imported documentation","uri":"https:\/\/zotonic.com\/id\/content_group_imported_docs"},"category_id":{"id":322,"is_a":["meta","category"],"name":"model","title":"Models","uri":"https:\/\/test.zotonic.com\/id\/322"},"doc_source_path":"apps\/zotonic_core\/src\/models\/m_config.erl","publication_start":"2023-06-24T08:17:51Z","github_url":"https:\/\/github.com\/zotonic\/zotonic\/blob\/master\/apps\/zotonic_core\/src\/models\/m_config.erl","pivot_location_lng":null,"doc_source_kind":"model","name":"doc_model_model_config","is_unfindable":false,"is_published":true,"pivot_geocode":null,"created":"2020-05-30T05:47:32Z","uri":null,"doc_status":"current","is_dependent":false,"erlang_app":"zotonic_core","publication_end":"9999-06-01T00:00:00Z","modifier_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"privacy":0,"doc_source_commit":"28493fb676b2d92727e68d4fba20d89c56cf8ead\n","erlang_module":"m_config","creator_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"modified":"2026-10-15T20:07:37Z","title_slug":"config"},"uri":"https:\/\/zotonic.com\/id\/1729","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1729"}},"status":"ok"}