diff --git a/app/client/src/js/app.js b/app/client/src/js/app.js index 3554f01..a6eec33 100644 --- a/app/client/src/js/app.js +++ b/app/client/src/js/app.js @@ -5,6 +5,7 @@ import '../scss/app.scss'; import MainUI from '@a2nt/ss-bootstrap-ui-webpack-boilerplate-react/src/js/_components/_main'; import '@a2nt/ss-bootstrap-ui-webpack-boilerplate-react/src/js/_ui/_ui.instagram.feed'; +import '@a2nt/ss-bootstrap-ui-webpack-boilerplate-react/src/js/_ui/_ui.carousel'; import './_layout'; @@ -30,5 +31,5 @@ const images = importAll( require.context('../img/', false, /\.(png|jpe?g|svg)$/), ); const fontAwesome = importAll( - require.context('font-awesome', false, /\.(otf|eot|svg|ttf|woff|woff2)$/), + require.context('font-awesome', false, /\.(otf|eot|ttf|woff|woff2)$/), ); diff --git a/app/client/src/scss/_variables.scss b/app/client/src/scss/_variables.scss index d5d353e..88f1139 100644 --- a/app/client/src/scss/_variables.scss +++ b/app/client/src/scss/_variables.scss @@ -1,4 +1,5 @@ -@import '~@a2nt/ss-bootstrap-ui-webpack-boilerplate-react/src/scss/_variables'; +$white: #fff; +$black: #000; $body-bg: #fff; $body-color: #212529; @@ -29,8 +30,7 @@ $body-main-nav-link-hover-color: $body-color; $body-main-nav-dropdown-hover-bg: $body-color; $body-footer-footer-bg: $body-bg; -$font-family-base: 'Roboto', -$font-family-sans-serif; +$font-family-base: 'Roboto'; // $full-body-min-width: map-get($grid-breakpoints, 'lg'); @@ -72,3 +72,7 @@ $carousel-controls-zindex: 11; $carousel-controls-shadow: 1px 1px $black; $carousel-controls-hover-bg: transparentize($black, 0.4); $carousel-slide-img-loading-max-height: 70vh; + +@import '~@a2nt/ss-bootstrap-ui-webpack-boilerplate-react/src/scss/_variables'; +$font-family-base: 'Roboto', +$font-family-sans-serif; diff --git a/app/src/Extensions/EmbeddedObjectExtension.php b/app/src/Extensions/EmbeddedObjectExtension.php index 9499a9d..b043a4d 100644 --- a/app/src/Extensions/EmbeddedObjectExtension.php +++ b/app/src/Extensions/EmbeddedObjectExtension.php @@ -41,36 +41,38 @@ class EmbeddedObjectExtension extends DataExtension $url, $matches ); - $videoID = $matches[1]; + if (isset($matches[1])) { + $videoID = $matches[1]; - $params = array_merge($params, [ - 'feature=oembed', - 'wmode=transparent', - 'enablejsapi=1', - 'disablekb=1', - 'iv_load_policy=3', - 'modestbranding=1', - 'rel=0', - 'showinfo=0', - //'controls='.($this->owner->getField('Controls') ? '1': '0') - ]); + $params = array_merge($params, [ + 'feature=oembed', + 'wmode=transparent', + 'enablejsapi=1', + 'disablekb=1', + 'iv_load_policy=3', + 'modestbranding=1', + 'rel=0', + 'showinfo=0', + //'controls='.($this->owner->getField('Controls') ? '1': '0') + ]); - if ($this->owner->getField('Autoplay')) { - $params[] = 'autoplay=1'; - $params[] = 'mute=1'; + if ($this->owner->getField('Autoplay')) { + $params[] = 'autoplay=1'; + $params[] = 'mute=1'; + } + + if ($this->owner->getField('Loop')) { + $params[] = 'loop=1'; + $params[] = 'playlist=' . $videoID; + } + + $this->owner->EmbedHTML = preg_replace( + '/src="([A-z0-9:\/\.]+)\??(.*?)"/', + 'src="https://www.youtube.com/embed/' . $videoID . '?' . implode('&', $params) . '" ' + . implode(' ', $iframe_params), + $this->owner->EmbedHTML + ); } - - if ($this->owner->getField('Loop')) { - $params[] = 'loop=1'; - $params[] = 'playlist='.$videoID; - } - - $this->owner->EmbedHTML = preg_replace( - '/src="([A-z0-9:\/\.]+)\??(.*?)"/', - 'src="https://www.youtube.com/embed/'.$videoID.'?' . implode('&', $params) . '" ' - .implode(' ', $iframe_params), - $this->owner->EmbedHTML - ); } if (stripos($this->owner->EmbedHTML, 'https://player.vimeo.com/video/') > 0) { diff --git a/app/templates/Includes/Footer.ss b/app/templates/Includes/Footer.ss index 448459c..1bb4edc 100644 --- a/app/templates/Includes/Footer.ss +++ b/app/templates/Includes/Footer.ss @@ -26,7 +26,7 @@ <% include Objects\SocialLinks %> <% end_with %> - + <% include LocaleMenu %> diff --git a/app/templates/Includes/SlideItem_media.ss b/app/templates/Includes/SlideItem_media.ss index 98d37eb..96eb291 100644 --- a/app/templates/Includes/SlideItem_media.ss +++ b/app/templates/Includes/SlideItem_media.ss @@ -6,7 +6,7 @@ <% else %> <% if $Image || $ImageURL %> - <% if $Headline %>$Headline.XML<% end_if %>' - : '', - }, - }), - ); + plugins.push( + new HtmlWebpackPlugin({ + publicPath: '', + template: path.join(conf.APPDIR, conf.SRC, 'index.html'), + templateParameters: { + NODE_ENV: NODE_ENV, + GRAPHQL_URL: conf['GRAPHQL_URL'], + STATIC_URL: conf['STATIC_URL'], + REACT_SCRIPTS: NODE_ENV === 'production' ? + '' : '', + }, + }), + ); } const faviconPath = path.join(__dirname, conf.APPDIR, conf.SRC, 'favicon.png'); if (filesystem.existsSync(faviconPath)) { - plugins.push( - new FaviconsWebpackPlugin({ - title: 'Webpack App', - logo: faviconPath, - prefix: '/icons/', - emitStats: false, - persistentCache: true, - inject: false, - statsFilename: path.join( - conf.APPDIR, - conf.DIST, - 'icons', - 'iconstats.json', - ), - icons: { - android: true, - appleIcon: true, - appleStartup: true, - coast: true, - favicons: true, - firefox: true, - opengraph: true, - twitter: true, - yandex: true, - windows: true, - }, - }), - ); + plugins.push( + new FaviconsWebpackPlugin({ + title: 'Webpack App', + logo: faviconPath, + prefix: '/icons/', + emitStats: false, + persistentCache: true, + inject: false, + statsFilename: path.join( + conf.APPDIR, + conf.DIST, + 'icons', + 'iconstats.json', + ), + icons: { + android: true, + appleIcon: true, + appleStartup: true, + coast: true, + favicons: true, + firefox: true, + opengraph: true, + twitter: true, + yandex: true, + windows: true, + }, + }), + ); } // add themes favicons commonVariables.themes.forEach((theme) => { - const faviconPath = path.join(__dirname, theme, conf.SRC, 'favicon.png'); - if (filesystem.existsSync(faviconPath)) { - plugins.push( - new FaviconsWebpackPlugin({ - title: 'Webpack App', - logo: faviconPath, - prefix: '/' + theme + '-icons/', - emitStats: false, - persistentCache: true, - inject: false, - statsFilename: path.join( - conf.APPDIR, - conf.DIST, - theme + '-icons', - 'iconstats.json', - ), - icons: { - android: true, - appleIcon: true, - appleStartup: true, - coast: true, - favicons: true, - firefox: true, - opengraph: true, - twitter: true, - yandex: true, - windows: true, - }, - }), - ); - } + const faviconPath = path.join(__dirname, theme, conf.SRC, 'favicon.png'); + if (filesystem.existsSync(faviconPath)) { + plugins.push( + new FaviconsWebpackPlugin({ + title: 'Webpack App', + logo: faviconPath, + prefix: '/' + theme + '-icons/', + emitStats: false, + persistentCache: true, + inject: false, + statsFilename: path.join( + conf.APPDIR, + conf.DIST, + theme + '-icons', + 'iconstats.json', + ), + icons: { + android: true, + appleIcon: true, + appleStartup: true, + coast: true, + favicons: true, + firefox: true, + opengraph: true, + twitter: true, + yandex: true, + windows: true, + }, + }), + ); + } }); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') - .BundleAnalyzerPlugin; + .BundleAnalyzerPlugin; plugins.push( - new BundleAnalyzerPlugin({ - analyzerMode: 'static', - openAnalyzer: false, - }), + new BundleAnalyzerPlugin({ + analyzerMode: 'static', + openAnalyzer: false, + }), ); const cfg = merge(common, { - mode: NODE_ENV, - cache: { - type: 'filesystem', - }, - recordsPath: path.join(__dirname, conf.APPDIR, conf.DIST, 'records.json'), - optimization: { - //removeAvailableModules: false, - //realContentHash: false, - splitChunks: { - name: 'vendor', - minChunks: 2, - }, - concatenateModules: true, //ModuleConcatenationPlugin - minimizer: [ - new TerserPlugin({ - terserOptions: { - module: false, - parse: { - // we want terser to parse ecma 8 code. However, we don't want it - // to apply any minfication steps that turns valid ecma 5 code - // into invalid ecma 5 code. This is why the 'compress' and 'output' - // sections only apply transformations that are ecma 5 safe - // https://github.com/facebook/create-react-app/pull/4234 - ecma: 8, - }, - compress: { - ecma: 5, - warnings: false, - // Disabled because of an issue with Uglify breaking seemingly valid code: - // https://github.com/facebook/create-react-app/issues/2376 - // Pending further investigation: - // https://github.com/mishoo/UglifyJS2/issues/2011 - comparisons: false, - }, - keep_fnames: true, - keep_classnames: true, + mode: NODE_ENV, + cache: { + type: 'filesystem', + }, + recordsPath: path.join(__dirname, conf.APPDIR, conf.DIST, 'records.json'), + optimization: { + //removeAvailableModules: false, + //realContentHash: false, + splitChunks: { + name: 'vendor', + minChunks: 2, + }, + concatenateModules: true, //ModuleConcatenationPlugin + minimizer: [ + new TerserPlugin({ + terserOptions: { + module: false, + parse: { + // we want terser to parse ecma 8 code. However, we don't want it + // to apply any minfication steps that turns valid ecma 5 code + // into invalid ecma 5 code. This is why the 'compress' and 'output' + // sections only apply transformations that are ecma 5 safe + // https://github.com/facebook/create-react-app/pull/4234 + ecma: 8, + }, + compress: { + ecma: 5, + warnings: false, + // Disabled because of an issue with Uglify breaking seemingly valid code: + // https://github.com/facebook/create-react-app/issues/2376 + // Pending further investigation: + // https://github.com/mishoo/UglifyJS2/issues/2011 + comparisons: false, + }, + keep_fnames: true, + keep_classnames: true, - mangle: { - safari10: true, - keep_fnames: true, - keep_classnames: true, - reserved: ['$', 'jQuery', 'jquery'], - }, - output: { - ecma: 5, - comments: false, - // Turned on because emoji and regex is not minified properly using default - // https://github.com/facebook/create-react-app/issues/2488 - ascii_only: true, - }, - }, - // Use multi-process parallel running to improve the build speed - // Default number of concurrent runs: os.cpus().length - 1 - parallel: true, - }), - ], - }, + mangle: { + safari10: true, + keep_fnames: true, + keep_classnames: true, + reserved: ['$', 'jQuery', 'jquery'], + }, + output: { + ecma: 5, + comments: false, + // Turned on because emoji and regex is not minified properly using default + // https://github.com/facebook/create-react-app/issues/2488 + ascii_only: true, + }, + }, + // Use multi-process parallel running to improve the build speed + // Default number of concurrent runs: os.cpus().length - 1 + parallel: true, + }), + ], + }, - output: { - publicPath: path.join(conf.APPDIR, conf.DIST), - path: path.join(__dirname, conf.APPDIR, conf.DIST), - filename: path.join('js', '[name].js'), - }, + output: { + publicPath: path.join(conf.APPDIR, conf.DIST), + path: path.join(__dirname, conf.APPDIR, conf.DIST), + filename: path.join('js', '[name].js'), + }, - module: { - rules: [ - { - test: /\.jsx?$/, - //exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - presets: [ - '@babel/preset-env', - '@babel/react', - { - plugins: [ - '@babel/plugin-proposal-class-properties', - ], - }, - ], //Preset used for env setup - plugins: [['@babel/transform-react-jsx']], - cacheDirectory: true, - cacheCompression: true, - }, - }, - }, - { - test: /\.s?css$/, - use: [ - { - loader: MiniCssExtractPlugin.loader, - }, - { - loader: 'css-loader', - options: { - sourceMap: !COMPRESS, - }, - }, - { - loader: 'resolve-url-loader', - }, - { - loader: 'sass-loader', - options: { - sourceMap: !COMPRESS, - }, - }, - ], - }, - { - test: /fontawesome([^.]+).(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, - use: [ - { - loader: 'file-loader', - options: { - name: '[name].[ext]', - outputPath: 'fonts/', - publicPath: '../fonts/', - }, - }, - ], - }, - { - test: /\.(ttf|otf|eot|svg|woff(2)?)$/, - use: [ - { - loader: 'file-loader', - options: { - name: '[name].[ext]', - outputPath: 'fonts/', - publicPath: '../fonts/', - }, - }, - ], - }, - { - test: /\.(png|webp|jpg|jpeg|gif|svg)$/, - use: [ - { - loader: 'img-optimize-loader', - options: { - name: '[name].[ext]', - outputPath: 'img/', - publicPath: '../img/', - compress: { - // This will take more time and get smaller images. - mode: 'low', // 'lossless', 'high', 'low' - disableOnDevelopment: true, - webp: conf['webp'], - // loseless compression for png - optipng: { - optimizationLevel: 4, - }, - // lossy compression for png. This will generate smaller file than optipng. - pngquant: { - quality: [0.2, 0.8], - }, - // Compression for svg. - svgo: true, - // Compression for gif. - gifsicle: { - optimizationLevel: 3, - }, - // Compression for jpg. - mozjpeg: { - progressive: true, - quality: 60, - }, - }, - inline: { - limit: 1, - }, - }, - }, - ], - }, - ], - }, + module: { + rules: [{ + test: /\.jsx?$/, + //exclude: /node_modules/, + use: { + loader: 'babel-loader', + options: { + presets: [ + '@babel/preset-env', + '@babel/react', + { + plugins: [ + '@babel/plugin-proposal-class-properties', + ], + }, + ], //Preset used for env setup + plugins: [ + ['@babel/transform-react-jsx'] + ], + cacheDirectory: true, + cacheCompression: true, + }, + }, + }, + { + test: /\.s?css$/, + use: [{ + loader: MiniCssExtractPlugin.loader, + }, + { + loader: 'css-loader', + options: { + sourceMap: !COMPRESS, + }, + }, + { + loader: 'resolve-url-loader', + }, + { + loader: 'sass-loader', + options: { + sourceMap: !COMPRESS, + }, + }, + ], + }, + { + test: /fontawesome([^.]+).(ttf|otf|eot|woff(2)?)(\?[a-z0-9]+)?$/, + use: [{ + loader: 'file-loader', + options: { + name: '[name].[ext]', + outputPath: 'fonts/', + publicPath: '../fonts/', + }, + }, ], + }, + { + test: /\.(ttf|otf|eot|svg|woff(2)?)$/, + use: [{ + loader: 'file-loader', + options: { + name: '[name].[ext]', + outputPath: 'fonts/', + publicPath: '../fonts/', + }, + }, ], + }, + { + test: /\.(png|webp|jpg|jpeg|gif|svg)$/, + use: [{ + loader: 'img-optimize-loader', + options: { + name: '[name].[ext]', + outputPath: 'img/', + publicPath: '../img/', + compress: { + // This will take more time and get smaller images. + mode: 'low', // 'lossless', 'high', 'low' + disableOnDevelopment: true, + webp: conf['webp'], + // loseless compression for png + optipng: { + optimizationLevel: 4, + }, + // lossy compression for png. This will generate smaller file than optipng. + pngquant: { + quality: [0.2, 0.8], + }, + // Compression for svg. + svgo: true, + // Compression for gif. + gifsicle: { + optimizationLevel: 3, + }, + // Compression for jpg. + mozjpeg: { + progressive: true, + quality: 60, + }, + }, + inline: { + limit: 1, + }, + }, + }, ], + }, + ], + }, - plugins: plugins, + plugins: plugins, }); console.log(cfg); diff --git a/webpack.config.serve.js b/webpack.config.serve.js index 0d2854c..7f9a308 100644 --- a/webpack.config.serve.js +++ b/webpack.config.serve.js @@ -66,8 +66,7 @@ if (filesystem.existsSync(indexPath)) { GRAPHQL_URL: conf['GRAPHQL_URL'], STATIC_URL: conf['STATIC_URL'], REACT_SCRIPTS: NODE_ENV === 'production' ? - '' : - '', + '' : '', }, }), ); @@ -89,8 +88,8 @@ const config = merge(common, { filename: '[name].js', // necessary for HMR to know where to load the hot update chunks publicPath: `http${conf['HTTPS'] ? 's' : ''}://${conf['HOSTNAME']}:${ - conf.PORT - }/`, + conf.PORT + }/`, }, module: { @@ -142,7 +141,7 @@ const config = merge(common, { ], }, { - test: /fontawesome([^.]+).(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, + test: /fontawesome([^.]+).(ttf|otf|eot|woff(2)?)(\?[a-z0-9]+)?$/, use: [{ loader: 'url-loader', }, ],