Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local context for content plugins invocation #17

Closed
traut opened this issue Dec 30, 2023 · 3 comments · Fixed by #96
Closed

Local context for content plugins invocation #17

traut opened this issue Dec 30, 2023 · 3 comments · Fixed by #96
Labels
enhancement New feature or request
Milestone

Comments

@traut
Copy link
Member

traut commented Dec 30, 2023

Background

Content plugins require the local context, in addition to invocation parameters, for execution. In addition to the data fetched from data plugins, the local context must contain the body of the template and the results of previous executions -- this will allow us to create meta content blocks -- the blocks that query the template / other blocks instead of just data.

Design

  • initial local context is a struct that contains:
    • data -- a map with the data returned by data plugins
    • document -- a JSON-style map of the current document template
      • already processed content blocks contain a result field with the result of the execution of the block

content plugin execution steps:

  • the local context is extended with:
    • query root field that contains a value of query attribute from the block definition
    • query_result -- a result of JQ query from query attribute applied to the initial local context (with data and document top fields)
  • the local context is passed to the plugin via API, together with the arguments specified in the block
  • the execution results are added to the context for the next plugin execution

For example, we should be able to perform these queries:

document "test-document" {
    meta {
        name = "Test Document Template"
        tags = ["tag-a", "tag-b"]
    }

    content text {
        query = ".document.meta.name"
        text = "Template name is is {{ .query_result }}"
    }

    content text {
        query = ".document.content[0].result"
        test = "First block result is \"{{ .query_result }}\""
    }
}
@traut traut added the enhancement New feature or request label Dec 30, 2023
@traut traut added this to the v0.1 milestone Dec 30, 2023
@Andrew-Morozko
Copy link
Contributor

I have a couple of concerns: right now all inter-block linking (config/ref) is done exclusively via names, but here the second content text refers to the result of the first block via index. This seems inconsistent with the rest of the system and more fragile: prepending another content block above the first one can break the reference in the last block (and even worse, if the types line up, then the reference would be syntactically correct, but unexpectedly change the semantics).

Perhaps we should stick to the named references, it would look something like this:

document "test-document" {
    meta {
        name = "Test Document Template"
        tags = ["tag-a", "tag-b"]
    }

    content text "my_query" {
        query = .document.meta.name
        text = "Template name is is {{ .query_result }}"
    }

    content text {
        query = .document.content["my_query"].result
        test = "Referenced block result is \"{{ .query_result }}\""
    }
}

The second issue is references to yet-unexecuted blocks, like this:

document "test-document" {
    meta {
        name = "Test Document Template"
        tags = ["tag-a", "tag-b"]
    }

    content text {
        query = .document.content["my_query"].result
        test = "Referenced block result is \"{{ .query_result }}\""
    }

    content text "my_query" {
        query = .document.meta.name
        text = "Template name is is {{ .query_result }}"
    }
}

I assume for v0.1 we'll just forbid it, but the decision on whether we would eventually support these kinds of references should be made before the refactoring becomes too expensive.

@traut
Copy link
Member Author

traut commented Jan 3, 2024

Good points! I agree the proposed design could be better -- I'm open to ideas!

Having that document structure available for inspection ith queries allows us to build meta-blocks -- the blocks that use the document body as a data source. That data structure does not have to align to the one the business logic uses, it can be a serialization / simplification - it just needs to be easily queriable with jq.

My example with access-by-index through [0] is indeed very fragile! The proposal there was to "serialize" the document into dict/list nested structure by block type, but with the introduction of section, the order would be messed up 😞

Perhaps we should stick to the named references

Until now, we didn't consider referencing content inside the document. The references we worked with were against the blocks defined on the root level. Indeed, referencing inside the document is a completely different case -- on the path to the target block there might be anonymous parent blocks!

The second issue is references to yet-unexecuted blocks

I thought we can fix this by adding an explicit priority attribute to the content blocks allowing the template writers to control it – by default, priority can be set to 100 for "normal" blocks and set to 1000 for the blocks with meta-queries. Like a z-index 😂

I do not have a good idea on the document data structure we can use here, so any suggestions are welcome! The meta-queries are a nice-to-have feature for now, so we can take time to think it over.

@traut
Copy link
Member Author

traut commented Jan 28, 2024

to keep this realistic and unblock #15 and #56, I suggest we drop the requirement that the document tree must contain the rendered content.

I'll open a separate issue for the dependencies between content blocks.

// @Andrew-Morozko @dobarx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants