{"result":{"depiction_url":null,"edges":{"observes":{"objects":[{"created":"2026-10-22T20:07:32Z","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-10-22T20:07:32Z","object_id":{"id":1982,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_search_query","title":"observe_search_query\/2","uri":"https:\/\/zotonic.com\/id\/1982"},"seq":2},{"created":"2026-10-22T20:07:32Z","object_id":{"id":1999,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_rsc_merge","title":"observe_rsc_merge\/2","uri":"https:\/\/zotonic.com\/id\/1999"},"seq":3}],"predicate":{"id":2550,"is_a":["meta","predicate"],"name":"observes","title":{"_type":"trans","tr":{"en":"Observes"}},"uri":"https:\/\/zotonic.com\/id\/observes"}},"subject":{"objects":[{"created":"2026-10-22T20:07:32Z","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-10-22T20:07:32Z","object_id":{"id":2562,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_site_administrator","title":"Site administrator","uri":"https:\/\/zotonic.com\/id\/2562"},"seq":2},{"created":"2026-10-22T20:07:32Z","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":3},{"created":"2026-10-22T20:07:32Z","object_id":{"id":2586,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_search_and_discovery","title":"Search and discovery","uri":"https:\/\/zotonic.com\/id\/2586"},"seq":4},{"created":"2026-10-22T20:07:32Z","object_id":{"id":2599,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_api_and_integration","title":"API and integration","uri":"https:\/\/zotonic.com\/id\/2599"},"seq":5},{"created":"2026-10-22T20:07:32Z","object_id":{"id":2635,"is_a":["categorization","keyword","keyword_architecture"],"name":"zotonic_topic_module","title":"Module","uri":"https:\/\/zotonic.com\/id\/2635"},"seq":6},{"created":"2026-10-22T20:07:32Z","object_id":{"id":2678,"is_a":["categorization","keyword","keyword_technology"],"name":"zotonic_topic_semantic_web","title":"Semantic Web","uri":"https:\/\/zotonic.com\/id\/2678"},"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":3114,"is_a":["text","documentation","reference","module"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/3114"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_external_11_mod_wikiconcept","page_url":{"en":"https:\/\/zotonic.com\/docs\/3114\/mod_wikiconcept","x-default":"https:\/\/zotonic.com\/docs\/3114\/mod_wikiconcept"},"preview_url":null,"resource":{"version":21,"pivot_location_lat":null,"title":"mod_wikiconcept","is_authoritative":true,"body":"<p>Import Wikidata concepts from OpenAlex and connect them to Zotonic keyword\nresources. Imported concepts and multilingual search names are stored locally;\nsearching the local catalogue does not require an OpenAlex request.<\/p>\n<h2>Setup and installation<\/h2>\n<p>Enable <code>mod_wikiconcept<\/code>, which depends on <code>mod_admin<\/code>. Installation creates\n<code>wikiconcept<\/code> and <code>wikiconcept_name<\/code>, their constraints and search indexes.\nThe database needs <code>pg_trgm<\/code> in the <code>public<\/code> schema. The installer uses\n<code>create extension if not exists pg_trgm with schema public<\/code>; the database\nuser must be able to create the extension when absent and use that schema.\nThere are no module-specific configuration keys.<\/p>\n<p>Schema version 2 preserves existing concepts, search names and keyword links.\nIt converts the legacy <code>props_json<\/code> bytea column containing UTF-8 JSON to\njsonb in place. Invalid JSON aborts the schema transaction without discarding\ndata. Reinstallation never drops the tables or the shared extension.<\/p>\n<p>An OpenAlex import task is scheduled only when the concept table is empty.\nUse the Reimport button on the admin status page to refresh an existing or\npartially imported catalogue. Imports update matching concepts and their\nnames without clearing keyword connections; they do not prune concepts\nmissing from the upstream response.<\/p>\n<h2>Administration and search<\/h2>\n<p>The WikiConcepts entry under the admin Modules menu lists imported concepts,\nwith live search by name, Wikidata ID, OpenAlex ID or URL and numbered pagination.\nThe overview and concept dialog require <code>use mod_admin<\/code>. Click a row or its name\nbutton to view the summary, source links, ancestors, and available title and\nsummary languages. Keyword and source links remain directly clickable.<\/p>\n<p>For an unconnected concept, expand <strong>Create a keyword<\/strong> in the dialog and select\nthe keyword category or an allowed subcategory. Creation checks admin access\nand resource insert permissions, publishes the keyword, and updates the dialog\nand table with its edit link. An existing connection is reused.<\/p>\n<p>Keyword creation keeps nonempty translations in the site&#39;s editable languages.\nWhen none match, available English text is copied to the site&#39;s default language,\nnot the current interface language. Titles fall back to the concept&#39;s display\nname or identifier if necessary, so newly created keywords always have a title.<\/p>\n<p>The supplied keyword-editing UI also supports finding, connecting and\ndisconnecting concepts. The media dialog supports creating keywords from concepts.\nWhen resources are merged, links to the losing keyword move to the winner.<\/p>\n<p>Interface translation catalogs accompany the module for Arabic, German, Spanish,\nFrench, Indonesian, Italian, Dutch, Polish, Portuguese, Brazilian Portuguese,\nRussian, Swedish, Turkish, Ukrainian and Simplified Chinese. English is the source\nlanguage. Interface translations are separate from imported concept translations.<\/p>\n<p>Two searches are exposed through <code>m.search<\/code>:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">{% with m.search.wikiconcept::%{ text: &quot;biology&quot; } as result %}\n    {% for concept in result %}{{ concept.display_name|escape }}{% endfor %}\n{% endwith %}\n<\/code><\/pre>\n<p><code>wikiconcept<\/code> takes <code>text<\/code> and searches local names or identifiers. It returns an\nexact total for the standard pager; use <code>m.search.paged.wikiconcept<\/code> for pagination.\n<code>wikiconcept_descendant<\/code> takes <code>concept<\/code> and finds concepts at the next level\nwhose ancestor list contains that concept. The results are concept maps,\nnot resource IDs. Escape imported text when rendering it.<\/p>\n<p>The model&#39;s read paths and the search observers do not apply resource ACL\nfiltering. Connecting and disconnecting through <code>m_wikiconcept<\/code> require an\neditable keyword resource; creating a keyword uses <code>m_rsc<\/code> insert permissions.\nThe Reimport postback itself has no explicit ACL check in its event handler.\nSee <code>m_wikiconcept<\/code> for the model paths and direct Erlang APIs.<\/p>","slug":"mod_wikiconcept","doc_module_config":[],"is_protected":false,"visible_for":0,"tz":"UTC","language":["en"],"doc_source_hash":"56c76c773991523f00a176dd842853190f0ed907c3e867ede6b97c3786ecbb4f","doc_module_observers":[{"name":"admin_menu","page_name":"doc_notification_admin_menu"},{"name":"rsc_merge","page_name":"doc_notification_rsc_merge"},{"name":"search_query","page_name":"doc_notification_search_query"}],"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"},"external_module_id":{"id":11,"is_a":[],"name":null,"title":null,"uri":"https:\/\/zotonic.com\/id\/11"},"git_url":"https:\/\/github.com\/driebit\/zotonic_mod_wikiconcept.git","category_id":{"id":320,"is_a":["meta","category"],"name":"module","title":"Modules","uri":"https:\/\/test.zotonic.com\/id\/320"},"doc_source_path":".\/src\/mod_wikiconcept.erl","publication_start":"2026-10-22T20:07:32Z","github_url":"https:\/\/github.com\/driebit\/zotonic_mod_wikiconcept.git","pivot_location_lng":null,"doc_source_kind":"external","name":"doc_external_11_mod_wikiconcept","is_unfindable":false,"is_published":true,"pivot_geocode":null,"external_module_title":"Wikidata Concepts","created":"2026-10-22T20:07:32Z","uri":null,"doc_status":"current","is_dependent":false,"is_external_module":true,"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":"5f9530a8bf56b6bc3df48ab462c1c2d55af14472","creator_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"modified":"2026-10-22T20:07:33Z","title_slug":"mod_wikiconcept"},"uri":"https:\/\/zotonic.com\/id\/3114","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/3114"}},"status":"ok"}