Fase B3+B4: built-in Project/Area tags and Citation class

B3: registers :logseq.class/Project and :logseq.class/Area as
built-in page-like classes (the TODO in class.cljs already asked for
this), so users can tag pages/journals with them out of the box.
Fixed a markdown-mirror test whose "Custom Tag" fixture used to be
titled "Project" and collided with the new built-in class.

B4: adds :logseq.class/Citation plus /target and /context properties,
following the :logseq.class/Comments pattern. Since target is a
:node-typed ref, citation blocks automatically show up in the
existing block/citation reference graph without any changes there.
This commit is contained in:
2026-08-26 19:03:14 +02:00
parent fcf41c7b41
commit b67f7e9f78
4 changed files with 44 additions and 6 deletions

View File

@@ -51,6 +51,12 @@
{:title "Comment"
:properties {:logseq.property.class/hide-from-node true}}
:logseq.class/Citation
{:title "Citation"
:properties {:logseq.property/icon {:type :tabler-icon :id "quote"}}
:schema {:properties [:logseq.property.citation/target :logseq.property.citation/context]
:required-properties [:logseq.property.citation/target]}}
:logseq.class/Query
{:title "Query"
:properties {:logseq.property/icon {:type :tabler-icon :id "search"}}
@@ -101,7 +107,15 @@
{:title "Template"
:schema {:properties [:logseq.property/template-applied-to]}}
;; TODO: Add more classes such as :book, :paper, :movie, :music, :project)
:logseq.class/Project
{:title "Project"
:properties {:logseq.property.class/extends :logseq.class/Page}}
:logseq.class/Area
{:title "Area"
:properties {:logseq.property.class/extends :logseq.class/Page}}
;; TODO: Add more classes such as :book, :paper, :movie, :music)
)))
(def page-children-classes

View File

@@ -7,6 +7,15 @@
(defn- parent-class-id [db]
(:db/id (d/entity db :user.class/Parent)))
(deftest project-and-area-are-built-in-page-classes
(testing "Project and Area are registered as built-in classes that behave like pages"
(is (contains? db-class/built-in-classes :logseq.class/Project))
(is (contains? db-class/built-in-classes :logseq.class/Area))
(is (contains? db-class/page-children-classes :logseq.class/Project))
(is (contains? db-class/page-children-classes :logseq.class/Area))
(is (not (contains? db-class/private-tags :logseq.class/Project)))
(is (not (contains? db-class/private-tags :logseq.class/Area)))))
(deftest get-class-objects-dedupes-inherited-tags-test
(let [conn (db-test/create-conn-with-blocks
{:classes {:Parent {:block/title "Parent"}

View File

@@ -364,6 +364,21 @@
(is (contains? (set (:links result))
{:source hub-id :target page-id}))))
(deftest block-graph-follows-citation-target-ref
(let [conn (db-test/create-conn-with-blocks
{:pages-and-blocks
[{:page {:block/title "Citing page"}
:blocks [{:block/title "a quote"
:build/tags [:logseq.class/Citation]}]}
{:page {:block/title "Cited page"}}]})
citation-block (d/entity @conn (d/q '[:find ?b . :where [?b :block/title "a quote"]] @conn))
cited-page (d/entity @conn (d/q '[:find ?b . :where [?b :block/title "Cited page"]] @conn))
_ (d/transact! conn [[:db/add (:db/id citation-block) :logseq.property.citation/target (:db/id cited-page)]
[:db/add (:db/id citation-block) :block/refs (:db/id cited-page)]])
result (graph-view/build-graph @conn {:type :block :block/uuid (:block/uuid citation-block)})]
(is (= #{"a quote" "Cited page"} (node-labels result))
"The citation graph follows the node-typed citation target ref, same as any other reference")))
(deftest tags-and-objects-graph-skips-large-unrelated-page-set-quickly
(let [conn (db-test/create-conn-with-blocks
{:pages-and-blocks

View File

@@ -673,9 +673,9 @@
{:page {:block/title "Built In"
:build/properties {:logseq.property/built-in? true}}
:blocks [{:block/title "system"}]}
{:page {:block/title "Project"
{:page {:block/title "Custom Tag"
:block/tags #{:logseq.class/Tag}
:db/ident :user.class/Project}
:db/ident :user.class/CustomTag}
:blocks [{:block/title "class"}]}
{:page {:block/title "rating"
:block/tags #{:logseq.class/Property}
@@ -686,16 +686,16 @@
(is (not= ::missing-mirror-repo-fn result))
(let [page-a (db-test/find-page-by-title @conn "Page A")
journal (db-test/find-journal-by-journal-day @conn 20240508)
project (db-test/find-page-by-title @conn "Project")]
custom-tag (db-test/find-page-by-title @conn "Custom Tag")]
(is (= (str (page-marker (:block/uuid page-a)) "\n\n"
"- alpha")
(get @files (page-path "pages/Page A.md"))))
(is (= (str (page-marker (:block/uuid journal)) "\n\n"
"- journal")
(get @files (page-path "journals/2024_05_08.md"))))
(is (= (str (page-marker (:block/uuid project)) "\n\n"
(is (= (str (page-marker (:block/uuid custom-tag)) "\n\n"
"- class")
(get @files (page-path "pages/Project.md")))))
(get @files (page-path "pages/Custom Tag.md")))))
(is (nil? (get @files (page-path "pages/Built In.md"))))
(is (nil? (get @files (page-path "pages/rating.md"))))))
(p/catch (fn [e] (is false (str "unexpected error: " e))))