Skip to content

Commit

Permalink
Added Glide for on-demand image resizing
Browse files Browse the repository at this point in the history
  • Loading branch information
Swader committed Mar 6, 2016
1 parent 8bb24d3 commit bd4cb31
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 1 deletion.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,8 @@ nb-configuration.xml
public/dist/css/*.css
public/dist/js/*.js

# Ignore all generated images, but keep the folder
public/static/image/*
!public/static/image/.gitkeep

/phinx.yml
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ To get access to flash messages, either retrieve the flasher instance from the c

To style the messages, several pre-configured templates exist that you can inject into the Flash class. Most popular CSS frameworks are covered. For available templates, see `vendor/tamtamchik/simple-flash/src/Templates/`. Change the injected template in `app/config.php` (notice that Foundation6 is injected by default).

### Image generation

This skeleton comes with [Glide](http://glide.thephpleague.com) which generates resized images from a source image on-demand - perfect for media queries. It also saves them for later, so the next time they're requested, they don't need to be regenerated. In a nutshell, this allows you to have a single image like `assets/image/xyz.png`, and then request it with `/static/image/xyz-WIDTH.png` and it will get automatically generated at that width.

For a demonstration of this, see the homepage when you install the project, or read [this tutorial](http://www.sitepoint.com/easy-dynamic-on-demand-image-resizing-with-glide).

Note that while this is on by default, it is entirely optional - you can disable this image generation by commenting out the related route in `routes.php`.

### Styling

See [FRONTEND.md](docs/FRONTEND.md).
Expand Down
20 changes: 20 additions & 0 deletions app/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,26 @@
return $te;
},

'glide' => function () {
$server = League\Glide\ServerFactory::create(
[
'source' => new League\Flysystem\Filesystem(
new League\Flysystem\Adapter\Local(
__DIR__ . '/../assets/image'
)
),
'cache' => new League\Flysystem\Filesystem(
new League\Flysystem\Adapter\Local(
__DIR__ . '/../public/static/image'
)
),
'driver' => 'gd',
]
);

return $server;
},

ClientInterface::class => function () {
$client = new Client();

Expand Down
5 changes: 5 additions & 0 deletions app/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,9 @@
['GET', '/account', 'Standard\Controllers\AccountController'],
['GET', '/account/index', ['Standard\Controllers\AccountController', 'indexAction']],

/* Comment the line below if you don't want to use Glide's dynamic
* image generation (see http://www.sitepoint.com/easy-dynamic-on-demand-image-resizing-with-glide) */
['GET', '/static/image/{image}', ['Standard\Controllers\ImageController', 'renderImage']],
['GET', '/image/demo', ['Standard\Controllers\ImageController', 'demo']]

];
Empty file added assets/image/.gitkeep
Empty file.
Binary file added assets/image/sitepoint_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"tamtamchik/simple-flash": "dev-master",
"respect/validation": "^1.0",
"sitepoint/rauth": "dev-master",
"doctrine/annotations": "^1.2"
"doctrine/annotations": "^1.2",
"league/glide": "^1.0"
},
"require-dev": {
"symfony/var-dumper": "^3.0",
Expand Down
Empty file added public/static/image/.gitkeep
Empty file.
78 changes: 78 additions & 0 deletions src/Standard/Controllers/ImageController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

namespace Standard\Controllers;

use League\Glide\Server;
use Standard\Abstracts\Controller;
use Twig_Environment;

class ImageController extends Controller
{
/**
* @Inject("glide")
* @var Server
*/
private $glide;

private $allowedWidths = [
320,
460,
768,
992,
1280,
1920,
];

/**
* @var Twig_Environment
*/
private $twig;

public function __construct(Twig_Environment $twig)
{
$this->twig = $twig;
}

public function renderImage($image)
{
$width = $this->getWidth($image);

$imageSource = str_replace('-'.$width, '', $image);

$imagePath = $this->glide->makeImage($imageSource, ['w' => $width]);
$imageBase = $this->glide->getCache()->read($imagePath);
$this->glide->getCache()->put($image, $imageBase);
$this->glide->outputImage($imageSource, ['w' => $width]);
}

/**
* @param string $imagePath
* @return int
*/
private function getWidth(string $imagePath) : int
{
$fragments = explode('-', $imagePath);

if (count($fragments) < 2) {
header(
($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0') . ' 500 ' . 'Server Error ImgErr00'
);
die("Nope! Image fragments missing.");
}

$width = (int)explode('.', $fragments[1])[0];
if (!in_array($width, $this->allowedWidths)) {
header(
($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0') . ' 500 ' . 'Server Error ImgErr01'
);
die("Nope! Disallowed width: ".$width." for image ".$imagePath);
}

return $width;
}

public function demo()
{
echo $this->twig->render('image/demo.twig');
}
}
6 changes: 6 additions & 0 deletions src/Standard/Views/home.twig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
<p>This is a highly configurable skeleton app with dependency injection, user authentication and authorization, templating, flash messages, and more. It's a no-framework framework, in a way. For details, please see the
<a href="https://github.com/swader/nofw">README</a>.</p>

<h2>Dynamic image generation demo</h2>

<p>This skeleton comes with PhpLeague's <a
href="http://glide.thephpleague.org">Glide</a>, a library for dynamically generating different sizes of images for different devices. This allows you to include a single source image (i.e. "sitepoint_logo.png"), request a resized version (i.e. "sitepoint_logo-320.png") and it will get generated automatically - even saved for later use. This is perfect for media queries and the like. To test this out, go
<a href="/image/demo">here</a>.</p>

{% if username == null %}
<p>To sign up / log in, please go <a href="/auth">here</a>.</p>
{% endif %}
Expand Down
16 changes: 16 additions & 0 deletions src/Standard/Views/image/demo.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% extends 'layout/master.twig' %}

{% block content %}

<h1>Demo of on-demand images</h1>

<p>The image below was generated by requesting "public/static/image/sitepoint_logo-320.png", which did not exist beforehand. It was generated from "assets/image/sitepoint_logo.png". Try changing its width in dev tools to one of the following to generate a new one, or to any other width to generate an error. You can alter the allowed widths in "Standard/Controllers/ImageController", and you can change the path from which the source is read and to which the processed image is saved in "app/config.php".</p>

<p><img src="/static/image/sitepoint_logo-320.png"
alt="SitePoint Logo Resized"></p>

<p>Feel free to delete "public/static/image/sitepoint_logo-320.png" and refresh this page - it will re-appear.</p>

<p>Adding more images is just a matter of adding extra source images into "assets/image" and using them with a width suffix. Note that the widths are limited to prevent an image-processing attack (someone could request a billion sizes if it weren't limited).</p>

{% endblock %}

0 comments on commit bd4cb31

Please sign in to comment.