page_property.cljs 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. (ns frontend.handler.file-based.page-property
  2. "Page property fns for file graphs"
  3. (:require [clojure.string :as string]
  4. [frontend.db :as db]
  5. [logseq.outliner.core :as outliner-core]
  6. [frontend.modules.outliner.ui :as ui-outliner-tx]
  7. [frontend.state :as state]
  8. [frontend.util :as util]
  9. [promesa.core :as p]))
  10. (defn insert-property
  11. [format content key value]
  12. (when (and (string? content) (not (string/blank? (name key))))
  13. (let [key (if (string? key) (keyword key) key)
  14. key-part (util/format (case format
  15. :org "#+%s: "
  16. "%s:: ") (string/lower-case (name key)))
  17. new-property-line (str key-part value)
  18. lines (string/split-lines content)
  19. key-exists? (atom false)
  20. lines (doall
  21. (map (fn [line]
  22. (if (and (string/starts-with?
  23. (string/lower-case line)
  24. (string/lower-case key-part))
  25. (not @key-exists?)) ; only replace the first match
  26. (do
  27. (reset! key-exists? true)
  28. new-property-line)
  29. line)) lines))
  30. lines (if (= lines [""]) nil lines)
  31. lines (if @key-exists? lines (cons new-property-line lines))]
  32. (string/join "\n" lines))))
  33. (defn insert-properties
  34. "Updates multiple page properties. Mainly just used in legacy title context"
  35. [format content kvs]
  36. (reduce
  37. (fn [content [k v]]
  38. (let [k (if (string? k)
  39. (keyword (-> (string/lower-case k)
  40. (string/replace " " "-")))
  41. k)
  42. v (if (coll? v)
  43. (some->>
  44. (seq v)
  45. (distinct)
  46. (string/join ", "))
  47. v)]
  48. (insert-property format content k v)))
  49. content kvs))
  50. (defn add-property!
  51. [page-name key value]
  52. (let [repo (state/get-current-repo)]
  53. (when-let [page (db/pull [:block/name (util/page-name-sanity-lc page-name)])]
  54. (let [key (keyword key)
  55. pre-block (db/get-pre-block repo (:db/id page))
  56. format (state/get-preferred-format)
  57. page-id {:db/id (:db/id page)}
  58. org? (= format :org)
  59. value (if (contains? #{:filters} key) (pr-str value) value)]
  60. (if pre-block
  61. (let [properties (:block/properties pre-block)
  62. new-properties (assoc properties key value)
  63. content (:block/content pre-block)
  64. new-content (insert-property format content key value)
  65. block {:db/id (:db/id pre-block)
  66. :block/properties new-properties
  67. :block/content new-content
  68. :block/page page-id}
  69. tx [(assoc page-id :block/properties new-properties)
  70. block]]
  71. (db/transact! tx))
  72. (let [block {:block/uuid (db/new-block-id)
  73. :block/left page-id
  74. :block/parent page-id
  75. :block/page page-id
  76. :block/content (if org?
  77. (str "#+" (string/upper-case (name key)) ": " value)
  78. (str (name key) ":: " value))
  79. :block/format format
  80. :block/properties {key value}
  81. :block/pre-block? true}
  82. page-properties-tx [(assoc page-id :block/properties {key value})]]
  83. (ui-outliner-tx/transact!
  84. {:outliner-op :insert-blocks
  85. :additional-tx page-properties-tx}
  86. (outliner-core/insert-blocks! repo (db/get-db false) block page {:sibling? false}))))))))