cdowdy / boltbetterthumbs Goto Github PK
View Code? Open in Web Editor NEWBolt Extension for thumbnails, srcset and picture element using Glide
Bolt Extension for thumbnails, srcset and picture element using Glide
current check for permissions is the dashboard. This is wrong. a guest could log in and edit/delete/prime the cache for an image.. this is unwanted
use the picture element with a separate twig function like:
{{ picture( record.image, 'configName') }}
Problems with this.
The way the config is setup right now could get messy since the picture element also allows multiple files at a particular media query. ie:
<picture>
<source srcset="image-big.png, image-big-2x.png 2x"
media="(min-width: 990px)">
<source srcset="image-medium.png, image-medium-2x.png 2x"
media="(min-width: 750px)">
<img srcset="image-small.png, image-small-2x.png 2x"
alt="Some Fancy Pants Alt Text">
</picture>
So the current config setup in 'modifications' would fail at here. Since we take each array inside modifications and use that for the files in srcset in an img tag. IE:
picture:
class: []
altText: '~'
modifications:
small:
w: 900
crop: 'crop-top'
medium:
w: 600
large:
w: 300
Either We'd have to setup a config option for media queries and use those as our basis, make the modifications array even messier by using more arrays:
modifications:
media_queries: [ 'min-width: 900', 'min-width: 700' ]
mediaQuery1:
small:
w: 900
crop: 'crop-top'
medium:
w: 600
large:
w: 300
media2:
small:
w: 900
crop: 'crop-top'
medium:
w: 600
large:
w: 300
This all sounds dumb, is fragile and allows for to many easy to make errors.
Type Switching
Since intervention doesn't do webp (or jxr) we would need to pass through those images. PHP doesn't have a IMAGETYPE_WEBP
like for jpg/png/gif but imagewebp
exists in php 5.5+. So we'd need to fork and modify Flysystems getmimetype method which I'm not going to do right now.
Passing through those image's also negates the use of any glide modifications. This is a bag of snakes :)
So in order to do type switching with webp, jxr and jpeg2000 for example:
<picture>
<source srcset='fancy-pants.jxr' type='image/vnd.ms-photo'>
<source srcset='fancy-pants.jp2' type='image/jp2'>
<source srcset='fancy-pants.webp' type='image/webp'>
<img srcset='fancy-pants.png' alt='alt-de-alt'>
</picture>
we need a way to reliably get the mimetype and then let those passthrough without using intervention to modify the images. This can be done without the extension so maybe tell uses... "nah brah manually build that baaad thang instead".
Soooo this issue here is for me to come back at another time look at this and think of a better way to handle the picture element.
When used alongside the Minify HTML extension: https://github.com/nlemoine/bolt-extension-minify-html
Srcset images are not loaded. Looking at the network monitor I'm seeing a 500 error for each image.
Images are still being generated and cached.
The original passthrough image is loading fine.
Did a very quick comparison of the minified vs original srcset markup to see if it's getting mangled somewhere by the minifier, but nothing immediately jumps out as being obviously out of place. Only had time for a very brief look, though.
If you're using the GD image driver for image manipulations and try to process a TIFF, BMP, ICO, PSD you get an indefinite spinner. There is no obvious error, besides the dev console, To let a user know what exactly went wrong or why.
If you're using the imagemagick driver everything is okie dokie!
For some reason bolt updated and will now strip attributes not found in the "allowed_attributes" config settings when you use this extension in a contenttypes field (html etc) .
This worked for the entirety of the Bolt 3.x until recently (3.2.14 I noticed it first)
tags removed are:
Essentially they pushed an update, didn't tell anyone what it was doing and broke this haha.. but it's an easy fix. You have to add these to your bolt config htmlcleaner -> allowedtags and allowed_attributes
sorry to insist
I am loading images via lazysizes.
when I use {{ img( record.image, 'post' ) }}
smaller and bigger images are loaded, when the viewport changes.
but using:
<img class="lazyload full-image" data-sizes="auto"
data-{{ btsrc(record.image, 'post') }}
data-{{ srcset(record.image, 'post') }}
/>
only new images are loaded when the viewport gets smaller (turning from landscape to portrait)
but bigger images are not loaded when switching to a bigger viewport
I tested both on the same page
If request: true
is set in the caching section of bolts config.yml the srcset images are not found.
The images are generated and cached. The srcset is constructed properly and it seems the paths are correct but the images don't load.
I must have set request to true by accident at some point in the past, because personally I don't need it. Still, it took me a few hours of head scratching to figure out why things weren't working properly.
Any visitor can hit the backend pages and remove from the cache.. this is a biiiiiiiiig oversight.
see bolt/bolt#7483
that gets fixed/updated or bolt developers decide that hey people wanting to fix your undocumented usage of something is something they'll like I'll return to maintaining this.
As of right now if you're not a core developer of bolt good luck having any input.
used
Is there currently any way to choose to use the original image at a specific width? Or an option to prevent an image being processed if it already matches the w value?
For example, it would be useful when the original is a .png and a user only needs to generate smaller sizes as .jpg files
My experience with using GD to process .png files is that they invariably come back much larger than the original.
Just tested with a 51k .png file which came back at 220k
The included jquery cdn script doesn't use HTTPS and will be blocked if you serve your site over https (mixed content) so you can't delete or prime images..
Either update the link or use Bolt's jquery but that uses a fragile version strategy right now so either make a pull there (!! prefered :) ) or bite the bullet and just keep on top of bolt's jquery updates
When I visit /extend/betterthumbs/files
in v1.5.2 I can see a card for each image with a delete image button. However the image previews are not found. All I get is the dark grey background where the image should be and the filename as alt text.
If I click the delete button anyway I get an endless spinner and a not found response for the delete request.
with http_cache enabled an exception of:
The controller must return a response (null given). Did you forget to add a return statement somewhere in your controller?
Forgot to return an actual response.. fix incoming :) related #15
would be nice to be able to pre generate image / prime the cache.
would either have to grab the pages from the sitemap and use curl on the urls (probably wont work since images are signed)
grab all the records images from the database, combine them with settings from the extensions config then generate them with a nut command / backend page. - ugh naw thanks :)
Or do glides eager manipulations, check if the user is logged in ( I don't know how to do this in bolt right now), if so do
$app['betterthumbs']->makeImage( '/img/' . record-image . $modifications );
and save those to the cache.
Is it possible? I want to to use this extension for a client and they make heavy use of animated gifs. Since they upload all the media, a condition to bypass an animated GIF to be processed by Glide would be a nice-have.
I want to incorporate this extension to a current website I have but I'm using some pictures elements and some inline background-images with css.
It would be nice if I could generate a single image url without an img tag for me to use in other scenarios.
Thank you for making this extension and keep up the good work! ๐
if a width is set in a config:
srcset:
# other settings
modifications:
small: { 'w': 340 }
medium: { 'w': 680 }
large: { 'w': 800 }
xlarge: { 'w': 1260 }
and we try to "add" some modifications in a template (for instance changing image format) like so:
{{ img(record.image, 'srcset', {
'modifications': { 'medium': { 'fm': 'png' } }
} ) }}
then the srcset string is invalid. the width for "medium" setting gets overriden to null.
<img src="fallback src img"
srcset="<!-- other srcset candidates -->
/img/file-name.jpg?fm=png&s=fa230fddc843fa4b1c763b6e72d496f5 0w, <!-- bad width descriptor and no width -->
/img/file-name.jpg?w=1260&fit=stretch&s=79f74dc3a92976699cee74ded5b327a5 1400w"
alt=""
This ins't the intended behavior nor is it very helpful :) haha.
hi,
on bolt 3.3(.2) the pass to the backend link docs and files is 'extensions' and not 'extend'
results in a 404 error
the path to extend still works but bolt opens extenstions
in the docs is a little typo
for the lazyload example you missed the closing round parentheses ')'
with allow twig set to true in your contentType field the twig tag no longer renders the image but the escaped twig output.
contentType Setup:
pages:
name: Pages
singular_name: Page
fields:
title:
type: text
class: large
group: content
slug:
type: slug
uses: title
image:
type: image
teaser:
type: html
height: 150px
body:
type: html
height: 300px
allowtwig: true # here alllow twig is set to true!
template:
type: templateselect
filter: '*.twig'
taxonomy: [ groups ]
recordsperpage: 100
a config with a missing sizes attribute doesn't fallback to the default of 100vw. It fallsback to the named config.
Example:
waterMarkedIMG:
widthDensity: 'w'
modifications:
small:
w: 200
fit: 'crop'
mark: 'bthumb-watermark.png'
markw: '30w'
markpos: center
medium:
w: 350
fit: 'crop'
mark: 'bthumb-watermark.png'
markw: '30w'
markpos: center
large:
w: 500
fit: 'stretch'
mark: 'watermark.png'
markw: '30w'
markpos: center
1_large:
w: 650
fit: 'stretch'
mark: 'watermark.png'
markw: '30w'
markpos: center
produces:
<img sizes="waterMarkedIMG"
srcset="srcset candidates"
src="src candidate"
alt="alt text provided">
images in a subfolder in the prime cache page don't have the correct path set for it's name. So on image creation an image is sent to the controller with it's basename and not its full file path name.
php app/nut betterthumbs:cacheClear filename.jpg
You'll get
[RuntimeException]
Accessed request service outside of request scope. Try moving that call to a before handler or controller.
in bolt 3.x.x versions jquery are different.
In bolt 3.0.11 jquery is version 2.2.1 in other versions its 2.2.4. This causes using bolt's asset function
<script src="{{ asset('js/jquery-2.2.4.min.js', 'bolt') }}"></script>
to break since bolt is using. The file is versioned twice. One version being the jquery version number and the second the query string appended to the file in the compiled twig output.
Quick and dirty solution. Use the Jquery CDN. Not google's CDN jquery's. This gets around proxies/firewalls that block google and certain countries that also block google.. looking at you the great firewall :)
In a normal linux server an image served from a responsive image set:
<img sizes="100vw"
srcset="/img/analog-camera-photography-vintage-1844.jpg?w=175 175w ,
/img/analog-camera-photography-vintage-1844.jpg?w=350 350w ,
/img/analog-camera-photography-vintage-1844.jpg?w=700 700w ,
/img/analog-camera-photography-vintage-1844.jpg?w=1400 1400w "
src="/analog-camera-photography-vintage-1844.jpg?w=175"
alt="analog-camera-photography-vintage-1844" >
on a browser that is ~1300px the image of
/img/analog-camera-photography-vintage-1844.jpg?w=700
will be generated and saved to the cache. If another person visits the same page with a smaller browser (~350px) then the image of
/img/analog-camera-photography-vintage-1844.jpg?w=350
will be served If you download/view this image you'll notice that its the same size as the image served from the very first cached visit (~700px). This is by design according to glide.
On a windows box each image requested is generated at the appropriate size.
Add in our default settings of signing the image then this breaks a little bit more.
This is no bueno for responsive images. Breaks the entire purpose of it. We're gonna have to bypass glide's cache. save the image under a new name (append the width or density descriptor to it) and then maybe use our own signing mechanism if signing is still broken.
Idea to do this similar to:
/** url would look like */
/img/?w=350&filt=sepia&fm=pjp/analog-camera-photography-vintage-350w.jpg
# the original file would be analog-camera-photography-vintage.jpg
/** in our controller */
public function connect(Application $app)
{
/** @var ControllerCollection $ctr */
$ctr = $app['controllers_factory'];
$ctr->get('/{modifications}/{path}', [$this, 'makeImage'])
->assert('path', '.+')
->bind('betterthumbs');
return $ctr;
}
public function makeImage(Application $app, $path, $modifications )
{
$configHelper = new ConfigHelper($this->config);
$presets = $configHelper->setPresets();
// set and merge any defaults
$defaults = $configHelper->setDefaults();
$app['betterthumbs']->setDefaults($defaults);
$app['betterthumbs']->setPresets($presets);
$app['betterthumbs']->setCacheWithFileExtensions(true);
$createImage = $app['betterthumbs']->makeImage($path, $modifications);
$basePath = $app['betterthumbs']->getCache()->read($createImage);
$app['betterthumbs']->getCache()->put($image, $basePath);
ob_clean();
return $app['betterthumbs']->outputImage($path, $modifications);
}
would need other logic to append/insert the width or density to the filename in the makeImage method or inside one of the helpers (probably a better Idea there)
related bug in glides repo: thephpleague/glide#155
Right now if you wanted to lazy load an image you can only use lazy load plugins or scripts that work by a single data attribute or by a class.
This is rigid. Since we use responsive images by default it makes sense to allow by default the markup pattern used by lazysizes
To make it flexible and allow other lazy load plugins make a config section with lazyload data/setup.
The default settings for this block should contain a few things.
ie:
# other settings
lazyload_settings: &lazySettings
lazyLoad_imgs: true
lazySizes: true
pattern: lqip #low quality image placeholder
# custom solution:
lazyload_settings: &lazySettings
lazyLoad_imgs: true
lazySizes: false
Then in a named config block have use yaml's repeated nodes
namedConfigBlock:
lazyload:
<<: *lazySettings
There's just to many variables and lazy load scripts to cover all of them. So either only allow lazysizes right now, or allow lazysizes, rework the config sections and add an option that just spits out the srcset and src attributes to be used in the twig template similar too:
<img sizes="your sizes"
srcset="{{ record.image|bthumbSrcset }}"
src="{{ record.image|bthumbSrc }}" >
If i follow that pattern I have to name the filter ( the |bthumbSrcset
portion ) something unique. Using just srcset
or src
is so generic and the actual names I can't guarantee they wont collide with another extensions filters. Using this pattern also allows me to simplify the lazyload section. This will allow me to only care about the lazysizes script and markup patterns. ie:
# other settings
lazyload_settings: &lazySettings
lazySizes: true
pattern: lqip #low quality image placeholder
# further down in a named config block
namedConfigBlock:
lazyload:
<<: *lazySettings
modifications:
# mods
This will use the lazy sizes markup pattern defined in the pattern section and if lazysizes is set to true will load the script from my vendor directory. If its false then the end user can load it from a cdn or their script bundles.
I think I'll try out this last pattern using filters :)
if no modifications are present then presets are used. Ideally to shorten the URL it should read:
<img src=" fallback src img"
srcset="/img/file-name.jpg?p=small&s=29f39473d9eedbc742fe90b6ec447ed4 175w,
/img/file-name.jpg?p=medium&s=6c7abd4958711a848f39e25905a10c73 350w,
/img/file-name.jpg?p=large&s=fa230fddc843fa4b1c763b6e72d496f5 700w,
/img/file-name.jpg?p=xlarge&s=79f74dc3a92976699cee74ded5b327a5 1400w"
alt="" >
instead of:
<img src="fallback src img"
srcset="/img/file-name.jpg?w=175&fit=stretch&s=29f39473d9eedbc742fe90b6ec447ed4 175w,
/img/file-name.jpg?w=350&fit=stretch&s=6c7abd4958711a848f39e25905a10c73 350w,
/img/file-name.jpg?w=700&fit=stretch&fm=png&s=fa230fddc843fa4b1c763b6e72d496f5 700w,
/img/file-name.jpg?w=1400&fit=stretch&s=79f74dc3a92976699cee74ded5b327a5 1400w"
alt=""
Response is not sending a 304 for not modified images.
Currently I can only get Firefox to send a 304. Chrome just constantly sends 200. Edge who knows cause you have to jump through hoops when using vagrant and I'm not about that action boss.
currently hitting enter or clicking the button allows an empty text input field to be submited to prime the cache for a single image.. cause im a goof :)
'betterthumbs/thumb.html.twig' is not defined
Version compare doesn't return the appropriate file path
boltbetterthumbs/src/Helpers/FilePathHelper.php
Lines 34 to 42 in 4733e64
For instance, the extension Translate adds "?_locale=en" at the end of any BackEnd request.
then the URL for Do Prime is https://my-site.com/bolt?_locale=en/extensions/betterthumbs/files/prime/do, and it does not work properly.
Is it possible to choose the size of the image used as fallback for browsers without srcset support?
For a site with more users on ie11 than non-supporting mobile browsers it would make sense to serve the original image as fallback instead of a smaller one. Otherwise ie11 users can end up with a heavily pixelated scaled-up image.
Looked through the docs but nothing jumps out as a simple way to do it (would prefer to avoid polyfills if possible).
I'm getting the following error when using the img
tag and the value is empty.
On my line 17 there's this:
{{ img(record.image, 'betterthumbs') }}
I don't know if this is the intented behaviour. But seems reasonable to me to check the existence of an image and display a 404 placeholder or don't display anything at all.
Meanwhile I'm using this to check before hand:
{% if record.image %}
{{ img(record.image, 'betterthumbs') }}
{% endif %}
If using something like varnish it don't save images twice. An image is created/requested saved to the cache then varnish again would typically save it.
Instead of filling up disk space use flysystems' memory adapter and don't save these images to the cache let varnish deal with them.
used here:
and
Will need to eventually move to bolt's filesystem to get the paths / directories
https://docs.bolt.cm/3.3/extensions/filesystem/working-with-directories
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.