@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix content: <http://purl.org/rss/1.0/modules/content/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<https://lhero.org/portfolio/lh-tasks/>
  a sioc:Post ;
  dc:title "Master tasks and subtasks" ;
  dcterms:identifier 152258 ;
  dc:modified "2026-10-24T00:23:15Z"^^xsd:dateTime ;
  dc:created "2026-10-23T23:07:56Z"^^xsd:dateTime ;
  sioc:link <https://lhero.org/portfolio/lh-tasks/master-tasks-and-subtasks/> ;
  sioc:has_creator <https://lhero.org/author/1/#account> ;
  sioc:has_container <https://lhero.org/#posts> ;
  content:encoded "<ul class=\"lh_portfolio-meta\"><li><strong>Part of:</strong> <a href=\"https://lhero.org/portfolio/lh-tasks/\">LH Tasks</a></li></ul><p class=\"wp-block-paragraph\">Since 1.24.0 (#152206) a task can be a subtask of a master task. <code>LH_Tasks_subtasks_class</code> (<code>includes/lh-tasks-subtasks-class.php</code>) owns the relationship, the rollup and Markdown checklist rendering.</p><h3 class=\"wp-block-heading\">Relationship</h3><ul class=\"wp-block-list\"><li>The master is stored in <code>post_parent</code>. The post type stays non-hierarchical, so task URLs are unchanged; subtasks are read straight from the posts table, so attachments parented to a task never count.</li><li>One level deep: <code>validate_parent_id()</code> refuses the task itself, a missing or trashed task, a master that is itself a subtask, and making a task that has subtasks into one.</li><li><code>create-task</code> and <code>update-task</code> take <code>parent_id</code> (0 on update makes a task standalone again), <code>list-tasks</code> filters by it, and <code>get-task</code> returns <code>parent_id</code> and <code>children</code> (task_id, title, status, due_date, assigned_to; soonest due first, undated last). <code>parent_id</code> is in the default list fields.</li></ul><h3 class=\"wp-block-heading\">Who can see a master</h3><p class=\"wp-block-paragraph\">Since 1.25.0 (#152259) <code>LH_Tasks_visibility_class::current_user_can_view_task()</code> also lets anyone who is the hard assignment or claimant of one of a task&#8217;s subtasks read it. A master is usually left unassigned for staff while its subtasks go to one person (a captain, say), and the email they get links to the master, which they could not open before.</p><h3 class=\"wp-block-heading\">Rollup</h3><p class=\"wp-block-paragraph\"><code>LH_Tasks_status_table_class::set_status()</code> fires <code>lh_tasks_task_status_changed</code> (<code>$post_id, $status, $from_status</code>) on every workflow change. When a subtask changes, or is trashed, its open master is recomputed:</p><ul class=\"wp-block-list\"><li><strong>Any subtask Failed:</strong> the master moves to Pending, logged as <code>subtask_failed</code>, and <code>lh_tasks_task_subtask_failed</code> fires.</li><li><strong>Every subtask finished</strong> (Resolved, Closed or Cancelled): the master resolves, logged as <code>subtasks_complete</code>, and <code>lh_tasks_task_completed</code> fires. Cancelled counts as finished because only staff can cancel and it means the item does not apply. A subtask Awaiting review is not finished until it is accepted.</li><li>A finished master is left alone. Moving a subtask between masters with <code>update-task</code> recomputes both.</li></ul><h3 class=\"wp-block-heading\">Task page</h3><p class=\"wp-block-paragraph\">The task page is written for the person doing the work, who is often new to the system (1.25.0, #152259).</p><ul class=\"wp-block-list\"><li>A master shows a Subtasks checklist with progress (&#8220;3 of 5 done&#8221;). Each row has a disabled checkbox for done or not done, the subtask&#8217;s title linking to it, and plain words: &#8220;due Thursday 12 November 2026 (20 days left)&#8221; while open, Waiting to be checked while it is with its reviewer, Done once finished. The owner is shown unless it is the viewer. Internal status names are not shown in rows.</li><li>Whoever may mark a subtask done gets a button after the row, reading <strong>Mark for review</strong> when someone else will check it (<code>needs_review()</code>) and Mark as done otherwise. It posts to the master&#8217;s page (field <code>lh_tasks_single_task_return_to</code>) and comes back there. The done form on a task&#8217;s own page uses the same wording.</li><li>A subtask shows Part of, linking to its master.</li><li>Due dates include the weekday (filter <code>lh_tasks_due_date_format</code>, default <code>l j F Y</code>), with days left or overdue while the task is open. The progress log is headed Timeline and ends with the task&#8217;s creation.</li><li>People who are not staff (the task capability) see a plain status in the details (To do, Waiting to be checked, Done, or the label of another finished state), and the Timeline leaves out staff records: <code>updated</code>, <code>admin_override</code>, <code>heartbeat</code>, <code>claimed</code> and <code>reassigned</code> (filter <code>lh_tasks_return_staff_only_events</code>). Staff see everything.</li><li>List items in a description starting <code>[ ]</code> or <code>[x]</code> render as read-only checkboxes. lh-content-converter does not yet keep Markdown task lists in that form (#152257), so this only works for HTML written that way for now.</li></ul><h3 class=\"wp-block-heading\">Admin</h3><p class=\"wp-block-paragraph\">The Tasks list has a Subtasks column: Part of the master on a subtask, or N of M done on a master, linking to <code>edit.php?post_type=lh_tasks-task_post&amp;lh_tasks_parent=ID</code>, which lists that master&#8217;s subtasks. Setting the master from the block editor sidebar is not available yet: use the abilities.</p>"^^rdf:XMLLiteral ;
  sioc:content "Part of: LH TasksSince 1.24.0 (#152206) a task can be a subtask of a master task. LH_Tasks_subtasks_class (includes/lh-tasks-subtasks-class.php) owns the relationship, the rollup and Markdown checklist rendering.RelationshipThe master is stored in post_parent. The post type stays non-hierarchical, so task URLs are unchanged; subtasks are read straight from the posts table, so attachments parented to a task never count.One level deep: validate_parent_id() refuses the task itself, a missing or trashed task, a master that is itself a subtask, and making a task that has subtasks into one.create-task and update-task take parent_id (0 on update makes a task standalone again), list-tasks filters by it, and get-task returns parent_id and children (task_id, title, status, due_date, assigned_to; soonest due first, undated last). parent_id is in the default list fields.Who can see a masterSince 1.25.0 (#152259) LH_Tasks_visibility_class::current_user_can_view_task() also lets anyone who is the hard assignment or claimant of one of a task&#8217;s subtasks read it. A master is usually left unassigned for staff while its subtasks go to one person (a captain, say), and the email they get links to the master, which they could not open before.RollupLH_Tasks_status_table_class::set_status() fires lh_tasks_task_status_changed ($post_id, $status, $from_status) on every workflow change. When a subtask changes, or is trashed, its open master is recomputed:Any subtask Failed: the master moves to Pending, logged as subtask_failed, and lh_tasks_task_subtask_failed fires.Every subtask finished (Resolved, Closed or Cancelled): the master resolves, logged as subtasks_complete, and lh_tasks_task_completed fires. Cancelled counts as finished because only staff can cancel and it means the item does not apply. A subtask Awaiting review is not finished until it is accepted.A finished master is left alone. Moving a subtask between masters with update-task recomputes both.Task pageThe task page is written for the person doing the work, who is often new to the system (1.25.0, #152259).A master shows a Subtasks checklist with progress (&#8220;3 of 5 done&#8221;). Each row has a disabled checkbox for done or not done, the subtask&#8217;s title linking to it, and plain words: &#8220;due Thursday 12 November 2026 (20 days left)&#8221; while open, Waiting to be checked while it is with its reviewer, Done once finished. The owner is shown unless it is the viewer. Internal status names are not shown in rows.Whoever may mark a subtask done gets a button after the row, reading Mark for review when someone else will check it (needs_review()) and Mark as done otherwise. It posts to the master&#8217;s page (field lh_tasks_single_task_return_to) and comes back there. The done form on a task&#8217;s own page uses the same wording.A subtask shows Part of, linking to its master.Due dates include the weekday (filter lh_tasks_due_date_format, default l j F Y), with days left or overdue while the task is open. The progress log is headed Timeline and ends with the task&#8217;s creation.People who are not staff (the task capability) see a plain status in the details (To do, Waiting to be checked, Done, or the label of another finished state), and the Timeline leaves out staff records: updated, admin_override, heartbeat, claimed and reassigned (filter lh_tasks_return_staff_only_events). Staff see everything.List items in a description starting [ ] or [x] render as read-only checkboxes. lh-content-converter does not yet keep Markdown task lists in that form (#152257), so this only works for HTML written that way for now.AdminThe Tasks list has a Subtasks column: Part of the master on a subtask, or N of M done on a master, linking to edit.php?post_type=lh_tasks-task_post&amp;lh_tasks_parent=ID, which lists that master&#8217;s subtasks. Setting the master from the block editor sidebar is not available yet: use the abilities." ;
  sioc:topic <https://lhero.org/?taxonomy=author&term=cap-1> .

<https://lhero.org/author/1/#account> rdfs:seeAlso <https://lhero.org/author/1/?feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=author&term=cap-1> rdfs:seeAlso <https://lhero.org/?taxonomy=author&term=cap-1&feed=lhrdf&format=turtle> .
