/**
 * Recursively list the pages under a page for editing.
 *
 * @param ExhibitPage $page A page to list.
 * @return string
 */
function exhibit_builder_edit_page_list($page)
{
    $pageId = html_escape($page->id);
    $html = '<li class="page" id="page_' . $pageId . '">' . '<div class="sortable-item">' . '<a href="../edit-page/' . $pageId . '">' . html_escape($page->title) . '</a>' . '<a class="delete-toggle delete-element" href="#">' . __('Delete') . '</a>' . '</div>';
    if ($children = $page->getChildPages()) {
        $html .= '<ul>';
        foreach ($children as $child) {
            $html .= exhibit_builder_edit_page_list($child);
        }
        $html .= '</ul>';
    }
    $html .= '</li>';
    return $html;
}
<ul id="page-list" class="sortable">
    <?php 
foreach ($exhibit->TopPages as $page) {
    ?>
        <?php 
    echo exhibit_builder_edit_page_list($page);
    ?>
    <?php 
}
?>
    <?php 
echo $this->formHidden('pages-hidden');
?>
    <?php 
echo $this->formHidden('pages-delete-hidden');
?>
</ul>

<script type="text/javascript">
Omeka.addReadyCallback(Omeka.ExhibitBuilder.enableSorting);
Omeka.addReadyCallback(Omeka.ExhibitBuilder.activateDeleteLinks);
Omeka.addReadyCallback(Omeka.ExhibitBuilder.setUpFormSubmission);
</script>