Суть идеи

Допустим, пишем мы какой-то контент - статью в блог, например. И в процессе возникает идея - дописать еще абзац о чем-то, вставить картинку или ссылку на статью, которую потом планируем написать. Программисты в таком случае в коде обычно используют комментарии с пометкой @TODO - потом можно быстро найти все задачи прямо в проекте.

Решение

Я решил использовать такой же метод - задачи можно ставить прямо в содержимом ресурса. Достаточно написать "@TODO: Сделать что-то", и обернуть это в HTML комментарий, чтобы эта информация не отображалась посетителям на сайте. Потом создать виджет и вывести его на главную страницу админки - таким образом накопившиеся задачи будут мозолить глаза и автоматически напоминать о себе.

Для удобства прямо в виджете выводим ID ресурса и ссылку на него, чтобы можно было сразу перейти к редактированию, не копаясь в дереве ресурсов. Чтобы убрать задачу - нужно удалить ее текст из содержимого ресурса.

Реализация в MODX

Для начала создаем ресурс (или используем существующий) и добавляем в содержимое ресурса задачу - <!-- @TODO: Какая-нибудь задача -->.

Переходим в «Настройки>Панели управления>Виджеты» и создаем виджет. Название любое, я назову «widget_todo_list». Значение «Размер» лучше установить «На всю ширину». Выбираем тип виджета «Сниппет», и сразу вписываем название сниппета (пока просто название, создадим мы его дальше) в поле «Содержимое виджета». Название сниппета также можно использовать любое, я назову «WidgetTodoList».

Теперь привяжем созданный виджет к панели управления. Возвращаемся в «Настройки>Панели управления>Панели управления». По умолчанию там будет всего одна панель - «Default». Заходим в редактирование панели и жмем кнопку «Добавить виджет». Во всплывающем окне выбираем ранее созданный виджет «widget_todo_list», жмем «Сохранить». Виджет должен появиться в таблице с другими виджетами.

Чтобы настроить, в каком порядке они будут отображаться - введите числовое значение в таблицу в столбец "Сортировка". Наименьшие значения будут вверху, наибольшие - внизу. Я хочу, чтобы задачи были в самом начале, поэтому ставлю 0.

Теперь осталось создать сам сниппет - php скрипт, который будет получать из базы данных содержимое ресурсов, обрабатывать их и генерировать содержимое виджета - таблицу с задачами и ссылками на ресурса. Создаем новый сниппет, называем, как записывали ранее в содержимом виджета - WidgetTodoList.

Сам скрипт будет такой (возможно, есть смысл вынести html в чанки, чтобы не смешивать html и php, но кода тут не так много, так что я решил не усложнять и все объединить в одном месте):


<?php
/* Сниппет для создания виджета для панели управления @TODO

Алгоритм работы:
- Выбираем из базы данных все ресурсы, где в поле content есть <!-- @TODO: Текст задачи →
- Проходим циклом по полученным ресурсам, выбираем все задачи в массив регулярным выражением
- Генерируем и возвращаем таблицу с задачами
*/

$query = $modx->newQuery('modResource');
$query->where(array('content: LIKE ' => '%@TODO:%'));
$query->select('id,content,pagetitle');
$resourses = $modx->getCollection('modResource', $query, false);

$todo_array = [];
$todo_regexp = "<!--[ ]{0,}@TODO:[ ]{0,}(.*?)-->";

foreach ($resourses as $resourse) {
    $id = $resourse->get('id');
    $pagetitle = $resourse->get('pagetitle');
    preg_match_all($todo_regexp, $resourse->get('content'), $out);
    $tasks = $out[1];
    if ($tasks) {
        foreach ($tasks as $task) {
            array_push($todo_array, array('id'=>$id, 'task'=>$task, 'pagetitle'=>$pagetitle));
        }
    }
}

$content = '
<style>
.panel-widget-todolist {
    font-size: 14px;
    width: 100%;
    border-collapse: collapse;
    color: #444;
}
.panel-widget-todolist thead {
    background-color: #D3DCE3;
    font-weight: bold;
    color: dimgray;
}
.panel-widget-todolist td {
    padding: 0.6em 18px 0.6em 5px;
    border: 1px solid #ddd;
}
.panel-widget-todolist td:nth-child(1) {
    width: 40px;
}
</style>';

$content .= "<h2>Всего задач: " . count($todo_array) . "</h2>";
$content .= "<table class='panel-widget-todolist' cellspacing='0' cellpadding='0'>";
$content .= "<thead><tr><td>ID</td><td>Задача</td></tr></thead><tbody>";

foreach ($todo_array as $todo) {
    $content .= "<tr><td><a title='" . $todo['pagetitle'] . "' href='?a=resource/update&id=" . $todo['id'] . "' target='_blank'>" . $todo['id'] . "</a></td>";
    $content .= "<td>" . $todo['task'] . "</td></tr>";
}

$content .= "</tbody></table>";
return $content;

Сохраняем и переходим на главную страницу админки - должен появиться виджет с таблицей задач. У каждой задачи указан ID ресурса, в котором она находится. ID обернут в ссылку на этот ресурс в админке, так что можно сразу переходить и редактировать. Названия ресурсов прописаны в атрибуте «title» ссылки, так что при наведении на нее можно посмотреть название ресурса.