Просмотр исходного кода

Switch named block links to autolink to header blocks

Replaced block property approach as it doesn't provide as much
functionality initially
Gabriel Horner 3 лет назад
Родитель
Сommit
10d6bc28da

+ 1 - 1
deps/graph-parser/src/logseq/graph_parser/property.cljs

@@ -47,7 +47,7 @@
   "Properties used by logseq that user can edit"
   []
   (into #{:title :icon :template :template-including-parent :public :filters :exclude-from-graph-view
-          :logseq.query/nlp-date :logseq.block/route-name
+          :logseq.query/nlp-date
           ;; org-mode only
           :macro :filetags}
         editable-linkable-built-in-properties))

+ 1 - 1
src/main/frontend/components/block.cljs

@@ -2026,7 +2026,7 @@
 
 (def hidden-editable-block-properties
   "Properties that are hidden in a block (block property)"
-  #{:logseq.query/nlp-date :logseq.block/route-name})
+  #{:logseq.query/nlp-date})
 
 (assert (set/subset? hidden-editable-block-properties (gp-property/editable-built-in-properties))
         "Hidden editable page properties must be valid editable properties")

+ 3 - 2
src/main/frontend/components/page.cljs

@@ -46,12 +46,13 @@
 ;; Named block links only works on web (and publishing)
 (if util/web-platform?
   (defn- get-block-uuid-by-block-route-name
-    "Return string block uuid for matching :name and :block params or nil if not found"
+    "Return string block uuid for matching :name and :block-route-name params or
+    nil if not found"
     [state]
     ;; Only query if block name is in the route
     (when-let [route-name (get-in (first (:rum/args state))
                                   [:parameters :path :block-route-name])]
-      (->> (model/get-block-by-page-name-and-route-name
+      (->> (model/get-block-by-page-name-and-block-route-name
             (state/get-current-repo)
             (get-page-name state)
             route-name)

+ 20 - 5
src/main/frontend/db/model.cljs

@@ -267,19 +267,34 @@
   [id]
   (db-utils/pull [:block/uuid (if (uuid? id) id (uuid id))]))
 
-(defn get-block-by-page-name-and-route-name
-  "Returns first block for given page name and route-name property"
+(defn heading-content->route-name
+  "Converts a heading block's content to its route name. This works
+independent of format as format specific heading characters are stripped"
+  [block-content]
+  (some->> block-content
+           (re-find #"^#{0,}\s*(.*)(?:\n|$)")
+           second
+           string/lower-case))
+
+(defn get-block-by-page-name-and-block-route-name
+  "Returns first block for given page name and block's route name. Block's route
+  name must match the content of a page's block header"
   [repo page-name route-name]
   (->> (d/q '[:find (pull ?b [:block/uuid])
-              :in $ ?page-name ?route-name
+              :in $ ?page-name ?route-name ?content-matches
               :where
               [?page :block/name ?page-name]
               [?b :block/page ?page]
               [?b :block/properties ?prop]
-              [(get ?prop :logseq.block/route-name) ?route-name]]
+              [(get ?prop :heading) _]
+              [?b :block/content ?content]
+              [(?content-matches ?content ?route-name)]]
             (conn/get-db repo)
             page-name
-            route-name)
+            route-name
+            (fn content-matches? [block-content external-content]
+              (= (heading-content->route-name block-content)
+                 (string/lower-case external-content))))
        ffirst))
 
 (defn get-page-format

+ 2 - 2
src/main/frontend/handler/route.cljs

@@ -51,10 +51,10 @@
     ;; Only query if in a block context
     (let [block (when (uuid? page-name-or-block-uuid)
                   (model/get-block-by-uuid page-name-or-block-uuid))]
-      (if-let [route-name (get-in block [:block/properties :logseq.block/route-name])]
+      (if (get-in block [:block/properties :heading])
         {:to :page-block
          :path-params {:name (get-in block [:block/page :block/name])
-                       :block-route-name route-name}}
+                       :block-route-name (model/heading-content->route-name (:block/content block))}}
         {:to :page
          :path-params {:name (str page-name-or-block-uuid)}})))
 

+ 14 - 1
src/test/frontend/db/model_test.cljs

@@ -121,4 +121,17 @@
          (#'model/get-unnecessary-namespaces-name '("one/two/tree" "one" "one/two" "non nested tag" "non nested link")))
       "Must be  one/two one"))
 
-#_(cljs.test/test-ns 'frontend.db.model-test)
+(deftest get-block-by-page-name-and-block-route-name
+  (load-test-files [{:file/path "foo.md"
+                     :file/content "foo:: bar
+- b2
+- ### Header 2
+foo:: bar"}])
+  (is (uuid?
+       (:block/uuid
+        (model/get-block-by-page-name-and-block-route-name test-helper/test-db "foo" "header 2")))
+      "Header block's content returns map with :block/uuid")
+
+  (is (nil?
+       (model/get-block-by-page-name-and-block-route-name test-helper/test-db "foo" "b2"))
+      "Non header block's content returns nil"))

+ 19 - 10
src/test/frontend/handler/route_test.cljs

@@ -11,25 +11,34 @@
   (load-test-files [{:file/path "foo.md"
                      :file/content "foo:: bar
 - b1
-logseq.block/route-name:: b1
-- b2"}])
+- ## B1
+- b2
+- ### Header 2
+foo:: bar"}])
 
   (let [block (ffirst
                (db-utils/q '[:find (pull ?b [:block/uuid])
-                             :where [?b :block/content "b1\nlogseq.block/route-name:: b1"]]))]
+                             :where [?b :block/content "## B1"]]))]
     (is (= {:to :page-block
             :path-params {:name "foo" :block-route-name "b1"}}
            (#'route-handler/default-page-route (:block/uuid block)))
         "Generates a page-block link if route-name is found"))
 
-  (let [uuid (->
-              (db-utils/q '[:find (pull ?b [:block/uuid])
-                            :where [?b :block/content "b2"]])
-              ffirst
-              :block/uuid)]
+  (let [block (ffirst
+               (db-utils/q '[:find (pull ?b [:block/uuid])
+                             :where [?b :block/content "### Header 2\nfoo:: bar"]]))]
+    (is (= {:to :page-block
+            :path-params {:name "foo" :block-route-name "header 2"}}
+           (#'route-handler/default-page-route (:block/uuid block)))
+        "Generates a page-block link if route-name with whitespace and properties is found"))
+
+  (let [uuid (-> (db-utils/q '[:find (pull ?b [:block/uuid])
+                               :where [?b :block/content "b2"]])
+                 ffirst
+                 :block/uuid)]
     (is (= {:to :page :path-params {:name (str uuid)}}
-          (#'route-handler/default-page-route uuid))
-       "Generates a page link if route-name is not found"))
+           (#'route-handler/default-page-route uuid))
+        "Generates a page link if route-name is not found"))
 
   (is (= {:to :page :path-params {:name "page-name"}}
          (#'route-handler/default-page-route "page-name"))