Ссылки, которые переживают переименование

Productivity

Каждый, кто больше года ведёт архив заметок со ссылками, встречал эту ошибку.

Вы завели заметку Q3 planning. За восемь месяцев на неё стали ссылаться тридцать других заметок. Потом третий квартал закончился, и вы переименовали её в Q3 planning (2025) — очевидно правильный шаг.

Тридцать ссылок сломались. Без шума. Они по-прежнему отображаются, по-прежнему выглядят как ссылки и теперь ведут на заметку, которой нет. Некоторые системы услужливо предлагают её создать, и в вашем графе поселяется вторая, пустая Q3 planning.

Причина в том, что большинство вики-приложений для заметок хранят ссылку как название. [[Q3 planning]] — это буквально строка «Q3 planning», и при отображении приложение ищет заметку с таким именем. Ссылка — догадка, которая чаще всего оказывается верной.

Notez хранит id.

Что вставляет [[

Наберите [[ в редакторе, и откроется список заметок рабочего пространства. Выберите заметку или создайте новую прямо из этого списка, и в документ попадёт узел с двумя полями:

  • noteId — настоящий идентификатор целевой заметки

  • fallbackTitle — название на момент вставки

Ссылка — это id. Запасное название — подпись на крайний случай.

При отображении чип находит целевую заметку по id и показывает её текущее название. Переименуйте заметку, и все чипы, которые на неё указывают, сразу обновятся везде. Ничего не нужно чинить: ни массового поиска с заменой по архиву, ни отчёта о «неразрешённых ссылках», который приходится разбирать в воскресенье.

Ещё это значит, что ссылки однозначны, чего ссылки по названию добиться не могут. У двух заметок может быть одно название. Одного id у двух заметок быть не может.

Обратные ссылки — это запрос, а не функция, которую надо поддерживать

Раз ссылка хранит id конкретной заметки, обратное направление достаётся даром.

При каждом сохранении заметки Notez обходит сохранённый документ, собирает id заметок, на которые он ссылается, и сверяет этот набор с тем, что было записано раньше: новые ссылки добавляет, удалённые удаляет. Таблица ссылок — чистая функция от вашего текста. Разойтись с тем, что вы написали, она не может, потому что при каждом сохранении собирается заново из того, что вы написали.

Кое-что при этом отсеивается, и у каждого фильтра своя причина:

  • Ссылки на себя. Ссылка заметки на саму себя — не связь.

  • Заметки из других рабочих пространств. Остаются только заметки того же пространства. Поэтому ссылка в рабочем пространстве для работы никогда не выдаст, что у вас есть какая-то личная заметка, и дело не в правиле, а в том, как устроена система.

  • Некорректные id. В заметках из импорта, пока импорт не связал их между собой, могут оставаться неразрешённые ссылки-заглушки. Их отбрасывают, чтобы сохранение не падало.

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

Два вида ссылок, и это намеренно

Ссылки [[ в тексте — не единственный способ связать заметки. Второй — пользовательское свойство типа Связь: типизированное поле заметки, значение которого — другая заметка. Например, свойство Client в каждой заметке о встрече, которое указывает на заметку этого клиента.

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

Причина — ошибка, которую я не хочу выпустить второй раз. Сверка при сохранении сравнивает весь набор ссылок заметки и удаляет всё, чего нет в тексте. Если бы связи из свойств лежали в той же таблице, следующее сохранение текста заглянуло бы в документ, не нашло бы их и удалило. Ваши связи Client исчезали бы по одной заметке ровно в момент правки — то есть незаметно и только в самых активных заметках.

Поэтому два вида хранятся отдельно и объединяются при чтении. Каждое чтение чуть дороже, зато один вид не может молча съесть другой.

Для вас на практике разница такая:

  • Ссылки в тексте — часть прозы. Их место посреди предложения, там, где связь — ваша мысль: «это следует из [[разбора инцидента с ретраями]]».

  • Свойства-связи — структура. Они нужны, когда у каждой заметки одного типа есть такой указатель и по нему хочется фильтровать и сортировать.

Пользуйтесь обоими. Они отвечают на разные вопросы.

Граф

Когда ссылки указывают на конкретные записи, граф — это отрисовка данных, которые уже есть, а не отдельная система. Раздел «Связанные заметки» любой заметки можно смотреть списком или графом: на что она ссылается и что ссылается на неё.

Одна оговорка: граф полезен для локального исследования — увидеть окрестности одной заметки, заметить скопление, которое вы не планировали. Как картина всего архива он полезен гораздо меньше. Десять тысяч заметок, нарисованных клубком, — это заставка для экрана. Я сделал локальный граф.

Что происходит со ссылками в публичной заметке

Поделитесь заметкой по публичной ссылке, и ссылки в её тексте поведут себя осторожно. У публичной страницы нет доступа к вашему рабочему пространству, поэтому чип показывает fallbackTitle, сохранённый при вставке, — здесь подпись на крайний случай наконец пригождается — и становится рабочей ссылкой, только если целевая заметка тоже опубликована.

Если нет, чип отображается неактивным серым текстом. Читатель видит, что здесь на что-то ссылаются, но не узнаёт текущее название и не может туда попасть.

Это правильное поведение по умолчанию, и его стоит знать, прежде чем делиться заметкой: опубликованная заметка не вытаскивает связанные заметки в открытый доступ. Если нужно, чтобы читался весь связанный набор, поделитесь каждой заметкой из него.

Как этим пользоваться на практике

Ссылки — из тех функций, которые легко распланировать до мелочей и потом забросить. Что работает:

  1. Ставьте ссылку, пока пишете, а не потом. Когда вы набираете фразу о том, что уже записывали, вы точно знаете, что связь есть. Потом вы этого не вспомните.

  2. Не связывайте всё подряд. Заметка, на которую ссылаются из сорока мест, ничего вам не говорит. Ссылки несут смысл, только когда стоят выборочно.

  3. Прежде чем писать новую заметку, посмотрите обратные ссылки. Откройте заметку по теме, посмотрите, что на неё уже ссылается, и часто окажется, что большую часть новой заметки вы написали восемь месяцев назад.

  4. Превратите повторяющуюся ссылку в свойство-связь. Если вы вручную ссылаетесь на заметку клиента из каждой заметки о встрече, это уже не проза, а поле. Сделайте его полем и получите фильтры и сортировку бесплатно.

  5. Переименовывайте смело. Ради этого всё и сделано. Название — описание, а не идентификатор, и его можно улучшать всякий раз, когда приходит вариант получше.

Это тихое преимущество ссылок по id, и проявляется оно не сразу. В системе со ссылками по названию вы постепенно перестаёте переименовывать, потому что переименование чего-то стоит и вы уже обжигались. В итоге архив полон названий, с которыми вы просто смирились.

Когда ссылки переживают переименование, названия со временем становятся лучше.

Читайте также