{"result":{"depiction_url":null,"edges":{"relation":{"objects":[{"created":"2020-05-30T05:48:23Z","object_id":{"id":1331,"is_a":["text","documentation","reference","module"],"name":"doc_module_mod_admin","title":"mod_admin","uri":"https:\/\/zotonic.com\/id\/1331"},"seq":1000000},{"created":"2020-05-30T05:48:23Z","object_id":{"id":1332,"is_a":["text","documentation","reference","template_filter"],"name":"doc_template_filter_filter_menu_rsc","title":"menu_rsc","uri":"https:\/\/zotonic.com\/id\/1332"},"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:48Z","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:48Z","object_id":{"id":2563,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_frontend_developer","title":"Frontend developer","uri":"https:\/\/zotonic.com\/id\/2563"},"seq":2},{"created":"2026-09-09T13:47:48Z","object_id":{"id":2583,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_user_interface_and_interaction","title":"User interface and interaction","uri":"https:\/\/zotonic.com\/id\/2583"},"seq":3},{"created":"2026-09-09T13:47:48Z","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:48Z","object_id":{"id":2641,"is_a":["categorization","keyword","keyword_task"],"name":"zotonic_topic_render","title":"Render","uri":"https:\/\/zotonic.com\/id\/2641"},"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":1822,"is_a":["text","documentation","reference","module"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1822"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_module_mod_admin_frontend","page_url":{"en":"https:\/\/zotonic.com\/docs\/1822\/mod_admin_frontend","x-default":"https:\/\/zotonic.com\/docs\/1822\/mod_admin_frontend"},"preview_url":null,"resource":{"version":4093,"pivot_location_lat":null,"title":"mod_admin_frontend","is_authoritative":true,"body":"<p>Adds editing of resources, menu-trees and collections for non-admin users.<\/p>\n<p>With many sites it is needed to let “normal” users edit content. For those users the <code>\/admin<\/code> interface is\noverwhelming and also gives too many options that only administrators should be using.<\/p>\n<p>For this use-case the mod_admin_frontend is created. It reuses some templates and parts of the normal admin, but in\nsuch a way that only the most needed options and fields are present. It also enables editing a menu-tree or collection,\nside-by-side with the content in the menu-tree.<\/p>\n<h2>Interface and dispatching<\/h2>\n<p>The interface is a one-page interface which uses postbacks to update the currently edited resource and forms. The\nediting history is maintained by using hashes in the url.<\/p>\n<p>The URL of the edit page is generated by the dispatch rule <code>admin_frontend_edit<\/code>:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">[\n    {admin_frontend_edit, [&quot;edit&quot;], controller_page, [{acl, is_auth}, {template, &quot;page_admin_frontend_edit.tpl&quot;}]},\n    {admin_frontend_edit, [&quot;edit&quot;, id], controller_page, [{acl_action, edit}, {template, {cat, &quot;page_admin_frontend_edit.tpl&quot;}}]}\n].\n<\/code><\/pre>\n<p>The template uses the <code>menu_rsc<\/code> filter to find the contextual menu for the resource being edited. Per default the\n<code>menu_rsc<\/code> filter will fallback to the resource with the name <code>main_menu<\/code>. Hook into the <code>#menu_rsc{}<\/code> notification to\nchange this behavior.<\/p>\n<p>To edit a specific resource in the context of a menu that is non-standard for the resource, use the following code:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">&lt;a href=&quot;{% url admin_frontend_edit id=my_menu %}#edit_id={{ id }}&quot;&gt;Click to edit {{ id.title }}&lt;\/a&gt;\n<\/code><\/pre>\n<h2>Customizing and templates<\/h2>\n<p>The <code>mod_admin_frontend<\/code> makes heavy use of <code>catinclude<\/code> to find the correct templates.<\/p>\n<p>The column with the menu is rendered using <code>{% catinclude &quot;_admin_menu_menu_view.tpl&quot; tree_id ... %}<\/code>. The\nresource-column with the main editing form is rendered using <code>{% catinclude &quot;_admin_frontend_edit.tpl&quot; id ... %}<\/code>.\nThis column is loaded lazily via a postback.<\/p>\n<h3>Editor profile<\/h3>\n<p>With <code>mod_editor_tiptap<\/code>, frontend editing defaults to the <code>advanced<\/code> profile.\nSet <code>mod_admin_frontend.editor_profile<\/code> to <code>simple<\/code>, <code>normal<\/code>, or <code>advanced<\/code> in\nthe site configuration to choose another profile. An unset or empty value uses\n<code>advanced<\/code>; unrecognized profile names fall back to Tiptap&#39;s <code>normal<\/code> profile.<\/p>\n<p>The setting is applied as <code>data-editor-profile<\/code> on the resource edit form,\nincluding forms loaded via postbacks. A nearer attribute on a field container\nor textarea overrides it. Profile definitions and site overrides are provided\nby <code>_editor_tiptap_profiles.tpl<\/code> in <code>mod_editor_tiptap<\/code>.\nThis setting does not change TinyMCE configuration.<\/p>\n<h3>Responsive menu column<\/h3>\n<p>When less than 1100 CSS pixels remain for the editor, the menu column collapses.\nA Menu button in the editor toolbar temporarily shows the menu in place of the\nform. The form remains mounted, preserving unsaved edits. Selecting a resource\ncloses the menu. The available width is observed, so resizing the live preview\nalso updates the layout. Site toolbar overrides using <code>save-buttons<\/code> inherit this\nbehavior through the core frontend script and styles.<\/p>\n<h3>Customizing the menu column<\/h3>\n<p>Extra content can be added above or below the menu view by overruling the blocks <code>above_menu<\/code> and <code>below_menu<\/code>.<\/p>\n<h3>Customizing the main edit column<\/h3>\n<p>The main edit template <code>_admin_frontend_edit.tpl<\/code> provides the main edit-form, javascript initializations and fields for\nbasic publication status editing.<\/p>\n<p>The main edit block <code>edit_blocks<\/code> is defined as follows and can be overruled for specific categories:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">{% block edit_blocks %}\n    {% catinclude &quot;_admin_edit_basics.tpl&quot; id is_editable=is_editable languages=languages %}\n\n    {% if id.category_id.feature_show_address %}\n        {% catinclude &quot;_admin_edit_content_address.tpl&quot; id is_editable=is_editable languages=languages %}\n    {% endif %}\n\n    {% all catinclude &quot;_admin_edit_content.tpl&quot; id is_editable=is_editable languages=languages %}\n\n    {% if id.is_a.media or id.medium %}\n        {% include &quot;_admin_edit_content_media.tpl&quot; %}\n    {% endif %}\n\n    {% catinclude &quot;_admin_edit_body.tpl&quot; id is_editable=is_editable languages=languages %}\n    {% catinclude &quot;_admin_edit_blocks.tpl&quot; id is_editable=is_editable languages=languages %}\n    {% catinclude &quot;_admin_edit_depiction.tpl&quot; id is_editable=is_editable languages=languages %}\n{% endblock %}\n<\/code><\/pre>\n<p>If any content needs to be added on top of the page, between the publication checkbox and the main edit fields, then\noverrule the block <code>meta_data_after<\/code>.<\/p>\n<p>If you click on the cog icon on the right, then a meta data panel is shown (for access-control options and language\nsettings). This panel can be extended with extra tabs using the blocks <code>meta_tabs<\/code> and <code>meta_panels<\/code>.<\/p>\n<h2>Live view<\/h2>\n<p>The Open panel \/ Close panel button toggles a right-hand iframe showing saved\ncontent without saving the form. A hint in the panel header reminds the user to\nsave when the form has unsaved changes. Resource,\nmedia and incoming\/outgoing edge events for both the edited resource and <code>tree_id<\/code>\nrefresh the preview. Switching resources replaces the subscriptions; closing the\npanel releases them. Unsaved form changes are not rendered.<\/p>\n<p>The preview uses the form&#39;s <code>view_location<\/code> override, falling back to <code>page_url<\/code> in\nthe editing language. Keep <code>_admin_edit_preview_context.tpl<\/code> inside the <code>rscform<\/code>\nblock so site overrides of <code>view_location<\/code> apply. Sites replacing the outer editor\nlayout or navbar must include <code>_admin_edit_preview.tpl<\/code> once and\n<code>_admin_edit_preview_button.tpl<\/code> in their toolbar. The iframe is same-origin and\nuses the editor&#39;s existing permissions. External destinations can be opened in a\nnew tab. Opening an admin or admin_frontend editor inside the preview navigates\nthe top window to that editor. Open state and width are remembered for the browser session.<\/p>\n<p>Preview languages are document-local. Embedded navigation and background requests\ndo not update the shared <code>z.lang<\/code> cookie, and embedded language switches do not\nchange the user&#39;s saved language preference. Authentication refresh uses the\ndocument&#39;s language for its MQTT session, keeping lazy templates and postbacks in\nthe preview language. Custom HTTP loaders must likewise include their document&#39;s\nlanguage in their URL or <code>z_language<\/code> argument instead of relying on the cookie.<\/p>\n<h2>Accepted Events<\/h2>\n<p>Delegate callbacks:<\/p>\n<ul><li><code>event\/2<\/code> with <code>postback<\/code> messages: <code>admin_menu_edit<\/code>.<\/li><li><code>event\/2<\/code> with <code>postback_notify<\/code> messages: <code>&lt;&lt;&quot;admin-menu-edit&quot;&gt;&gt;<\/code>.<\/li><\/ul>","slug":"mod_admin_frontend","doc_module_config":[{"default":"&lt;&lt;&quot;advanced&quot;&gt;&gt;","description":"Tiptap profile for frontend editing: simple, normal, or advanced.","has_default":true,"key":"editor_profile","module":"mod_admin_frontend","type":"string"}],"is_protected":false,"visible_for":0,"tz":"UTC","language":["en"],"doc_source_hash":"aacc06456d289f50fb7c20811883d7fb987d21b286b54d7f16c304ba291bc8f2","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_admin_frontend\/src\/mod_admin_frontend.erl","publication_start":"2023-06-24T08:17:46Z","github_url":"https:\/\/github.com\/zotonic\/zotonic\/blob\/master\/apps\/zotonic_mod_admin_frontend\/src\/mod_admin_frontend.erl","pivot_location_lng":null,"doc_source_kind":"module","name":"doc_module_mod_admin_frontend","is_unfindable":false,"is_published":true,"pivot_geocode":null,"created":"2020-05-30T05:47:38Z","uri":null,"doc_status":"current","is_dependent":false,"erlang_app":"zotonic_mod_admin_frontend","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":"bb8c4bfc7674f55f71ccc1d9130a01760b8031bc\n","creator_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"modified":"2026-10-24T06:46:49Z","title_slug":"mod_admin_frontend"},"uri":"https:\/\/zotonic.com\/id\/1822","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1822"}},"status":"ok"}