translation_tree

Tree translation API. get/<id> returns language counts, get/status/<id> returns job progress and post/<id> starts a job. Reads require edit access to the root; tree traversal requires visibility of every member. Each page must still be editable when the worker reaches it; otherwise it is skipped. Trees include their root and unique menu/haspart descendants. No caller privileges are elevated.

The bulk_dialog postback accepts an ids list for bulk-update selections. It checks edit access to every selected page, deduplicates the IDs, and stores a selection for one day. Its bulk- token can be used instead of a resource ID on the same model paths. Only the authenticated user who created the selection can access it. Bulk jobs process exactly the selected pages, without traversing their descendants, and check each page's edit permission again before changing it.

For example, m.translation_tree[123] returns the following data for a tree with three unique pages, two available in English and all three available in Dutch:

#{total => 3, languages => [{en, 2}, {nl, 3}]}

The total includes the root. Language counts can overlap because a page can have multiple languages. The model callback wraps this data as {ok, {Data, Rest}}, where Rest is the unused model path.

m.translation_tree.status[123] can return this progress map:

#{root => 123,
  job => <<"example-job-id">>,
  state => running,
  operation => <<"translate">>,
  total => 3,
  done => 2,
  skipped => 1,
  failed => 0}

done counts all processed pages, including skipped and failed pages. total is zero until traversal finishes. The state becomes complete when every page has been processed, even if individual pages failed; failed as a state indicates a job-level failure. With no known job the response is #{root => 123, state => idle}. A successful post/<id> returns {ok, Progress} as soon as the job starts.

The event/2 handler opens the translation dialog using a signed dialog postback with an id argument identifying the tree root. For example:

{% button text=_"Translate all pages"
    postback={dialog id=tree_id} delegate="m_translation_tree" %}

The handler checks edit access to the root and visibility of the tree, then renders _dialog_translation_tree.tpl with the resolved id and the language-count map as tree. If these checks fail, it displays an error growl. Opening the dialog does not start a job; the dialog submits a confirmed operation through post/<id>.

Edit on GitHub