{"result":{"depiction_url":null,"edges":{"in_module":{"objects":[{"created":"2020-05-30T05:47:26Z","object_id":{"id":1296,"is_a":["text","documentation","reference","module"],"name":"doc_module_mod_base","title":"mod_base","uri":"https:\/\/zotonic.com\/id\/1296"},"seq":1000000}],"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:47:26Z","object_id":{"id":1372,"is_a":["text","documentation","reference","template_tag"],"name":"doc_template_tag_tag_lib","title":"lib","uri":"https:\/\/zotonic.com\/id\/1372"},"seq":1000000},{"created":"2020-05-30T05:47:26Z","object_id":{"id":1536,"is_a":["text","documentation","developerguide"],"name":"doc_developerguide_access_control","title":"Access control","uri":"https:\/\/zotonic.com\/id\/1536"},"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:47:52Z","object_id":{"id":1372,"is_a":["text","documentation","reference","template_tag"],"name":"doc_template_tag_tag_lib","title":"lib","uri":"https:\/\/zotonic.com\/id\/1372"},"seq":1000000}],"predicate":{"id":2409,"is_a":["meta","predicate"],"name":"refers","title":{"_type":"trans","tr":{"en":"Refers"}},"uri":"https:\/\/zotonic.com\/id\/refers"}},"relation":{"objects":[{"created":"2020-05-30T05:47:26Z","object_id":{"id":1556,"is_a":["text","documentation","reference","controller"],"name":"doc_controller_controller_file_id","title":"controller_file_id","uri":"https:\/\/zotonic.com\/id\/1556"},"seq":1000000},{"created":"2020-05-30T05:47:26Z","object_id":{"id":1372,"is_a":["text","documentation","reference","template_tag"],"name":"doc_template_tag_tag_lib","title":"lib","uri":"https:\/\/zotonic.com\/id\/1372"},"seq":1000000},{"created":"2020-05-30T05:47:26Z","object_id":{"id":1341,"is_a":["text","documentation","reference","template_tag"],"name":"doc_template_tag_tag_image","title":"image","uri":"https:\/\/zotonic.com\/id\/1341"},"seq":1000000},{"created":"2020-05-30T05:47:26Z","object_id":{"id":1369,"is_a":["text","documentation","reference","template_tag"],"name":"doc_template_tag_tag_image_url","title":"image_url","uri":"https:\/\/zotonic.com\/id\/1369"},"seq":1000000}],"predicate":{"id":303,"is_a":["meta","predicate"],"name":"relation","title":{"_type":"trans","tr":{"nl":"Relatie","en":"Relation"}},"uri":"http:\/\/purl.org\/dc\/terms\/relation"}},"subject":{"objects":[{"created":"2026-09-09T13:47:52Z","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:47:52Z","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:47:52Z","object_id":{"id":2581,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_file_storage","title":"File storage","uri":"https:\/\/zotonic.com\/id\/2581"},"seq":3},{"created":"2026-09-09T13:47:52Z","object_id":{"id":2626,"is_a":["categorization","keyword","keyword_architecture"],"name":"zotonic_topic_controller","title":"Controller","uri":"https:\/\/zotonic.com\/id\/2626"},"seq":4},{"created":"2026-09-09T13:47:52Z","object_id":{"id":2676,"is_a":["categorization","keyword","keyword_technology"],"name":"zotonic_topic_http","title":"HTTP","uri":"https:\/\/zotonic.com\/id\/2676"},"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":1555,"is_a":["text","documentation","reference","controller"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1555"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_controller_controller_file","page_url":{"en":"https:\/\/zotonic.com\/docs\/1555\/controller_file","x-default":"https:\/\/zotonic.com\/docs\/1555\/controller_file"},"preview_url":null,"resource":{"version":3995,"pivot_location_lat":null,"title":"controller_file","is_authoritative":true,"body":"<p>Serve an uploaded-, resized- or library file.<\/p>\n<p>This controller is used to serve files and images. It is able to manipulate an image according to the parameters supplied.<\/p>\n<p>Image manipulation parameters are signed to prevent random image manipulations on the request of visitors, which might\nresult in a denial of service due to processing- or disk space limitations.<\/p>\n<p>This controller serves all files with a very long client side caching time and handles if-modified-since checks. Text\nfiles are served with gzip compression if the user-agent supports it.<\/p>\n<p>Multiple files can be served in a single request; the controller concatenates them into a single file. See the\n<a href=\"\/id\/doc_template_tag_tag_lib\" class=\"doc-reference doc-reference-tag\"><code>tag#lib<\/code><\/a> tag for more information. The creators of the files have to ensure that they can be\nproperly concatenated.<\/p>\n<h2>Dispatch rules and options<\/h2>\n<p>Example dispatch rules:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">{image, [&quot;image&quot;, &#39;*&#39;], controller_file, []},\n{lib, [&quot;lib&quot;, &#39;*&#39;], controller_file, [{root, [lib]}]}\n<\/code><\/pre>\n<p>controller_file has the following dispatch options:<\/p>\n<table class=\"table\"><thead><tr><th>Option<\/th><th>Description<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td><code>root<\/code><\/td><td>List of root directories where files are located. Use <code>lib<\/code> for the library files. This defaults to the site’s “files\/archive” directory.<\/td><td><code>{root, [lib]}<\/code><\/td><\/tr><tr><td><code>path<\/code><\/td><td>Default file to be served. Used for files like “robots.txt” and “favicon.ico”.<\/td><td><code>{path,&quot;misc\/robots.txt&quot;}<\/code><\/td><\/tr><tr><td><code>content_disposition<\/code><\/td><td>If the file should be viewed in the browser or downloaded. Possible values are <code>inline<\/code> and <code>attachment<\/code>. Defaults to the browser’s defaults by not setting the “Content-Disposition” response header.<\/td><td><code>{content_disposition, inline}<\/code><\/td><\/tr><tr><td><code>acl<\/code><\/td><td>Extra authorization checks to be performed.<\/td><td>See <a href=\"#acl-options\">ACL options<\/a>.<\/td><\/tr><tr><td><code>max_age<\/code><\/td><td>Max age, used for Cache and Expires. Value is an integer, number of secs.<\/td><td><code>{max_age,3600}<\/code><\/td><\/tr><\/tbody><\/table>\n<h3>ACL options<\/h3>\n<p><a href=\"\/id\/doc_developerguide_access_control#guide-authorization\">Authorization<\/a> checks to perform, in addition to the <code>acl_action<\/code> dispatch option, can be given in the <code>acl<\/code> dispatch option, and accepts the following options:<\/p>\n<table class=\"table\"><thead><tr><th>ACL option<\/th><th>Description<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td><code>is_auth<\/code><\/td><td>Disable anonymous access to this resource.<\/td><td><code>{acl, is_auth}<\/code><\/td><\/tr><tr><td><code>logoff<\/code><\/td><td>Log out user before processing the request.<\/td><td><code>{acl, logoff}<\/code><\/td><\/tr><tr><td><code>{Action, Resource}<\/code><\/td><td>Check if user is allowed to perform <code>Action<\/code> on <code>Resource<\/code>. The example is equivalent to the options <code>{acl_action, edit}, {id, my_named_page}<\/code>.<\/td><td><code>{acl, {edit, my_named_page}}<\/code><\/td><\/tr><tr><td><code>[{Action, Resource}]<\/code><\/td><td>A list of checks to be performed, as above.<\/td><td><code>{acl, [{view, secret_page}, {update, 345}]}<\/code><\/td><\/tr><tr><td><code>ignore<\/code><\/td><td>Don’t perform any access control checks. Be careful to add your own checks in the rendered template and all its included templates.<\/td><td><code>{acl, ignore}<\/code><\/td><\/tr><\/tbody><\/table>\n<h2>More about the search root<\/h2>\n<p>The search root can be a list with one or more of the following:<\/p>\n<ul><li>The atom lib for finding library files in the <em>lib<\/em> directory of modules.<\/li><li>The atom template for finding files in the <em>template<\/em> directory of modules.<\/li><li>A directory name (binary or string). This directory name must be absolute or relative to the <em>files<\/em> directory of the site.<\/li><li>A tuple <code>{module, ModuleName}<\/code> to refer to a module. The module must implement the functions file_exists\/2 and file_forbidden\/2.<\/li><li>A tuple <code>{id, RscId}<\/code> where RscId is the unique name or id of a resource. The resource must have a medium record containing an uploaded file.<\/li><\/ul>\n<p>Note that located files are aggressively cached. Changes to the lookup routines or files will take a while before they\nare visible for new requests.<\/p>\n<h2>CSS and JavaScript templates<\/h2>\n<div class=\"admonition note\"><p class=\"first admonition-title\">Note<\/p><p class=\"last\"><code>controller_file<\/code> replaces <code>controller_file_readonly<\/code> and <code>controller_lib<\/code><\/p><\/div>\n<p>If a file with a lib or template root is not found, then the same filename with the addition of .tpl is checked. For\nexample styles.css.tpl. If found then the template will be rendered against an empty site context. This means that, with\nthe current implementation, the template will not receive the current language, user etc. This behavior may change in\nthe future.<\/p>\n<p>New in version 0.11.<\/p>","slug":"controller_file","is_protected":false,"visible_for":0,"tz":"UTC","language":["en"],"doc_source_hash":"36dccd5b6bef418472b6b750fd393da99aac34a606611c0c337c673beb7271c1","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":321,"is_a":["meta","category"],"name":"controller","title":"Controllers","uri":"https:\/\/test.zotonic.com\/id\/321"},"doc_source_path":"apps\/zotonic_mod_base\/src\/controllers\/controller_file.erl","publication_start":"2023-06-24T08:17:51Z","github_url":"https:\/\/github.com\/zotonic\/zotonic\/blob\/master\/apps\/zotonic_mod_base\/src\/controllers\/controller_file.erl","pivot_location_lng":null,"doc_source_kind":"controller","name":"doc_controller_controller_file","is_unfindable":false,"is_published":true,"pivot_geocode":null,"created":"2020-05-30T05:47:26Z","uri":null,"doc_status":"current","is_dependent":false,"erlang_app":"zotonic_mod_base","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":"66cb145eae7002b184e7d8c4c7bba5e53e8248e5\n","erlang_module":"controller_file","creator_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"modified":"2026-10-02T12:40:23Z","title_slug":"controller_file"},"uri":"https:\/\/zotonic.com\/id\/1555","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1555"}},"status":"ok"}