Embed blocks without their children

  • Preparation:
    • Add a macro inside file config.edn , inside macros{} :
    :childlessembed "<div class='kit embed-block color-level' data-kit='childlessembed' data-uuid='$1'>$1</div>"
    
    • The code below requires having kits inside file custom.js .
    • Inside page ChildlessEmbed in Logseq, put the following code in a javascript code-block:
    logseq.kits.setStatic(function childlessembed(div){
        const id = div.dataset.uuid
        if (id !== "$1") {
            const content = logseq.api.get_block(id.slice(2, -2)).content
            div.innerHTML = content.replace(/\n?.*[:][:].*\n?/g, "\n").trim()
            return
        }
    
        div.closest("span.inline").querySelectorAll(".block-children-container")
        .forEach( (child)=>{child.style.display = 'none'} )
        div.remove()
    })
    
  • Usage:
    • Embed a block like usually.
      • e.g.{{embed ((uuid))}}
    • Use the macro in one of two ways:
      • To keep the static content only:
        • Rename embed with your macro.
          • e.g.{{childlessembed ((uuid))}}
        • This should maintain the static content, skipping the children.
      • To keep all the content:
        • Add your macro somewhere in the block.
          • e.g. {{embed ((uuid))}}{{childlessembed}}
        • This should simply hide the children.

So, if e.g. from PageA I want to embed blockA in PageB, does that mean I have to put the javascript code-block in PageB?

On PageB I will also have {{childlessembed ((uuid))}}.

So, can/should `{{childlessembed ((uuid))}} be put immediately below the javascript code-block? I am a bit confused about this.

No, the javascript code-block goes once for all to its own Logseq page, one named as the kit. Just like the macro is defined once for all. The names are like this:

  • macro:
    • childlessembed in the example
    • this is your choice
  • kit:
    • childlessembed in the example
    • this needs to match with the dedicated Logseq page
  • page:
    • ChildlessEmbed in the example
    • this needs to match with kit

PageA and PageB don’t need any definitions:

  • PageA is totally unaware.
  • PageB just uses the macro which is defined elsewhere (in file config.edn).
    • This calls the javascript code which is defined elsewhere (in the dedicated Logseq page).
1 Like

@mentaloid

I am doing something wrong. This is what I have:

  1. in the custom.css file
button.kit {
  background: var(--ls-tertiary-background-color);
  padding: 2px 4px 2px 4px;
}
button.out {
  background: var(--ls-tertiary-background-color);
  display: inline-table;
  line-height: 12px;
  margin: 0px 3px 0px 3px;
  padding: 2px;
}
and the rest of the code
  1. in the custom.js file
const AsyncFunction = async function(){}.constructor;
function Concept(_key){
    return {_key, __proto__: Concept.prototype};
}
Concept.prototype.setChild = Concept.setChild = function setChild(name){
    const child = Concept(name);
    this[name] = child;
    return child;
}
and the rest of the code
  1. on the Logseq page called Childlessembed:
    image

I have kept all your original names, i.e. not changed anything to any of the codes above nor those on the kits page.

So, putting {{childlessembed ((uuid))}} on a page does not render the embedded text.

Be careful when copying formatted code. Should remove all formatting (e.g. double characters **), otherwise it breaks. You can also check the console (Ctrl + Shift + i) for resulting errors.

When I open the debug console in VSC code, all are showing “no problems”.

On the Logseq page I removed all the ** but it still does not work. This is what the console shows for the page with the embed code:

Replace also this:

```js

with this:

```javascript

I wrote a long comment with screenshots because it was still not working. And then I decided to once again copy the javascript code above and “paste and match style”. Restart Logseq, and bingo.

But it is not quite right yet:

  • the original text is *some text*, i.e. in italics. The embed does not render italics, it shows the asterisks instead.
  • I indented the embed relative to the paragraph above, but it does not render indented, it renders on the same level as the para above.

Now, there is something else I just noticed as I am writing this: a normal embed can de edited in situ, i.e. you don’t have to go to the original text. But using your childlessembed method does not support that. So, my question then is: what is the advantage of using your system, rather than just inserting a reference to the parent block? The latter renders the original text, but does not support in situ editing, and it is much more straightforward.

Different tools for different needs. No tool is for everything and no tool has an advantage, each tool is designed for particular straightforward scenarios. Decide which one you need in each case. As stated in the OP, this macro covers two scenarios, which are impossible with the default functionality:

  • One for static content, by mentioning the uuid.
    • You have tried this one, but is not what you want.
    • This is for bringing simple text from one block to another. It loses all formatting, but the info is there. So when you change the value in the original place, it will change in every place that embeds it.
      • This also allows for extra code to process it in a way that is useful to the new context.
      • This is a similar case with your previous problem:
        • Formatting is usually desirable, but sometimes the raw text is needed.
  • One for full content, by not mentioning the uuid.
    • This is for seeing embedded blocks, without having to hover on any of them.
    • From what I understand, you have not tried this one yet.
1 Like

Correct. And …… that one gives me exactly what I want.
Many thanks for everything, esp. your patience - I know I have said that before, but I am struck each time by it. Thank you.

I’m having some trouble with the macro when using the {{embed ((uuid))}}{{childlessembed}} version. It works when I embed a block inside an empty block or when the command is appended to the first line of text of the block, but when it is placed in a new line inside the block it returns the embedded block with childs and another embedded block after the intended one containing only $1. So

  • {{embed ((uuid))}}{{childlessembed}} works;
  • Some text {{embed ((uuid))}}{{childlessembed}} works;
  • Some text
    {{embed ((uuid))}}{{childlessembed}} doesn’t work.

Any suggestions on how to make the last case work?

Welcome. Try replacing "span.inline" with "div.block-content"

1 Like

Worked like a charm, thanks a lot!