IMPR: WebP format + some minor improvements

This commit is contained in:
Tony Air 2020-07-20 17:25:57 +07:00
parent bc7fea884a
commit 2c97a2a4cf
14 changed files with 109 additions and 45 deletions

View File

@ -10,4 +10,5 @@ Site\Templates\WebpackTemplateProvider:
SRC: client/src SRC: client/src
DIST: client/dist DIST: client/dist
TYPESJS: client/src/js/types TYPESJS: client/src/js/types
TYPESSCSS: client/src/scss/types TYPESSCSS: client/src/scss/types
webp: false

View File

@ -74,7 +74,7 @@ class MapElement extends ElementContent
return $fields; return $fields;
} }
public function MapAPIKey(): string public static function MapAPIKey(): string
{ {
$type = self::config()->get('map_type'); $type = self::config()->get('map_type');

View File

@ -3,11 +3,24 @@
namespace Site\Extensions; namespace Site\Extensions;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Extension; use SilverStripe\Core\Extension;
use SilverStripe\FontAwesome\FontAwesomeField;
use SilverStripe\View\Requirements;
use Site\Templates\DeferredRequirements;
class LeftAndMainExtension extends Extension class LeftAndMainExtension extends Extension
{ {
public function init() public function init()
{ {
$config = Config::inst()->get(DeferredRequirements::class);
// App libs
if (!$config['nofontawesome']) {
$v = !isset($config['fontawesome_version']) || !$config['fontawesome_version']
? Config::inst()->get(FontAwesomeField::class, 'version')
: $config['fontawesome_version'];
Requirements::css('//use.fontawesome.com/releases/v'.$v.'/css/all.css');
}
} }
} }

View File

@ -31,6 +31,7 @@ class WebpackTemplateProvider implements TemplateGlobalProvider
* @var string assets static files directory * @var string assets static files directory
*/ */
private static $dist = 'client/dist'; private static $dist = 'client/dist';
private static $webp = false;
/** /**
* @return array * @return array
@ -81,7 +82,20 @@ class WebpackTemplateProvider implements TemplateGlobalProvider
public static function resourcesURL($link = null): string public static function resourcesURL($link = null): string
{ {
return Controller::join_links(Director::baseURL(), '/resources/'.self::projectName().'/client/dist/img/', $link); $cfg = self::config();
if ($cfg['webp'] && !self::isActive()) {
$link = str_replace(['.png','.jpg','.jpeg'], '.webp', $link);
}
return Controller::join_links(
Director::baseURL(),
'/resources/',
self::projectName(),
$cfg['dist'],
'img',
$link
);
} }

View File

@ -80,6 +80,13 @@ class TestServer extends BuildTask
echo self::error('Assets dir <b>'.ASSETS_DIR.'</b> dir is no writable!'); echo self::error('Assets dir <b>'.ASSETS_DIR.'</b> dir is no writable!');
} }
if (function_exists('imagewebp')) {
echo self::success('WebP is available');
} else {
echo self::error('WebP is not available');
}
die(); die();
} }

View File

@ -0,0 +1,18 @@
<?php
namespace Site\Traits;
trait PaginatedListing
{
private $filter = [];
public function NextPage($pageID = null)
{
$vars = $this->getRequest()->requestVars();
$vars = array_filter($vars);
$vars['page'] = $pageID ? $pageID : '2';
return $this->Link('?'.http_build_query($vars));
}
}

View File

@ -9,7 +9,6 @@
aria-haspopup="true" aria-haspopup="true"
aria-expanded="false" aria-expanded="false"
href="{$Link}" href="{$Link}"
title="$Title.XML"
> >
$MenuTitle.XML $MenuTitle.XML
<% if $isCurrent || $isSection %><i class="sr-only">(current)</i><% end_if %> <% if $isCurrent || $isSection %><i class="sr-only">(current)</i><% end_if %>

View File

@ -3,11 +3,7 @@
<% loop $NotificationsToday %> <% loop $NotificationsToday %>
<div class="alert alert-warning"> <div class="alert alert-warning">
<div class="container"> <div class="container">
<b class="btn btn-danger btn-close" data-dismiss="alert" aria-label="Close"> <% if $DisplayTitle && $Title %>
<i class="fas fa-times"></i>
</b>
<% if $Title %>
<h2>$Title</h2> <h2>$Title</h2>
<% end_if %> <% end_if %>
@ -25,6 +21,10 @@
</a> </a>
<% end_with %> <% end_with %>
<% end_if %> <% end_if %>
<b class="btn btn-danger btn-close" data-dismiss="alert" aria-label="Close">
<i class="fas fa-times"></i>
</b>
</div> </div>
</div> </div>
<% end_loop %> <% end_loop %>

View File

@ -44,7 +44,8 @@
"a2nt/silverstripe-font-awesome-field": "dev-master", "a2nt/silverstripe-font-awesome-field": "dev-master",
"a2nt/silverstripe-mapboxfield": "dev-master", "a2nt/silverstripe-mapboxfield": "dev-master",
"a2nt/silverstripe-progressivewebapp": "dev-master", "a2nt/silverstripe-progressivewebapp": "dev-master",
"bummzack/sortablefile": "*" "bummzack/sortablefile": "*",
"showpro/silverstripe-seo-images": "*"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^5.7", "phpunit/phpunit": "^5.7",

View File

@ -1,6 +1,6 @@
{ {
"name": "ss-webpack-boilerplate", "name": "ss-webpack-boilerplate",
"version": "2.2.1", "version": "2.0.2",
"description": "Lets you create SilverStripe faster", "description": "Lets you create SilverStripe faster",
"author": "Tony Air <tony@twma.pro>", "author": "Tony Air <tony@twma.pro>",
"license": "MIT", "license": "MIT",
@ -32,7 +32,7 @@
], ],
"dependencies": { "dependencies": {
"@a2nt/meta-lightbox": "^2.2.1", "@a2nt/meta-lightbox": "^2.2.1",
"@a2nt/ss-bootstrap-ui-webpack-boilerplate": "^2.2.1", "@a2nt/ss-bootstrap-ui-webpack-boilerplate": "^2.3.1",
"bootbox": "^4.4.0", "bootbox": "^4.4.0",
"bootstrap": "^4.5.0", "bootstrap": "^4.5.0",
"bootstrap-confirmation2": "^4.1.0", "bootstrap-confirmation2": "^4.1.0",
@ -40,6 +40,7 @@
"bootstrap-offcanvas": "^1.0.0", "bootstrap-offcanvas": "^1.0.0",
"bootstrap-table": "^1.16.0", "bootstrap-table": "^1.16.0",
"bootstrap-timepicker": "^0.5.2", "bootstrap-timepicker": "^0.5.2",
"exif-js": "^2.3.0",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
"inputmask": "^5.0.3", "inputmask": "^5.0.3",
@ -50,23 +51,25 @@
"jquery.appear": "^1.0.1", "jquery.appear": "^1.0.1",
"mapbox-gl": "^1.11.0", "mapbox-gl": "^1.11.0",
"material-design-color": "^2.3.2", "material-design-color": "^2.3.2",
"moment": "^2.27.0",
"offcanvas-bootstrap": "^2.5.2",
"popper.js": "*", "popper.js": "*",
"select2": "^4.0.13", "select2": "^4.0.13",
"setimmediate": "^1.0.5",
"smooth-scroll": "^14.2.1", "smooth-scroll": "^14.2.1",
"sticky-sidebar": "^3.3.1", "sticky-sidebar": "^3.3.1",
"tablednd": "^1.0.3",
"yarn": "^1.22.4" "yarn": "^1.22.4"
}, },
"devDependencies": { "devDependencies": {
"@a2nt/image-sprite-webpack-plugin": "^0.2.5", "@a2nt/image-sprite-webpack-plugin": "^0.2.5",
"@babel/core": "^7.10.2", "@babel/core": "^7.10.4",
"@babel/plugin-proposal-object-rest-spread": "^7.10.1", "@babel/plugin-proposal-object-rest-spread": "^7.10.4",
"@babel/plugin-transform-react-jsx": "^7.10.1", "@babel/plugin-transform-react-jsx": "^7.10.4",
"@babel/preset-env": "^7.10.2", "@babel/preset-env": "^7.10.4",
"@google/markerclusterer": "^1.0.3", "@google/markerclusterer": "^1.0.3",
"animate.css": "^3.7.2", "animate.css": "^3.7.2",
"ansi-html": "^0.0.7", "autoprefixer": "^9.8.4",
"ansi-regex": "^5.0.0",
"autoprefixer": "^9.8.0",
"babel-eslint": "^8.2.6", "babel-eslint": "^8.2.6",
"babel-loader": "^8.1.0", "babel-loader": "^8.1.0",
"copy-webpack-plugin": "^4.6.0", "copy-webpack-plugin": "^4.6.0",
@ -74,21 +77,22 @@
"cross-env": "^5.2.1", "cross-env": "^5.2.1",
"css-loader": "^3.6.0", "css-loader": "^3.6.0",
"eslint": "^4.19.1", "eslint": "^4.19.1",
"eslint-plugin-import": "^2.21.2", "eslint-plugin-import": "^2.22.0",
"eslint-plugin-jquery": "^1.5.1", "eslint-plugin-jquery": "^1.5.1",
"eslint-plugin-react": "^7.20.0", "eslint-plugin-react": "^7.20.3",
"exports-loader": "^0.7.0", "exports-loader": "^0.7.0",
"favicons-webpack-plugin": "0.0.9", "favicons-webpack-plugin": "0.0.9",
"file-loader": "^5.1.0", "file-loader": "^5.1.0",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
"hard-source-webpack-plugin": "^0.13.1", "hard-source-webpack-plugin": "^0.13.1",
"html-entities": "^1.3.1",
"html-webpack-plugin": "^4.3.0", "html-webpack-plugin": "^4.3.0",
"imagemin-gifsicle": "^7.0.0", "imagemin-gifsicle": "^7.0.0",
"imagemin-jpegtran": "^6.0.0", "imagemin-jpegtran": "^6.0.0",
"imagemin-optipng": "^7.1.0", "imagemin-optipng": "^7.1.0",
"imagemin-svgo": "^7.1.0", "imagemin-svgo": "^7.1.0",
"imagemin-webp": "^6.0.0",
"imagemin-webpack": "^5.1.1", "imagemin-webpack": "^5.1.1",
"img-optimize-loader": "^1.0.4",
"loglevel": "^1.6.8", "loglevel": "^1.6.8",
"mini-css-extract-plugin": "^0.9.0", "mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.14.1", "node-sass": "^4.14.1",
@ -102,8 +106,6 @@
"sass-lint-fix": "^1.12.1", "sass-lint-fix": "^1.12.1",
"sass-loader": "^8.0.2", "sass-loader": "^8.0.2",
"script-ext-html-webpack-plugin": "^2.1.4", "script-ext-html-webpack-plugin": "^2.1.4",
"sockjs-client": "^1.4.0",
"strip-ansi": "^6.0.0",
"style-loader": "^0.19.1", "style-loader": "^0.19.1",
"svg-url-loader": "^2.3.3", "svg-url-loader": "^2.3.3",
"terser-webpack-plugin": "^2.3.7", "terser-webpack-plugin": "^2.3.7",

View File

@ -5,9 +5,9 @@ ini_set('display_startup_errors', 1);
error_reporting(E_ALL); error_reporting(E_ALL);
require_once('vendor/autoload.php'); require_once('vendor/autoload.php');
require_once('framework/core/Constants.php'); //require_once('vendor/silverstripe/framework/src/Core/Constants.php');
require_once('app/code/Tasks/TestServer.php'); require_once('app/src/Tests/TestServer.php');
$req = new \SilverStripe\Control\NullHTTPRequest(); $req = new \SilverStripe\Control\NullHTTPRequest();

View File

@ -12,7 +12,6 @@ const filesystem = require('fs');
const includes = {}; const includes = {};
const modules = [ const modules = [
path.resolve(__dirname, 'public'),
path.resolve(__dirname, conf.APPDIR, 'client', 'src'), path.resolve(__dirname, conf.APPDIR, 'client', 'src'),
path.resolve(__dirname, conf.APPDIR, 'client', 'src', 'js'), path.resolve(__dirname, conf.APPDIR, 'client', 'src', 'js'),
path.resolve(__dirname, conf.APPDIR, 'client', 'src', 'scss'), path.resolve(__dirname, conf.APPDIR, 'client', 'src', 'scss'),
@ -20,9 +19,11 @@ const modules = [
path.resolve(__dirname, conf.APPDIR, 'client', 'src', 'thirdparty'), path.resolve(__dirname, conf.APPDIR, 'client', 'src', 'thirdparty'),
path.resolve(__dirname, conf.APPDIR, 'client', 'node_modules'), path.resolve(__dirname, conf.APPDIR, 'client', 'node_modules'),
path.resolve(__dirname, 'node_modules'), path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname),
path.resolve(__dirname, 'public'),
]; ];
const _addAppFiles = theme => { const _addAppFiles = (theme) => {
const dirPath = path.resolve(__dirname, theme); const dirPath = path.resolve(__dirname, theme);
const themeName = path.basename(theme); const themeName = path.basename(theme);
@ -44,11 +45,11 @@ const _addAppFiles = theme => {
modules.push(path.join(dirPath, 'client', 'src', 'img')); modules.push(path.join(dirPath, 'client', 'src', 'img'));
modules.push(path.join(dirPath, 'client', 'src', 'thirdparty')); modules.push(path.join(dirPath, 'client', 'src', 'thirdparty'));
const _getAllFilesFromFolder = function(dir, includeSubFolders = true) { const _getAllFilesFromFolder = function (dir, includeSubFolders = true) {
const dirPath = path.resolve(__dirname, dir); const dirPath = path.resolve(__dirname, dir);
let results = []; let results = [];
filesystem.readdirSync(dirPath).forEach(file => { filesystem.readdirSync(dirPath).forEach((file) => {
if (file.charAt(0) === '_') { if (file.charAt(0) === '_') {
return; return;
} }
@ -72,7 +73,7 @@ const _addAppFiles = theme => {
const typesJSPath = path.join(theme, conf.TYPESJS); const typesJSPath = path.join(theme, conf.TYPESJS);
if (filesystem.existsSync(typesJSPath)) { if (filesystem.existsSync(typesJSPath)) {
const pageScripts = _getAllFilesFromFolder(typesJSPath, true); const pageScripts = _getAllFilesFromFolder(typesJSPath, true);
pageScripts.forEach(file => { pageScripts.forEach((file) => {
includes[`${themeName}_${path.basename(file, '.js')}`] = file; includes[`${themeName}_${path.basename(file, '.js')}`] = file;
}); });
} }
@ -81,7 +82,7 @@ const _addAppFiles = theme => {
const typesSCSSPath = path.join(theme, conf.TYPESSCSS); const typesSCSSPath = path.join(theme, conf.TYPESSCSS);
if (filesystem.existsSync(typesSCSSPath)) { if (filesystem.existsSync(typesSCSSPath)) {
const scssIncludes = _getAllFilesFromFolder(typesSCSSPath, true); const scssIncludes = _getAllFilesFromFolder(typesSCSSPath, true);
scssIncludes.forEach(file => { scssIncludes.forEach((file) => {
includes[`${themeName}_${path.basename(file, '.scss')}`] = file; includes[`${themeName}_${path.basename(file, '.scss')}`] = file;
}); });
} }
@ -90,7 +91,7 @@ const _addAppFiles = theme => {
_addAppFiles(conf.APPDIR); _addAppFiles(conf.APPDIR);
// add themes // add themes
commonVariables.themes.forEach(theme => { commonVariables.themes.forEach((theme) => {
_addAppFiles(theme); _addAppFiles(theme);
}); });

View File

@ -77,7 +77,7 @@ const config = merge.strategy({
], ],
}, },
{ {
test: /\.(gif|png|jpg|jpeg|ttf|otf|eot|svg|woff(2)?)$/, test: /\.(gif|png|jpg|jpeg|ttf|otf|eot|svg|webp|woff(2)?)$/,
use: [ use: [
{ {
loader: 'file-loader', loader: 'file-loader',

View File

@ -102,10 +102,11 @@ let plugins = [
], ],
}, },
], ],
['webp', { quality: 100 }],
], ],
}, },
}), }),
new ImageSpritePlugin({ /*new ImageSpritePlugin({
exclude: /exclude|original|default-|icons|sprite/, exclude: /exclude|original|default-|icons|sprite/,
commentOrigin: false, commentOrigin: false,
compress: true, compress: true,
@ -115,11 +116,11 @@ let plugins = [
//outputPath: path.join(__dirname, conf.APPDIR, conf.DIST), //outputPath: path.join(__dirname, conf.APPDIR, conf.DIST),
outputFilename: 'img/sprite-[hash].png', outputFilename: 'img/sprite-[hash].png',
padding: 0, padding: 0,
}), }),*/
]; ];
// add themes favicons // add themes favicons
commonVariables.themes.forEach(theme => { commonVariables.themes.forEach((theme) => {
const faviconPath = path.join(__dirname, theme, conf.SRC, 'favicon.png'); const faviconPath = path.join(__dirname, theme, conf.SRC, 'favicon.png');
if (filesystem.existsSync(faviconPath)) { if (filesystem.existsSync(faviconPath)) {
plugins.push( plugins.push(
@ -272,17 +273,24 @@ module.exports = merge(common, {
], ],
}, },
{ {
test: /\.(png|jpg|jpeg|gif|svg)$/, test: /\.(png|webp|jpg|jpeg|gif|svg)$/,
loader: 'img-optimize-loader',
options: {
compress: {
// This will take more time and get smaller images.
mode: 'high', // 'lossless', 'low'
disableOnDevelopment: true,
webp: conf['webp'],
},
},
},
{
test: /\.(png|webp|jpg|jpeg|gif|svg)$/,
loader: 'file-loader', loader: 'file-loader',
options: { options: {
name: '[name].[ext]', name: conf['webp'] ? '[name].webp' : '[name].[ext]',
outputPath: 'img/', outputPath: 'img/',
publicPath: '../img/', publicPath: '../img/',
/*,
name(file) {
//return 'public/[path][name].[ext]';
return '[hash].[ext]';
},*/
}, },
}, },
], ],