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

Support for different selects based on object type (Block type/Page template/User role) #45

Open
tobimori opened this issue Feb 13, 2023 · 12 comments

Comments

@tobimori
Copy link

tobimori commented Feb 13, 2023

The issue

I want to access different properties based on block types. For an image, I might want to generate a srcset and get the alt text, but other blocks don't have an image, so the query would fail.

The previous solution would be to create a Block model with Kirby, with a toArray function. This would result in my "queries" being in two different locations - half of it in my frontend, and everything related to a specific Block type etc. would be in my backend.

Solution

I experimented with that idea here.

In short, I added a models property that allows to specify different selects based on the object type, similar to models in core.

const { result } = await fetchKql({
  query: 'page("home")',
  select: {
    title: true,
    blocks: {
      query: 'page.blocks.toBlocks',
      // needs select as potential fallback, empty array will return null if no matches
      // if not specified, query will not respect 'models' and return all fields
      select: ['type'],
      // 'models' as directory for different 'selects' based on class/block type
      models: {
        // 'select' for 'image' block type
        image: {
          type: true,
          image: 'block.image.toFile?.resize(200)',
          title: true
        },
        // 'select' for 'text' block type
        text: ['type', 'heading', 'text']
      }
    }
  }
})

This is a quick-and-dirty proof-of-concept, but it works for what I've tested it. Feel free to take any code from that repository for adding this feature.

@eriksachse
Copy link

Thanks.
I still struggle with the query and my implementation for layouts specifically look like this:

layout: {
  query: "page.layout.toLayouts",
  select: {
    columns: {
      query: "layout.columns",
      select: {
        id: true,
        width: true,
        blocks: {
          select: {
            type: true,
            text: true,
            image: {
              query: "block.image.toFile?.resize(200)",
              select: {
                url: true,
                // Resize should be here
                // small: "image.resize('200').url",
              },
            },
          },
        },
      },
    },
  },
},

And I wonder if I could add different srcsets... That would be amazing.

@tobimori
Copy link
Author

tobimori commented Feb 22, 2023

Pretty sure you should be able to something like this:

            image: {
              query: "block.image.toFile",
              select: {
                url: true,
                small: "file.resize('200').url",
                medium: "file.resize('400').url",
              },

Doesn't belong to this issue tho?

@benwest
Copy link
Contributor

benwest commented Mar 19, 2023

This is perfect, would love to see it in core - I guess it's not possible to implement as an additional plugin independent from KQL?

@tobimori
Copy link
Author

This is perfect, would love to see it in core - I guess it's not possible to implement as an additional plugin independent from KQL?

nope, sadly would need to be integrated in KQL directly - similar to how I did it.

@benwest
Copy link
Contributor

benwest commented Mar 21, 2023

I've made a push at TS types for KQL, supporting your extended models query: https://github.com/benwest/kql-ts

If you are interested in using, testing or helping out, cool! Otherwise, thanks for the plugin.

@tobimori
Copy link
Author

I've made a push at TS types for KQL, supporting your extended models query: benwest/kql-ts

If you are interested in using, testing or helping out, cool! Otherwise, thanks for the plugin.

Really nice! I'll check it out when I've time to work on my personal site again.

@johannschopplich
Copy link
Contributor

Seems like we all have the same issue – resolving relations inside blocks. For my personal use-case, I have created a custom toResolvedBlocks field method to resolve images.

Via the Kirby config, we can define, which blocks actually contain images:

# /site/config/config.php
return [
    'blocksResolver' => [
        // Blocks that contain files fields
        'files' => [
            // Block name as key, field name as value
            // Resolve the built-in `image` field of the `image` block
            'image' => 'image'
        ]
    ]
];

But the models option is much smarter. 😄

@tobimori
Copy link
Author

@bastianallgeier @distantnative I'd love to hear what you think about my approach. If it suits your needs, I'll happily submit a PR.

@bastianallgeier
Copy link
Member

Sorry for the delay, but I actually really love the models idea! A PR would be great.

@tobimori
Copy link
Author

tobimori commented Apr 20, 2023

A PR would be great.

@bastianallgeier

Do you mind taking a look at the plugin I linked above as a base for the PR? Will of course add unit tests, but just asking for feedback on the general implementation as I haven't completely understood the Kql code yet 🙂

@bastianallgeier
Copy link
Member

@tobimori sorry, I completely missd the link to your experiment. The code looks super straight forward.

@ovenum
Copy link

ovenum commented Nov 9, 2023

Just started looking into KQL and this one of the first issues i ran into. I know work is focused on releasing Kirby v4 and i can’t wait for it : )

To make KQL usable with blocks the support for different and custom block types should be added to the plugin. Reading the issues for KQL it seems that this causes at least a fair amount of headaches.

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

No branches or pull requests

6 participants