$note->text()->toBlocks()->excerpt(280) does not output what i expected

OK, i have writen my first plugin. I can display with the plugin a leaflet map with an gpx track.
The bleuprint of the page contains this field:

    fields:
      subheading:
        type: text
      tripname:
        label: Reise
        type: select
        options: query
        query: site.children.listed.template('trips').children
      text:
        type: blocks
        fieldsets:
          text:
            label: Text
            type: group
            fieldsets:
              - heading
              - text
              - list
              - quote
          additional:
            label: Zusatz
            type: group
            fieldsets:
              - line
              - gpxtrackleaflet
          media:
            label: Media
            type: group
            fieldsets:              
              - image
              - gallery
              - video

gpxtrackleaflet is the block of my plugin.

This is the PHP Code from gpxtrackleaflet.php. This shows the map with the gpx track.

<?php if($block->gpxtrack()->isNotEmpty()): ?>
    <div class="wrapper">
        <div class="kirby-leafleat-map">
            <div id="map"></div>
        </div>

    <script>
        if (map != undefined) { map.remove(); } 
        var map = L.map('map').setView([51.505, -0.09], 13);

        var tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 19,
            attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
        }).addTo(map);

        var gpx = '<?= $block->gpxtrack()->toFile()->url() ?>'; // URL to your GPX file or the GPX itself
        new L.GPX(gpx, {
            async: true,
            marker_options: {
                startIconUrl: '/assets/js/leaflet-gpx/pin-icon-start.png',
                endIconUrl: '/assets/js/leaflet-gpx/pin-icon-end.png',
                shadowUrl: '/assets/js/leaflet-gpx/pin-shadow.png'
            }
        }).on('loaded', function(e) {
        map.fitBounds(e.target.getBounds());
        }).addTo(map);
    </script>    
    </div>
<?php endif; ?>

now, when i use $note->text()->toBlocks()->excerpt(280) to output an excerpt of the page, and the first block of the page is an gpx track, i can see this - that’s the content of the script in my gpxtrackleaflet.php file
Auswahl_023

Can i control the output? The excerpt should be created from the first block of text

Martin

You can filter your blocks by type, grab the first and create the excerpt from that:

$note->text()->toBlocks()->filterBy('type', 'text')->first()->excerpt(280);
1 Like

argh, ok the solution is simple. I’ll try it tonight.
Sorry, could I have found that in the documentation myself?
Thank you for your quick response. I get the feeling you’re on the forum 24/7 to help us.

Martin

Well, yes, but not as an answer to such an isolated question. It needs some looking in multiple places.

  1. I want to get only text blocks => ok, I need a way to filter them, how can I do that, let’s look at the blocks object.
  2. I want to get only the first item => ok, I need to limit the output, again what methods does the blocks object have there for me
  3. Then last step, apply the excerpt.

I am facing a similar problem but the proposed solution seems to not be working for me.

I just created a field of type blocks:

fields:
        type: fields
        fields:
          text:
            type: blocks
            fieldsets:
              - text
              - image

And I am trying to get an excerpt from the first text

$item->text()->toBlocks()->filterBy('type', 'text')->first();

The line above properly return the first text block from the field.

$item->text()->toBlocks()->filterBy('type', 'text')->first()->excerpt(80);

But when I add the excerpt function it doesn’t work saying that it is calling to a function on null.

Am I missing any step?

Giving that you seem to be in a loop, if one of the pages doesn’t have a text blocks, this will indeed fail with the given error message.

Use the null-safe operator in this case instead:

$item->text()->toBlocks()->filterBy('type', 'text')->first()?->excerpt(80);

Or wrap the code in an if statement, making sure you have a field before calling excerpt.

1 Like

Ah you were completely right. It worked perfectly, Thank you!