getkirby / kirby

Kirby's core application folder
https://getkirby.com
Other
1.32k stars 168 forks source link

Kirby\Cms\Blueprint::load fails with multi-language block blueprint #4177

Closed shoogstoel closed 2 years ago

shoogstoel commented 2 years ago

Description

Tried to load a custom block's blueprint using Kirby\Cms\Blueprint::load('block-name-here'), resulting in a TypeError thrown by ucfirst, because Kirby assume the block's name to be a string. However, if the name is specified in multiple languages, it is actually an array.

Expected behavior
Blueprint to be loaded successfully.

To reproduce

To reproduce create a custom block with a name in more than 1 language and try to load its blueprint using Kirby\Cms\Blueprint::load('block-name-here').

Your setup

Kirby Version
3.6.2

Console output

{
  "status": "error",
  "message": "ucfirst(): Argument #1 ($string) must be of type string, array given",
  "code": 500,
  "exception": "TypeError",
  "key": null,
  "file": "/kirby/src/Cms/Blueprint.php",
  "line": 343,
  "details": [],
  "route": "page/([a-zA-Z0-9\\.\\-_%= \\+\\@\\(\\)]+)"
}

Your system (please complete the following information)

afbora commented 2 years ago

Could you try ::extend() method like as Kirby blocks use to load?

Kirby\Cms\Blueprint::extend('block-name-here');
shoogstoel commented 2 years ago

Sorry it tooke me so long, @afbora, can confirm that using Kirby\Cms\Blueprint::extend does not produce the error I described.

distantnative commented 2 years ago

For sure, the description of Kirby\Cms\Blueprint::load isn't correct then

Loads a blueprint from file or array

But I am also still not sure what your re doing. For one thing, it should probably be e.g. Kirby\Cms\Blueprint::load('blocks/button') (when following these docs https://getkirby.com/docs/reference/plugins/extensions/blocks#full-block-plugins__adding-a-default-blueprint-and-snippet)

But why would you specify the blocks name in different languages?

shoogstoel commented 2 years ago

I am naming it differently for specific languages in the blueprint.

distantnative commented 2 years ago

Can you provide your code?

I would think you don't need multiple blueprints for multiple languages, but rather translate the strings of your block inside the one blueprint.

shoogstoel commented 2 years ago

Sorry, just to clarify again: I am not using multiple blueprints. The name field inside the blueprint has language-specific values:

name:
  en: 'Some name in English'
  de: 'Deutscher Name'

[...]
distantnative commented 2 years ago

Ok sorry, now I understood the issue. Sorry

Summary

We can't call ucfirst() here https://github.com/getkirby/kirby/blob/main/src/Cms/Blueprint.php#L343 assuming props['name']) is a string as it might be also an i18n array. We only run I18n::translate on the next line.

Solution

Use ucfirst in https://github.com/getkirby/kirby/blob/main/src/Cms/Blueprint.php#L340 only for capitalising the filename (which will always be just a string) and accept if $props['name'] explicitly was set lowercased.

@afbora what do you think?

bastianallgeier commented 2 years ago