Skip to content

Instantly share code, notes, and snippets.

@alexey-goloburdin
Created April 22, 2025 13:41
Show Gist options
  • Save alexey-goloburdin/45109c89a914088c885897c5120eee7d to your computer and use it in GitHub Desktop.
Save alexey-goloburdin/45109c89a914088c885897c5120eee7d to your computer and use it in GitHub Desktop.
Настройки Obsidian для моей цифровой библиотеки https://youtu.be/CXBkvKVs0aQ. Файл books.md должен лежать в директории dataviewjs
const CATEGORY_BG_COLORS = {
    "эффективность": "#fff9f2", "разработка": "#ebffff", "edtech": "#f5fff7",
    "съёмка": "#f7f9ff", "художественное": "#fffdf0",
    "психология": "#faf1dd",
    "архитектура ПО": "#fff3f3", "AI": "#dfe6ff",
    //"фронтенд": "red",
    "Python": "#25912b",
    "менеджмент": "#f9fd95",
    "дизайн": "#d324ff",
    "default": "#f5f5f5"
};

const CATEGORY_FONT_COLORS = {
    "Python": "#fff",
    "дизайн": "#ffffec",
};

const getCategoryBgColor = category => {
    return (category in CATEGORY_BG_COLORS) ? CATEGORY_BG_COLORS[category]: CATEGORY_BG_COLORS["default"];
}

const getCategoryFontColor = category => {
    return (category in CATEGORY_FONT_COLORS) ? CATEGORY_FONT_COLORS[category]: CATEGORY_FONT_COLORS["default"];
}


const getBooks = () => {
    const books = dv.pages("")
        .where(page => {
            if (page["Тип"] && page["Тип"].path == "types/Книга.md"
                    && !["templates", "templater"].includes(page.file.folder)){
                return page;
            }
        });
    return books;
};

const formatDate = d => {
    if (!d) return '';
    return d.year === dv.date("now").year
        ? d.toFormat("d MMMM", { locale: "ru" })
        : d.toFormat("d MMMM yyyy", { locale: "ru" });
}

const renderCategories = book => {
    return (book.Категории ? book.Категории : []).map(
        c => `<span class="category" style="background-color: ${getCategoryBgColor(c)}; color: ${getCategoryFontColor(c)};">${c}</span>`
    ).join(" ");
}

const renderBook = (book, additionalBookRenderFunction) => {
    return `<div class="book">
        <a href="${book.file.name}.md" class="internal-link" target="_blank" rel="noopener nofollow"><img src="${book.Обложка}" data-filename="${book.file.name}" /></a>
        ${book.Progress}
        ${additionalBookRenderFunction(book)}
        <div class="categories">${renderCategories(book)}</div>
        <div class="pages">${book.Страниц} стр.</div>
    </div>`;
}

const renderBooks = (booksFiles, additionalBookRenderFunction) => {
    let booksHtml = [];
    for (const book of booksFiles) {
        booksHtml.push(renderBook(book, additionalBookRenderFunction))
    }
	return booksHtml.join("");
}

window.books = {getBooks, formatDate, renderBooks};
/* Base settings for all page width */
.wide-100 .cm-contentContainer, .wide-100 .cm-content, .wide-100 .cm-line,
.wide .cm-contentContainer, .wide .cm-content, .wide .cm-line,
.wide-95 .cm-contentContainer, .wide-95 .cm-content, .wide-95 .cm-line,
.wide-90 .cm-contentContainer, .wide-90 .cm-content, .wide-90 .cm-line,
.wide-85 .cm-contentContainer, .wide-85 .cm-content, .wide-85 .cm-line,
.wide-80 .cm-contentContainer, .wide-80 .cm-content, .wide-80 .cm-line,
.wide-75 .cm-contentContainer, .wide-75 .cm-content, .wide-75 .cm-line,
.wide-70 .cm-contentContainer, .wide-70 .cm-content, .wide-70 .cm-line,
.wide-65 .cm-contentContainer, .wide-65 .cm-content, .wide-65 .cm-line,
.wide-60 .cm-contentContainer, .wide-60 .cm-content, .wide-60 .cm-line,
.wide-55 .cm-contentContainer, .wide-55 .cm-content .wide-55 .cm-line
{
width: 100% !important;
max-width: 100% !important;
}
/* 100% page width for page with attribute cssclasses=wide-100 or cssclasses=wide */
.wide-100 .cm-sizer, .wide-100 .cm-contentContainer, .wide-100 .cm-content, .wide-100 .markdown-preview-sizer,
.wide .cm-sizer, .wide .cm-contentContainer, .wide .cm-content, .wide .markdown-preview-sizer
{
width: 100% !important;
max-width: 100% !important;
}
/* 95% page width for page with attribute cssclasses=wide-95 */
.wide-95 .cm-sizer, .wide-95 .markdown-preview-sizer {
width: 95% !important;
max-width: 95% !important;
}
/* 90% page width for page with attribute cssclasses=wide-90 */
.wide-90 .cm-sizer, .wide-90 .markdown-preview-sizer {
width: 90% !important;
max-width: 90% !important;
}
/* 85% page width for page with attribute cssclasses=wide-85 */
.wide-85 .cm-sizer, .wide-85 .markdown-preview-sizer {
width: 85% !important;
max-width: 85% !important;
}
/* 80% page width for page with attribute cssclasses=wide-80 */
.wide-80 .cm-sizer, .wide-80 .markdown-preview-sizer {
width: 80% !important;
max-width: 80% !important;
}
/* 75% page width for page with attribute cssclasses=wide-75 */
.wide-75 .cm-sizer, .wide-75 .markdown-preview-sizer {
width: 75% !important;
max-width: 75% !important;
}
/* 70% page width for page with attribute cssclasses=wide-70 */
.wide-70 .cm-sizer, .wide-70 .markdown-preview-sizer {
width: 70% !important;
max-width: 70% !important;
}
/* 65% page width for page with attribute cssclasses=wide-65 */
.wide-65 .cm-sizer, .wide-65 .markdown-preview-sizer {
width: 65% !important;
max-width: 65% !important;
}
/* 60% page width for page with attribute cssclasses=wide-60 */
.wide-60 .cm-sizer, .wide-60 .markdown-preview-sizer {
width: 60% !important;
max-width: 60% !important;
}
/* 55% page width for page with attribute cssclasses=wide-55 */
.wide-55 .cm-sizer, .wide-55 .markdown-preview-sizer {
width: 55% !important;
max-width: 55% !important;
}
/* Cosmetics for metadata and code blocks */
.cm-preview-code-block:hover {
box-shadow: none !important;
}
.metadata-properties-title {color: #d5d5d5; content:"Свойства";}
.metadata-properties-heading .collapse-indicator {display: none;}
/* Books render classes */
.books > span {
padding: 15px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
grid-auto-rows: minmax(300px, auto);
gap: 10px;
height: 100%;
}
.books img {
cursor: pointer;
height: 250px !important;
display: block;
margin: 0 auto 10px auto;
}
.books p[dir=auto] {margin: 0;}
.books progress {display: block !important; margin: 0 auto;}
.books .book {text-align: center;}
.books .book .pages {color: #9e9e9e; font-size: 0.75em;}
.books .book .category {
display: inline-block;
margin-bottom: 0.3em;
background-color: #f7efc3;
border-radius: 3px;
padding: 0px 7px;
width: auto;
font-size: 0.75em;
}
.popover {display: none !important;}
cssclasses
wide-85

Читаю сейчас ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && !page["Закончил читать"] && page["Начал читать"]) {return page;}}).length)

// import code
eval(
    (await app.vault.read(app.vault.getAbstractFileByPath("dataviewjs/books.md")))
    .replace("```js", "").replace("```", "")
);

const booksFiles = window.books.getBooks()
    .where(page => {
        if (!page["Закончил читать"] && page["Начал читать"]) {return page;}
    })
    .sort(p => p["Начал читать"], "desc");

dv.el("div", window.books.renderBooks(booksFiles, book => `начал ${window.books.formatDate(book["Начал читать"])}<br>`), {cls: "books"});

[!abstract] Купить

  • [[Книга «Не может быть. Парадоксы в рекламе, бизнесе и жизни», Алексей Иванов]]
  • [[Книга «Альтернейт. Сверхцели. Счастье. Баланс», Оскар Хартман]]
  • [[Книга «Безопасно by design», Джонсон Дэн Берг, Дэниел Деоган]]
  • [[Книга «Последняя лекция», Пауш Рэнди]]
  • [[Книга «Искусство объяснять. Как сделать так, чтобы вас понимали с полуслова», ЛеФевер Ли]]
  • [[Книга «Поиск на основе искусственного интеллекта», Трей Грейнджер]]

[!info] TODO

Прочитанное в 2025

let booksCount = 0;

let bookPages = dv.pages("").where(page => {
    if (page["Тип"] && page["Тип"].path == "types/Книга.md" && page.file.folder != "templates" && page["Закончил читать"] && new Date(page["Закончил читать"].ts).getFullYear() === 2025) {
	  booksCount++;
      return page;
    }
}).sort(p => p["Закончил читать"], "desc");

const MAX_BOOK_NAME_LENGTH = 50;
let index = booksCount + 1;

dv.table(
    ["", "Название", "Автор", "Страниц", "Прочитал"],
    bookPages.map(p => {
        const shortName = p.Название.length > MAX_BOOK_NAME_LENGTH  
            ? p.Название.substring(0, MAX_BOOK_NAME_LENGTH) + "..." 
            : p.Название;
		const authors = p.Автор.split(",").map(el => el.trim()).join("<br />");
        return [
			--index,
            dv.fileLink(p.file.path, false, shortName),
            authors,
            p.Страниц,
            p["Закончил читать"] !== null ? p["Закончил читать"] :
            ""
        ];
    })
);
  • [[Все книги]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder)) {return page;}}).length)
  • [[Все книги таблицей]]
  • [[Книги по категориям]]
cssclasses
wide-85

Все книги таблицей

let i = 1;
dv.table(["#", "Имя"], 
  dv.pages()
    .where(p => p["Тип"] && p["Тип"].path === "types/Книга.md")
    .where(p => !["templates", "templater"].includes(p.file.folder))
    .sort(p => p.file.name)
    .map(p => [i++, p.file.link])
)
cssclasses
wide-85

Python ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("Python")) {return page;}}).length)

// import code
eval(
    (await app.vault.read(app.vault.getAbstractFileByPath("dataviewjs/books.md")))
    .replace("```js", "").replace("```", "")
);

const booksFiles = window.books.getBooks()
    .where(p => p["Категории"].contains("Python"))
    .sort(p => p["Добавлена в базу"], "desc");

dv.el("div", window.books.renderBooks(booksFiles, book => `добавлена ${window.books.formatDate(book["Добавлена в базу"])}<br>`), {cls: "books"});
cssclasses
wide-85

Разработка ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("разработка")) {return page;}}).length)

// import code
eval(
    (await app.vault.read(app.vault.getAbstractFileByPath("dataviewjs/books.md")))
    .replace("```js", "").replace("```", "")
);

const booksFiles = window.books.getBooks()
    .where(p => p["Категории"].contains("разработка"))
    .sort(p => p["Добавлена в базу"], "desc");

dv.el("div", window.books.renderBooks(booksFiles, book => `добавлена ${window.books.formatDate(book["Добавлена в базу"])}<br>`), {cls: "books"});
cssclasses
wide-85

IT

[[Книги категории «разработка»|разработка]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("разработка")) {return page;}}).length), [[Книги категории «архитектура ПО»|архитектура ПО]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("архитектура ПО")) {return page;}}).length) [[Книги категории «Python»|Python]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("Python")) {return page;}}).length), [[Книги категории «Go»|Go]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("Go")) {return page;}}).length), [[Книги категории «typescript»|TypeScript]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("typescript")) {return page;}}).length), [[Книги категории «rust»|Rust]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("rust")) {return page;}}).length) [[Книги категории «PostgreSQL»|PostgreSQL]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("PostgreSQL")) {return page;}}).length), [[Книги категории «linux»|Linux]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("linux")) {return page;}}).length), [[Книги категории «фронтенд»|фронтенд]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("фронтенд")) {return page;}}).length), [[Книги категории «devops»|DevOps]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("devops")) {return page;}}).length), [[Книги категории «инфобез»|инфобез]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("инфобез")) {return page;}}).length), [[Книги категории «алгоритмы»|алгоритмы]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("алгоритмы")) {return page;}}).length), [[Книги категории «микросервисы»|микросервисы]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("микросервисы")) {return page;}}).length)

Бизнесовое

[[Книги категории «про бизнес»|про бизнес]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("про бизнес")) {return page;}}).length), [[Книги категории «стартапы»|стартапы]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("стартапы")) {return page;}}).length), [[Книги категории «управление продуктом»|управление продуктом]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("управление продуктом")) {return page;}}).length) [[Книги категории «менеджмент»|менеджмент]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("менеджмент")) {return page;}}).length), [[Книги категории «HR»|HR]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("HR")) {return page;}}).length), [[Книги категории «маркетинг»|маркетинг]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("маркетинг")) {return page;}}).length), [[Книги категории «интернет-маркетинг»|интернет-маркетинг]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("интернет-маркетинг")) {return page;}}).length) [[Книги категории «переговоры»|переговоры]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("переговоры")) {return page;}}).length), [[Книги категории «продажи»|продажи]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("продажи")) {return page;}}).length) [[Книги категории «экономика и инвестиции»|экономика и инвестиции]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("экономика и инвестиции")) {return page;}}).length) [[Книги категории «rroom»|rroom]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("rroom")) {return page;}}).length)

Публичность

[[Книги категории «съёмка»|съёмка]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("съёмка")) {return page;}}).length), [[Книги категории «YouTube»|YouTube]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("YouTube")) {return page;}}).length) [[Книги категории «личный бренд»|личный бренд]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("личный бренд")) {return page;}}).length) [[Книги категории «копирайтинг»|копирайтинг]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("копирайтинг")) {return page;}}).length), [[Книги категории «сторителлинг»|сторителлинг]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("сторителлинг")) {return page;}}).length), [[Книги категории «ораторское»|ораторское]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("ораторское")) {return page;}}).length)

EdTech

[[Книги категории «edtech»|edtech]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("edtech")) {return page;}}).length)

Как жить

[[Книги категории «как жить»|как жить]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("как жить")) {return page;}}).length), [[Книги категории «психология»|психология]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("психология")) {return page;}}).length) [[Книги категории «философия»|философия]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("философия")) {return page;}}).length), [[Книги категории «стоицизм»|стоицизм]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("стоицизм")) {return page;}}).length)

Остальное

[[Книги категории «художественное»|художественное]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("художественное")) {return page;}}).length) [[Книги категории «историческое»|историческое]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("историческое")) {return page;}}).length) [[Книги категории «дизайн»|дизайн]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("дизайн")) {return page;}}).length) [[Книги категории «AI»|AI]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("AI")) {return page;}}).length) [[Книги категории «медицина»|медицина]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("медицина")) {return page;}}).length) [[Книги категории «научное»|научное]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("научное")) {return page;}}).length) [[Книги категории «военное»|военное]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("военное")) {return page;}}).length) [[Книги категории «юридическое»|юридическое]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("юридическое")) {return page;}}).length) [[Книги категории «спорт»|спорт]] ($= dv.pages("").where(page => {if (page["Тип"] && page["Тип"].path == "types/Книга.md" && !["templates", "templater"].includes(page.file.folder) && page.Категории.contains("спорт")) {return page;}}).length)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment