Use html in panel label

I retrieve data from an API that is not allowed to be changed from within the panel.
For this I use disabled: true.

However, dates from the API are in a not human friendly format, like 2023-04-07T20:30:00+02:00.

My solution is that I hide the disabled input with CSS and display the date in the label, like this:
programstart:
label: "Date: {{ page.programstart().toDate('d-m-Y') }}"
type: text
disabled: true

This works good, however the label is bold by default, which is usually fine, but I would like to display the actual date in normal font weight.

My idea was to put a span around it to style in CSS, like
label: "Date: <span>{{ page.programstart().toDate('d-m-Y') }}</span>"
or
label: "Date: {{ <span> page.programstart().toDate('d-m-Y') </span>}}".

Unfortunately that doesn’t work.

Any ideas?

you need to enforce a style on the span.

<span style='font-style: normal!important;'>{{ page.programstart().toDate('d-m-Y') }}</span>

you could also create a custom field method to output html but keep in mind that you need to escape them with {< >} instead of {{ }}

or add a class to custom css for the panel and use that

<span class="myClassFromCustomPanelCss">{{ page.programstart().toDate('d-m-Y') }}</span>

and welcome to the forum :wave:

1 Like

Thanks for your reply.
Unfortunately I’m still struggling.

Based on you answer, I thought this would be correct:
label: "{<span>{{ page.programstart().toDate('d-m-Y') }}</span>}"

But the result is that <span> is printed as text (see screenshot).

CleanShot 2023-04-05 at 12.53.26@2x

"{< <span>page.programstart().toDate('d-m-Y') </span> <}"

The {< is what allows HTML instead of {{}}which doesn’t.

Thanks @texnixe, but I must still be doing something wrong.
I copied your line, but still fails.

i think you need a custom page/field method to return the html.

label: "{< page.programstart().myCustomHTMLOutput() >}"

Thanks for the suggestion, but unfortunately it looks like it’s also not possible.

Not sure how labels are rendered, maybe with Str::safeTemplate() or Str::template()?
If it’s Str::template(), the method doesn’t take {< >} into account at all.
Very interested in this as well, but I can’t find the corresponding part in the source code.

Doesn’t seem to work either. :cry:

dont use () in the query language uless you pass a parameter, maybe?

Nope :slight_smile:

hm sorry about that. then labels do not support querystrings yet. maybe create an feature request here

1 Like

I’ve solved it in a different way using specific CSS and JS for the panel.

config.php

  'panel' => [
    'css' => 'assets/css/panel.css',
    'js' => 'assets/js/panel.js'
  ],

panel.js

setTimeout(() => {
  const disabledLabels = document.querySelectorAll('div[data-disabled="true"] .k-field-label');
  disabledLabels.forEach(label => {
    const [first, ...rest] = label.innerText.split(':');
    const last = rest.join(':');
    label.innerHTML = `${first}: <span>${last}</span>`;
  })
}, 100);

panel.css

.k-text-field[data-disabled="true"] {
  label {
    margin-bottom: -2rem;
    span {
      font-weight: normal;
    }
  }
}

.k-input[data-disabled="true"] {
  display: none;
}

result

CleanShot 2023-04-07 at 15.18.38

1 Like

Hmmmm. :thinking:

It seems that panel.js is not (re)loaded/(re)triggered when you navigate to a different page in the panel, so it only works if you reload the page manually. :sob:

Any ideas on that @texnixe ?

I can use a setInterval() instead of a setTimeout() and it works, but it’s not pretty … :disappointed:

No.

But I have another idea.

What about storing those disabled fields in a hidden field and displaying their values in an info field instead? Return your value including the HTML from a page model as before.

      dateDisplay:
        type: info
        label: ''
        theme: neutral
        text: "{< page.getDateString >}"
      date:
        type: hidden

And in case the neutral theme is not neutral enough with its white background, you can give it a theme name of your choice and style it, see http://getkirby3.com.test/docs/cookbook/panel/customizing-panel#info-sections-fields

1 Like

Oh, that’s a nice CSS only suggestion!
I’ve implemented it, thanks! :smiley:

timeDisplay:
  type: info
  theme: none
  label: "Tijd"
  text: "{{ page.programstart.toDate('H:i') }} - {{ page.programend.toDate('H:i') }}"

Targeting .k-info-field with data-theme="none" I have this CSS to make it look the way I want it. Unfortunately :has is not supported in Firefox yet, but my clients will not use that browser.
I use it as my development browser, but I can live with the default layout.

.k-grid:has(.k-info-field):has([data-theme="none"]) {
  row-gap: 1rem;
  .k-info-field {
    display: flex;
    align-items: baseline;
    .k-headline {
      padding-bottom: 0;
    }
    h2 {
      font-size: initial;
      min-width: 240px;
    }
    .k-box {
      padding: 0;
      background-color: initial;
      font-size: initial;
    }
  }
}

1 Like

Works in Firefox too by setting layout.css.has-selector.enabled to true manually via about:config.