TiddlyWiki — очень хорошая штука и я давно ею пользуюсь. Тем не менее, некоторых вещей в ней нет, и это минус. Но её можно творчески допилить напильником, и это плюс.
Понадобился мне прогрессбар. Применений у него куча: показывать степень готовности поста, например. Или количество выполненных дел по сравнению с оставшимися. Да и вообще, наглядная штука.
Поскольку прогрессбара из коробки нет, начал я думать, как бы его добавить. И, для начала, сформулировал к нему требования. В прогрессбаре должна быть возможность задать следующие параметры:
Если какой-то параметр не задан, то он должен вычисляться автоматически.
Для решения подобных задач в TiddlyWiki существуют макросы. Это заранее заданный фрагмент текста, куда можно передать параметры и подставить их в нужные места.
В рамках эксперимента, я набросал пробный макрос, выводящий прогрессбар:
В том же тиддлере (так в TiddlyWiki называется фрагмент текста) дописал внизу вызов этого макроса:
Сохранил тиддлер и полюбовался результатом:
Схема оказалась принципиально рабочей. Но имела кучу несоответствий исходным требованиям. И исправить это было пока нельзя из-за крайней ограниченности создания макросов с помощью формата WikiText. Пришлось разбираться дальше.
В документации обнаружилось упоминание, что макросы можно писать и на JavaScript. Для этого тиддлер макроса должен содержать поле
Если массив
Это уже было хорошо. Но в TiddlyWiki нельзя просто взять и сделать тиддлер с куском JavaScript-а. Вернее, можно, но работать не будет. Чтобы конструкция заработала, её следует надлежащим образом оформить. Например, сделать плагин.
Что есть плагин в терминологии TiddlyWiki? Это некая совокупность тиддлеров, собранная в единое целое, которая помечена как скрытая и не отображается в обычном списке тиддлеров, может встраиваться в систему и запускаться на выполнение, а также может импортироваться из одной wiki в другую парой щелчков.
Первоначально для написания плагинов требовалось развернуть довольно сложную инфраструктуру с использованием node.js. Я когда-то пробовал это делать, но не получилось (не помню уже, по какой причине). Однако, на данный момент разработчик добавил возможность писать плагины прямо в браузере, чем я воспользовался и сейчас расскажу вам, как это делается.
Итак, уважаемые читатели, давайте приступим к созданию плагина. Сверяясь с документацией, скачаем чистый файл TiddlyWiki и начнём делать из него заготовку для плагина.
Первое, что надо сделать, это создать тиддлер HelloThere, настроить его автоматическое отображение при открытии страницы и прописать в нём ссылки на тиддлеры плагина.
Путь к плагину, согласно документации, должен выглядеть так:
Путь к скриптам, входящим в плагин, формируется подобным же образом:
Вот так выглядит мой вариант тиддлера HelloThere:
А это он же в отрисованном виде:
Стоит обратить внимание на две вещи. Во-первых, ссылки даны курсивом, потому что ни плагина, ни скрипта, входящего в его состав, пока не существует. Во-вторых, прогрессбар тоже пока не отрисован — по той же причине.
Чтобы настроить автоматическое отображение тиддлера при открытии страницы надо добавить его в список Default tiddlers. Его можно обнаружить либо в открывающемся по умолчанию тиддлере GettingStarted, либо найти в сайдбаре пиктограмму в виде шестерёнки и нажать её. В появившейся панели настроек ищем Default tiddlers и прописываем туда наш HelloThere.
Всё, первая часть готова. Теперь надо создать тиддлеры плагина и скрипта. Начнём с плагина.
Чтобы создать тиддлер, достаточно щёлкнуть по ссылке на него. Появляется заготовка тиддлера, нажимаем «Редактировать» и редактируем.
Как подсказывает документация, в плагине должны быть прописаны такие поля:
Заполняем поля, а в теле плагина пишем:
Сохраняем тиддлер. Треть работы выполнена.
Аналогичным образом поступаем со второй ссылкой, скриптом макроса. Щёлкаем по ней, нажимаем «Редактировать», заполняем поля:
Теперь само тело скрипта (под спойлером):
Я джаваскриптер не настоящий, пишу на этом языке от случая к случаю, поскольку идиотский сишный синтаксис с фигурными скобками меня очень раздражает. И вообще, это только пример написания плагина.
В общем, сохраняем готовый тиддлер. Всё, что нужно, уже написано. Но не работает, потому что не оформлено.
А сейчас — магия! Открываем консоль JavaScript в браузере и пишем там вот что:
Первый аргумент это имя плагина, который подлежит перепаковке. Второй — список тиддлеров, которые будут включены в плагин. Нажимаем Enter. Браузер говорит, что всё прошло успешно и для того, чтобы изменения возымели действие, надо сохранить и перезагрузить wiki.
Так и сделаем. После переоткрытия в тиддлере HelloThere внезапно появляется красивый зелёненький прогрессбар.
В новой версии TiddlyWiki появилась возможность писать плагины прямо не выходя избассейна браузера. Это позволяет творчески доработать систему под себя, открывает неограниченные горизонты и ещё на один маленький шаг приближает нас к мировому господству.
PS: не уверен в правильности выбора хабов, ибо не совсем понимаю, зачем они нужны. Если что-то сделал неправильно, буду благодарен за разъяснения в комментариях.
Понадобился мне прогрессбар. Применений у него куча: показывать степень готовности поста, например. Или количество выполненных дел по сравнению с оставшимися. Да и вообще, наглядная штука.
Поскольку прогрессбара из коробки нет, начал я думать, как бы его добавить. И, для начала, сформулировал к нему требования. В прогрессбаре должна быть возможность задать следующие параметры:
- цвет заполнения;
- размер;
- подсказку при наведении.
Если какой-то параметр не задан, то он должен вычисляться автоматически.
Для решения подобных задач в TiddlyWiki существуют макросы. Это заранее заданный фрагмент текста, куда можно передать параметры и подставить их в нужные места.
В рамках эксперимента, я набросал пробный макрос, выводящий прогрессбар:
\define progressbar(count:"0" total:"10")
<svg width="$total$5" height="15">
<g>
<title>$count$ из $total$</title>
<rect x="1.5" y="4.5" height="10" width="$count$0" rx="3" ry="3" style="fill: green; stroke: none" />
<rect x="1.5" y="4.5" height="10" width="$total$0" rx="3" ry="3" style="fill: none; stroke: green" />
</g>
</svg>
\end
В том же тиддлере (так в TiddlyWiki называется фрагмент текста) дописал внизу вызов этого макроса:
Прогрессбар: <<progressbar 3 4>>
Сохранил тиддлер и полюбовался результатом:
Схема оказалась принципиально рабочей. Но имела кучу несоответствий исходным требованиям. И исправить это было пока нельзя из-за крайней ограниченности создания макросов с помощью формата WikiText. Пришлось разбираться дальше.
В документации обнаружилось упоминание, что макросы можно писать и на JavaScript. Для этого тиддлер макроса должен содержать поле
module-type
со значением macro
(поля в TiddlyWiki представляют собой метаданные и могут назначаться любому тиддлеру). Скрипт макроса должен экспортировать следующие свойства:name
: Строка, представляющая собой имя, по которому будут вызывать макросparams
: Массив объектов со следующими свойствами:
name
: имя параметраdefault
: (необязательно) значение параметра по умолчанию
run
: Функция, которая будет вызываться при запуске макроса. Параметры извлекаются из вызова макроса и располагаются согласно массиву params. Функцияrun
должна вернуть строковое значение макроса. При вызовеthis
указывает на узел виджета, вызвавшего макрос.
Если массив
params
пуст или отсутствует, то все параметры будут просто переданы в метод run()
.Это уже было хорошо. Но в TiddlyWiki нельзя просто взять и сделать тиддлер с куском JavaScript-а. Вернее, можно, но работать не будет. Чтобы конструкция заработала, её следует надлежащим образом оформить. Например, сделать плагин.
Что есть плагин в терминологии TiddlyWiki? Это некая совокупность тиддлеров, собранная в единое целое, которая помечена как скрытая и не отображается в обычном списке тиддлеров, может встраиваться в систему и запускаться на выполнение, а также может импортироваться из одной wiki в другую парой щелчков.
Первоначально для написания плагинов требовалось развернуть довольно сложную инфраструктуру с использованием node.js. Я когда-то пробовал это делать, но не получилось (не помню уже, по какой причине). Однако, на данный момент разработчик добавил возможность писать плагины прямо в браузере, чем я воспользовался и сейчас расскажу вам, как это делается.
Итак, уважаемые читатели, давайте приступим к созданию плагина. Сверяясь с документацией, скачаем чистый файл TiddlyWiki и начнём делать из него заготовку для плагина.
Первое, что надо сделать, это создать тиддлер HelloThere, настроить его автоматическое отображение при открытии страницы и прописать в нём ссылки на тиддлеры плагина.
Путь к плагину, согласно документации, должен выглядеть так:
$:/plugins/ваше_имя/название_плагина
Путь к скриптам, входящим в плагин, формируется подобным же образом:
$:/plugins/ваше_имя/название_плагина/имя_скрипта.js
Вот так выглядит мой вариант тиддлера HelloThere:
* [[$:/plugins/morthan/progress]]
* [[$:/plugins/morthan/progress/progressbar.js]]
Прогрессбар получает следующие параметры:
; `count`
: Количество выполненного
; `total`
: Количество всего
; `width`
: Если указано --- длина прогрессбара в пикселях
; `color`
: Цвет заполнения (стандартно --- зелёный)
; `title`
: Подсказка, которая выводится при наведении мыши (по умолчанию --- '{count} из {total}')
<<progressbar 30 42 80>>
А это он же в отрисованном виде:
Стоит обратить внимание на две вещи. Во-первых, ссылки даны курсивом, потому что ни плагина, ни скрипта, входящего в его состав, пока не существует. Во-вторых, прогрессбар тоже пока не отрисован — по той же причине.
Чтобы настроить автоматическое отображение тиддлера при открытии страницы надо добавить его в список Default tiddlers. Его можно обнаружить либо в открывающемся по умолчанию тиддлере GettingStarted, либо найти в сайдбаре пиктограмму в виде шестерёнки и нажать её. В появившейся панели настроек ищем Default tiddlers и прописываем туда наш HelloThere.
Всё, первая часть готова. Теперь надо создать тиддлеры плагина и скрипта. Начнём с плагина.
Чтобы создать тиддлер, достаточно щёлкнуть по ссылке на него. Появляется заготовка тиддлера, нажимаем «Редактировать» и редактируем.
Как подсказывает документация, в плагине должны быть прописаны такие поля:
Поле | Значение |
---|---|
dependents |
Список разделённых пробелами плагинов, от которых зависит наш плагин (для названий с пробелами используйте квадратные скобки) |
description |
Описание плагина |
plugin-type |
Для обычного плагина «plugin», для темы «theme», а для языкового пакета «language» |
type |
Задайте «application/json» |
version |
Номер версии плагина (например, «0.0.1») |
{"tiddlers": {}}
Сохраняем тиддлер. Треть работы выполнена.
Аналогичным образом поступаем со второй ссылкой, скриптом макроса. Щёлкаем по ней, нажимаем «Редактировать», заполняем поля:
Поле | Значение |
---|---|
type |
«application/javascript» |
module-type |
«macro» |
Показать код
/*title: $:/plugins/morthan/progress/progressbar.js
type: application/javascript
module-type: macro
Macro to display progressbar
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Information about this macro
*/
exports.name = "progressbar";
exports.params = [
{name: "count"},
{name: "total"},
{name: "width",
default: ""},
{name: "color",
default: "green"},
{name: "title",
default: "{count} из {total}"}
];
/*
Run the macro
*/
exports.run = function(count, total, width, color, title) {
count = parseInt(count);
total = parseInt(total);
width = (width == '') ? total * 10 : parseInt(width);
var html = [svg(width), '<g>', tagTitle(count, total, title),
innerRect(count, total, width, color), outerRect(width), '</g>',
'</svg>'];
return html.join("\n");
};
function svg(width) {
width += 5;
return '<svg width="' + width + '" height="15">';
};
function rect(width, fill) {
return '<rect x="1.5" y="4.5" height="10" width="' + width +
'" rx="3" ry="3" style="fill: ' + fill + '; stroke: green" />';
};
function outerRect(width) {
return rect(width, 'none');
};
function innerRect(count, total, width, color) {
var dx = 0;
if (count > 0 && count != total) {
dx = count * width / total;
}
else if (count == total) {
dx = width;
}
return rect(dx, color);
};
function tagTitle(count, total, title) {
if (title == '') return '';
return '<title>' + title.replace('{count}', count).replace('{total}', total) + '</title>';
};
})();
Я джаваскриптер не настоящий, пишу на этом языке от случая к случаю, поскольку идиотский сишный синтаксис с фигурными скобками меня очень раздражает. И вообще, это только пример написания плагина.
В общем, сохраняем готовый тиддлер. Всё, что нужно, уже написано. Но не работает, потому что не оформлено.
А сейчас — магия! Открываем консоль JavaScript в браузере и пишем там вот что:
$tw.utils.repackPlugin('$:/plugins/morthan/progress', ['$:/plugins/morthan/progress/progressbar.js'])
Первый аргумент это имя плагина, который подлежит перепаковке. Второй — список тиддлеров, которые будут включены в плагин. Нажимаем Enter. Браузер говорит, что всё прошло успешно и для того, чтобы изменения возымели действие, надо сохранить и перезагрузить wiki.
Так и сделаем. После переоткрытия в тиддлере HelloThere внезапно появляется красивый зелёненький прогрессбар.
Заключение
В новой версии TiddlyWiki появилась возможность писать плагины прямо не выходя из
PS: не уверен в правильности выбора хабов, ибо не совсем понимаю, зачем они нужны. Если что-то сделал неправильно, буду благодарен за разъяснения в комментариях.
RPG
Всё же 1.5 МБ для пустой вики, в которой поиск работает криво — это перебор. И это они ещё jQuery выкинули!
Если интересует, у меня есть форк ветки 2.8 с некоторыми изменениями в части разделения движка на составные части (стиль и скрипт отдельными файлами, допилил до удобства использования под Android, а также пытаюсь выбросить зависимость jQuery), быстрый поиск с подсветкой и подсчётом релевантности, улучшенная разметка, CSS3 и т.п. Она пока проходит обкатку, но через некоторое время это можно будет выложить на github.
Morthan Автор
Я так понимаю, автор TiddlyWiki развращён зарубежными провайдерами и считает, что в наш век электроники и пластилина пустая вики на полтора метра — это ничего особенного. В принципе, его можно понять (где-то видел новость, что средний размер веб-страницы уже два метра, на этом фоне TiddlyWiki ещё прилично смотрится).
От форка не откажусь, но сейчас банально нет времени копаться в чём-то новом. Однако, буду благодарен за ссылку на github, когда оный форк там появится.
RPG
Дело не в провайдерах — эта вики создана быть локальной (правда, бекапы растут в геометрической прогрессии — каждый по 2 МБ). Дело в том, что новая версия откровенно тормоз (я ещё учитываю андроид и ноутбуки). Для меня основная суть базы знаний — наличие хорошего поиска. А в TW5 его просто нет, то что они там сделали — поиском назвать сложно. Последний гвоздь в крышку гроба — сложность хакинга. Для 5 версии вон, пришлось целую статью написать, а под 2.х.х просто тонны плагинов придумано, потому что порог вхождения минимальный, у меня пару-тройку вечеров ушло на то, чтобы переделать там поиск, русифицировать, выкинуть поддержку древних браузеров, добавить свою разметку по вкусу и поправить некоторые косяки.
P.S. Если у сообщества появится интерес к развитию 2 ветки — можно сделать полноценный форк с тестами и сборкой.
Morthan Автор
Я от бекапов вообще отказался, держу вики в дропбоксе и полагаюсь на возможность восстановить предыдущую версию. Про тормоза соглашусь. Заставить по-человечески работать андроидную версию у меня пока не получилось.