Trix-Editor: How to add a srcset attribute on attached images

© Trix editor logo

For the admin portion of this blog here im using laravel livewire and the trix editor to write and edit blog posts. One issue when it comes to SEO and loading times optimization of article contents are attached images that can be inserted in the text via the trix editor.

One thing ahead, this is not an article about how to handle image uploads in livewire from the trix "trix-add-attachment" event or how to create serveral image sizes. For the first issue ive found a helpfull tutorial on Youtube, for the image manipulation i use the intervention.io facade to create multiple webp image sizes on upload. From this created images my image model provides a srcset Attribute as a string like:



The srcset attribute value



foreach ($image->webp as $width => $path){
    $srcset .= Storage::url($path);
    $srcset .= ' ';
    $srcset .= $width;
    $srcset .= 'w, ';
}

$srcset = rtrim($srcset, ',');


This string is emmited form my livewire component to the trix attachment.setAttribute function after the image is saved, like so:
$this->emit( 'photoSaved', [
    'url'   => Storage::url( $image->path ),
    'href'  => Storage::url( $image->path ),
    'srcset'=> $srcset
] );

And set on the frontend like this:
@this.on('photoSaved', (photo) => {
   attachment.setAttributes(photo)
});

So far so good, now this data is available in the "figure" html node thats created by trix:
<figure data-trix-attachment="{&quot;contentType&quot;:&quot;image/jpeg&quot;
,&quot;filename&quot;:&quot;20211207_RoteNasen_WienMitte1.JPG&quot;
,&quot;filesize&quot;:104560,&quot;height&quot;:675,
&quot;
href&quot;:&quot;https://poppgerhard-blog.s3.eu-central-1.amazonaws.com/photos/202201/20211207_RoteNasen_WienMitte1.JPG&quot;
,&quot;
srcset&quot;:&quot;https://poppgerhard-blog.s3.eu-central-1.amazonaws.com/photos/202201/20211207_RoteNasen_WienMitte1_large.webp 1200w, 
https://poppgerhard-blog.s3.eu-central-1.amazonaws.com/photos/202201/20211207_RoteNasen_WienMitte1_medium.webp 600w, 
https://poppgerhard-blog.s3.eu-central-1.amazonaws.com/photos/202201/20211207_RoteNasen_WienMitte1_small.webp 300w, 
https://poppgerhard-blog.s3.eu-central-1.amazonaws.com/photos/202201/20211207_RoteNasen_WienMitte1_thumb.webp 120w, 
&quot;,&quot;url&quot;
:&quot;https://poppgerhard-blog.s3.eu-central-1.amazonaws.com/photos/202201/20211207_RoteNasen_WienMitte1.JPG&quot;,&quot;width&quot;
:900}" 
data-trix-content-type="image/jpeg" 
data-trix-attributes="{&quot;presentation&quot;:&quot;gallery&quot;}" 
class="attachment attachment--preview attachment--jpg">

Getting the srcset to the img tag

For me now the tricky part was to alter the html output of the editor so that this srcset data is applied to the image tag that trix generates. I must confess that i know nothing about coffee scripts, so altering trix itself, even after a day of googeling my finger bleding :), was not an option. Heres what i did instead.
On the laravel model for a blog post i setup an event that fires whenever a posting is created or updated.

protected static function booted()
{
    static::saved(function (blog $blog) {


        $doc = new \DOMDocument();
        @$doc->loadHTML($blog->body, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

        $figures = $doc->getElementsByTagName('figure');

        if($figures->length){

            for($i = 0; $i < $figures->length; $i++){

                if($figures->item($i)->hasAttribute('data-trix-attachment')){
                    $data = $figures->item($i)->getAttribute('data-trix-attachment');
                    $data = json_decode($data);


                    if($data->contentType === 'image/jpeg' || $data->contentType === 'image/png' && isset($data->srcset)){
                        $img = $figures->item($i)->getElementsByTagName('img');
                        $img->item(0)->setAttribute('srcset', $data->srcset);
                    }
                }
            }

            $blog->body = $doc->saveHTML();
        }

        $blog->saveQuietly();
    });
} 

Lets walk through this line by line.
First i instatiate a now dom document and load the posts content, with the Flags  
LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
its ensured that DOMDocument doesnt sourround the content with <html>, <head> and <body> tags.

Then we grab all <figure> tags, this are created by the trix editor and check if they have an
data-trix-attachment
  attribute.
This is the JSON String that trixt inserts with the setAttribute function on the attachment.
At least i search for the firs "img" node inside of the "figure" and set the srcset as an attribute on this.

Not to forget to  
 $blog->saveQuietly();
 
otherwise it ends up in an endless loop because the event is firing again and again...

Hope this helps someone ...




Feedback zu diesem Beitrag

Deine Meinung zählt

Dein Feedback zu unseren Inhalten hilft uns diese weiter zu verbessern, schreibe einen Kommentar und gib eine Bewertung ab.