I’ve been using LogSeq for almost a year and have been loving its ability to sort information and keep track of tasks in a very intuitive way. I have a personal graph where I keep track of lessons I’m learning and helpful resources. I’m trying to see if it’d be feasible to write/edit a novel in LogSeq (where it’s integrated with all my other thoughts and ideas). I currently have scenes and chapters on their own pages with several page properties to help with sorting/querying.
Sample Scene Properties:
scene-number:: 3
chapter-number:: 1
book::
characters::
setting::
description::
word-count::
type:: [[Scene]]
Sample Chapter Properties:
type:: [[Chapter]]
chapter-number:: 1
chapter-title::
word-count::
book::
My plan is to have a query on each chapter page to gather all scene pages with a matching chapter-number
property and sort them by their scene-number
property. This will facilitate easy scene order changing. I have book in there to filter out which book I’m looking for.
I’m having an issue making a query that returns the contents of the scene pages. I can get a list of the pages and their properties, but I’m having a hard time getting the contents of the pages. When I right click on my page title to see the page properties, I don’t see a contents
property. Is the file
property a page’s equivalent to :block/content
? Is there a way to access it and the :db/id
property within?
I’ve also thought about querying for each block that has a parent containing the correct chapter-number
property value, but I don’t know how to have the displayed scene blocks sorted as they are on the pages. I’d eventually like to have a page to query for the whole book and sort it by scene-number
.
@Siferiax I’ve seen several of your in-depth custom queries on this forum. Is this feasible to do with an Advanced query?
I have a rough query that would live on each chapter page below, but it’s not working.
#+BEGIN_QUERY
{ ; Surrounding Block
:title [:h2 "All Scenes in this chapter"]
:query [ ; Start Query Block
:find (pull ?p [*])
:in $ ?current-page
:where
(page-property ?p :type "scene")
(page-property ?p :chapter-number ?current-page)
] ; Close Query
:inputs [:current-page]
}
#+END_QUERY
First of, thanks for the elaborate information ! That really helped tackle this ![:slight_smile: :slight_smile:](https://discuss.logseq.com/images/emoji/twitter/slight_smile.png?v=12)
So it’s not impossible, just a bit complicated.
Some things to note:
- property values should be exactly equal for this to work
- you loose the group by page effect
- if you have multiple blocks on a scene’s page, those won’t be sorted properly this way
Here’s what it looks like:
Here’s what it looks like in table form, just to show the page names I used.
And here’s the query:
#+BEGIN_QUERY
{:title [:b "Scenes"]
:inputs [:query-page]
:query [:find ?scnum (pull ?b [*]) ;return both scene-number and blocks
:keys scene block ;put find values into key value pairs.
:in $ ?chapter
:where
;get the information about the chapter
[?ch :block/name ?chapter]
[?ch :block/properties ?chprop]
[(get ?chprop :book) ?chbook]
[(get ?chprop :chapter-number) ?chnum]
;find matching scenes
[?sc :block/properties ?scprop]
[(get ?scprop :type) ?type]
[(contains? ?type "Scene")]
[(get ?scprop :book) ?scbook]
[(= ?scbook ?chbook)]
[(get ?scprop :chapter-number) ?sc-chnum]
[(= ?sc-chnum ?chnum)]
[(get ?scprop :scene-number) ?scnum]
;get their blocks
[?b :block/page ?sc]
;exclude properties block
(not [?b :block/pre-block? true])
]
:result-transform (fn [result]
(sort-by
(fn [s] (get-in s [:block/properties :scene]))
(map
(fn [m]
(update (:block m) :block/properties
(fn [u] (assoc u :scene (get-in m [:scene]) ) )
)
)
result
)
)
)
}
#+END_QUERY
1 Like
Wow that you for taking the time to develop this query! I didn’t realize it would be that complex! I’ll need to spend some time digesting the pieces ![:exploding_head: :exploding_head:](https://discuss.logseq.com/images/emoji/twitter/exploding_head.png?v=12)
My current workflow will have multiple blocks within each Scene page. I want to be able to keep all the actual text of the scene in a “level 1” block and have comments/tasks/notes/references about each paragraph as child blocks. There isn’t a way to query and determine which order blocks appear in the page/file?
I may need to look into a custom JS plugin for this. I think there’s a get_page_tree()
function in the LogSeq API I may be able to use to keep/determine the order.
Is there a way to access the :db/id
or :block/file
properties in a query? Would these give the page structure/block order?
1 Like
You’re welcome.
For the results, if there’s only 1 level 1 block, it will work just fine.
It is having multiple level 1 blocks that will cause issues.
So if your page is
- this is the scene text
- this is some references
- TODO this is a task
That’s fine.
However if it is like
- this is some text
- this is some other text
There will be an issue sorting “this is some text” and “this is some other text”.
:block/file
is the db/id
of the file if I’m not mistaken.
db/id
of the block gets assigned when it is made and so may not lead to a proper sort.