{"result":{"depiction_url":null,"edges":{"observes":{"objects":[{"created":"2026-09-09T13:47:46Z","object_id":{"id":1466,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_admin_menu","title":"observe_admin_menu\/3","uri":"https:\/\/zotonic.com\/id\/1466"},"seq":1},{"created":"2026-09-09T13:47:46Z","object_id":{"id":2036,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_dropbox_file","title":"observe_dropbox_file\/2","uri":"https:\/\/zotonic.com\/id\/2036"},"seq":2}],"predicate":{"id":2550,"is_a":["meta","predicate"],"name":"observes","title":{"_type":"trans","tr":{"en":"Observes"}},"uri":"https:\/\/zotonic.com\/id\/observes"}},"references":{"objects":[{"created":"2020-05-30T05:48:09Z","object_id":{"id":1279,"is_a":["text","documentation"],"name":"doc_glossary","title":"Glossary","uri":"https:\/\/zotonic.com\/id\/1279"},"seq":1000000}],"predicate":{"id":332,"is_a":["meta","predicate"],"name":"references","title":{"_type":"trans","tr":{"en":"References"}},"uri":"https:\/\/zotonic.com\/id\/references"}},"subject":{"objects":[{"created":"2026-09-09T13:47:46Z","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:46Z","object_id":{"id":2565,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_integrator","title":"Integrator","uri":"https:\/\/zotonic.com\/id\/2565"},"seq":2},{"created":"2026-09-09T13:47:46Z","object_id":{"id":2600,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_import_and_migration","title":"Import and migration","uri":"https:\/\/zotonic.com\/id\/2600"},"seq":3},{"created":"2026-09-09T13:47:46Z","object_id":{"id":2635,"is_a":["categorization","keyword","keyword_architecture"],"name":"zotonic_topic_module","title":"Module","uri":"https:\/\/zotonic.com\/id\/2635"},"seq":4},{"created":"2026-09-09T13:47:46Z","object_id":{"id":2647,"is_a":["categorization","keyword","keyword_task"],"name":"zotonic_topic_parse","title":"Parse","uri":"https:\/\/zotonic.com\/id\/2647"},"seq":5},{"created":"2026-09-09T13:47:46Z","object_id":{"id":2650,"is_a":["categorization","keyword","keyword_task"],"name":"zotonic_topic_import","title":"Import","uri":"https:\/\/zotonic.com\/id\/2650"},"seq":6},{"created":"2026-09-09T13:47:46Z","object_id":{"id":2665,"is_a":["categorization","keyword","keyword_data_type"],"name":"zotonic_topic_structured_data","title":"Structured data","uri":"https:\/\/zotonic.com\/id\/2665"},"seq":7}],"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":1414,"is_a":["text","documentation","reference","module"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1414"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_module_mod_import_csv","page_url":{"en":"https:\/\/zotonic.com\/docs\/1414\/mod_import_csv","x-default":"https:\/\/zotonic.com\/docs\/1414\/mod_import_csv"},"preview_url":null,"resource":{"version":3331,"pivot_location_lat":null,"title":"mod_import_csv","is_authoritative":true,"body":"<p>Module which adds “import CSV” button to the admin status screen.<\/p>\n<p>The dropbox folder of the site is also watched for CSV or XLSX files.<\/p>\n<p>To determine whether it can import a file, it uses a notification:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">#import_csv_definition{basename, filename}\n<\/code><\/pre>\n<p>If the notification is not returning anything, it tries to map the columns found in the first row of the CSV file to\n<a href=\"\/id\/doc_glossary#term-resource\">resource<\/a> column names.\nCSV\/XLSX import module for admin-driven and watched-folder data imports.<\/p>\n<h2>Edge import<\/h2>\n<p>CSV files whose first three columns are <code>subject<\/code>, <code>predicate<\/code>, and <code>object<\/code> are imported as edge definitions instead\nof resources. The values in those columns are looked up as resource names: <code>subject<\/code> and <code>object<\/code> must name existing\nresources, and <code>predicate<\/code> must name an existing predicate resource.<\/p>\n<p>An optional fourth column named <code>order<\/code> sets the edge sequence number. For example, a tab-separated file can contain:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-text\">subject predicate object  order\npage_a  author    person_a 1\n<\/code><\/pre>\n<p>The separator can be a tab or comma, depending on what is detected for the file.<\/p>\n<p>Resource rows can also define edges by using column names that start with <code>&gt;<\/code> or <code>&lt;<\/code>.\nThe text after the marker is the predicate name, and the cell value is the resource name on the other side of the edge.<\/p>\n<ul><li><code>&gt; author<\/code> creates an outgoing edge from the imported row resource to the resource named in the cell.<\/li><li><code>&lt; relation<\/code> creates an incoming edge from the resource named in the cell to the imported row resource.<\/li><\/ul>\n<p>For example:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-text\">name   title    category  &gt; author  &lt; relation\npage_b Page B   text      person_a   page_a\n<\/code><\/pre>\n<p>This creates <code>page_b --author--&gt; person_a<\/code> and <code>page_a --relation--&gt; page_b<\/code>.<\/p>\n<h2>Accepted Events<\/h2>\n<p>This module handles the following notifier callbacks:<\/p>\n<ul><li><code>observe_admin_menu<\/code>: Add menu item to &#39;Content&#39; admin menu using <code>z_acl:is_allowed<\/code>.<\/li><li><code>observe_dropbox_file<\/code>: Import recognized CSV (including tab-separated) and XLSX files from the drop folder when an import definition matches.<\/li><\/ul>\n<p>Delegate callbacks:<\/p>\n<ul><li><code>event\/2<\/code> with <code>submit<\/code> messages: <code>csv_upload<\/code>.<\/li><\/ul>","slug":"mod_import_csv","is_protected":false,"visible_for":0,"tz":"UTC","language":["en"],"doc_source_hash":"1d3a3d35622ca4688ae69ad178eaab7eb41e59af1f58754a049c0d50cfbc191a","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":320,"is_a":["meta","category"],"name":"module","title":"Modules","uri":"https:\/\/test.zotonic.com\/id\/320"},"doc_source_path":"apps\/zotonic_mod_import_csv\/src\/mod_import_csv.erl","publication_start":"2023-01-30T19:24:00Z","github_url":"https:\/\/github.com\/zotonic\/zotonic\/blob\/master\/apps\/zotonic_mod_import_csv\/src\/mod_import_csv.erl","pivot_location_lng":null,"doc_source_kind":"module","name":"doc_module_mod_import_csv","is_unfindable":false,"is_published":true,"pivot_geocode":null,"created":"2020-05-30T05:47:21Z","uri":null,"doc_status":"current","is_dependent":false,"erlang_app":"zotonic_mod_import_csv","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","creator_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"modified":"2026-10-02T12:40:20Z","title_slug":"mod_import_csv"},"uri":"https:\/\/zotonic.com\/id\/1414","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1414"}},"status":"ok"}