kql icon indicating copy to clipboard operation
kql copied to clipboard

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

Open tobimori opened this issue 1 year ago • 12 comments

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.

tobimori avatar Feb 13 '23 08:02 tobimori