diff --git a/README.md b/README.md index ad1cd98..b3258ca 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,22 @@ Checkout files at /site/ folder for details + WebpackTemplateProvider::WebpackJS('file-name') and WebpackTemplateProvider::WebpackCSS('file-name') can be used at php area + All images will be optimised at /site/src/img and will be written to /site/dist/img (by default) + Favicons will be generated at /site/dist/icons using /site/src/favicon.png -+ Folder /site/src/js/types is used to create page specific JS (just create a JS file there and it will be compiled) ++ Folder /site/src/js/types is used to create page specific JS (just create JS file there and it will be compiled) ++ Folder /site/src/scss/types is used to create page specific CSS (just create SCSS file there and it will be compiled) ++ Automatic linting (JS+SCSS) + Bootstrap 4 included by default ++ Font-Awesome included by default ++ Deferred requirements loading ++ Requirements auto-loading ### Folder structure: + + /site/_config/webpack.yml (Webpack configurtion) + /site/code/WebpackTemplateProvider.php (WebpackJS and WebpackCSS functionality) ++ /site/code/DeferedRequirements.php (Deferred Requirements + Requirements auto-loader) + /site/templates/Page.ss (An example Page.ss) + /site/src (Your sources) ++ /site/dist (Your production assets) @@ -28,18 +36,16 @@ Checkout files at /site/ folder for details + /site/src/js/main.js (Your custom site-wide functionality) + /site/src/js/_events.js (Your custom site-wide events) + /site/src/js/_pageType_and_component_template.js (A template which can be used to create new modules) -+ /site/src/types/*.js (Extra page-specific modules to be autocompiled. My suggestion is to use *ClassName*.js and then require it at SilverStripe custom controller area) ++ /site/src/types/*.js (Extra page-specific modules to be auto-compiled. My suggestion is to use *ClassName*.js and then require it at SilverStripe custom controller area) + /site/src/scss (Your styling to be compiled) + /site/src/scss/_components (Your custom SCSS components) -+ /site/src/scss/app.scss (main application file to include sie-wide components) ++ /site/src/scss/app.scss (main application file to include site-wide components) + /site/src/scss/_variables.sccs (your custom variables, ex. bootstrap) + /site/src/scss/_layout.sccs (Your site-wide styling) -##### P.S to compile page specific styling add following line to /site/src/types/*PageClassName*.js -###### import "../scss/types/*PageClassName*.scss"; ### Requirements: @@ -51,14 +57,16 @@ Checkout files at /site/ folder for details + git clone https://github.com/a2nt/silverstripe-webpack.git + cd silverstripe-webpack + composer install -+ yarn install ++ npm install + edit robots.txt, humans.txt, cache.appcache, manifest.json and package.json to setup your own project ### Commands: + yarn - to update packages -+ yarn start - to start webpack webserver -+ yarn build - to build assets# silverstripe-webpack ++ yarn start - to start webpack development webserver ++ yarn build - to build production assets ++ yarn lint:check - to check SCSS and JS linting ++ yarn lint:fix - to fix SCSS and JS linting automatically ### TODO: diff --git a/site/_config/webpack.yml b/site/_config/webpack.yml index f2b9109..be96c54 100644 --- a/site/_config/webpack.yml +++ b/site/_config/webpack.yml @@ -2,10 +2,10 @@ # with all configuration variables presented # Cuz WebPack compiling script use it to set configuration -WebpackTemplateProvider: - dist: site/dist - hostname: localhost - port: "3000" - pages: site/src/js/types - pagesscss: site/src/scss/types - src: site/src +WebpackTemplateProvider: + SRC: site/src + DIST: site/dist + HOSTNAME: localhost + PORT: "3000" + TYPESJS: site/src/js/types + TYPESSCSS: site/src/scss/types diff --git a/site/code/DeferedRequirements.php b/site/code/DeferedRequirements.php new file mode 100755 index 0000000..29b3d05 --- /dev/null +++ b/site/code/DeferedRequirements.php @@ -0,0 +1,122 @@ + 'Auto', + 'DeferedCSS' => 'loadCSS', + 'DeferedJS' => 'loadJS', + ]; + } + + public static function Auto($class = false) + { + // Initialization + Requirements::block(THIRDPARTY_DIR.'/jquery/jquery.js'); + if (defined('FONT_AWESOME_DIR')) { + Requirements::block(FONT_AWESOME_DIR.'/css/lib/font-awesome.min.css'); + } + Requirements::set_force_js_to_bottom(true); + + // Main libs + DeferedRequirements::loadJS('//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js'); + + // App libs + DeferedRequirements::loadJS(project().'/dist/js/app.js'); + DeferedRequirements::loadCSS(project().'/dist/css/app.css'); + + // Class libs + if($class) { + DeferedRequirements::loadJS(project() . '/dist/js/' . $class . '.js'); + DeferedRequirements::loadCSS(project() . '/dist/css/' . $class . '.css'); + } + + return self::forTemplate(); + } + + public static function loadCSS($css) + { + if (self::$defered && !self::_webpackActive()) { + self::$css[] = $css; + } else { + WebpackTemplateProvider::loadCSS($css); + } + } + + public static function loadJS($js) + { + if (self::$defered && !self::_webpackActive()) { + self::$js[] = $js; + } else { + WebpackTemplateProvider::loadJS($js); + } + } + + protected static function _webpackActive() + { + return class_exists('WebpackTemplateProvider') && WebpackTemplateProvider::isActive(); + } + + public static function setDefered($bool) + { + self::$defered = $bool; + } + + public static function forTemplate() + { + if (!self::$defered || self::_webpackActive()) { + return false; + } + + $result = ''; + foreach (self::$css as $css) { + $result .= ''; + } + foreach (self::$js as $js) { + $result .= ''; + } + + $result .= + ''; + + return $result; + } + + private static function get_url($url) + { + // external URL + if (strpos($url, '//') !== false) { + return $url; + } + + $version = Config::inst()->get('DeferedRequirements', 'version'); + $version = $version + ? strpos($url, '?') // inner URL + ? '&'.$version // add param + : '?'.$version // new param + : ''; // no version defined + + $static_domain = Config::inst()->get('DeferedRequirements', 'static_domain'); + $static_domain = $static_domain ? $static_domain : ''; + + return $url.$version; + } +} diff --git a/site/code/WebpackTemplateProvider.php b/site/code/WebpackTemplateProvider.php index e1125a8..24defa3 100644 --- a/site/code/WebpackTemplateProvider.php +++ b/site/code/WebpackTemplateProvider.php @@ -6,18 +6,6 @@ class WebpackTemplateProvider extends Object implements TemplateGlobalProvider { - /** - * @return array - */ - public static function get_template_global_variables() - { - return [ - 'WebpackDevServer' => 'isActive', - 'WebpackCSS' => 'loadCSS', - 'WebpackJS' => 'loadJS', - ]; - } - /** * @var int port number */ @@ -31,7 +19,19 @@ class WebpackTemplateProvider extends Object implements TemplateGlobalProvider /** * @var string assets static files directory */ - private static $distDir = 'site/dist'; + private static $dist = 'site/dist'; + + /** + * @return array + */ + public static function get_template_global_variables() + { + return [ + 'WebpackDevServer' => 'isActive', + 'WebpackCSS' => 'loadCSS', + 'WebpackJS' => 'loadJS', + ]; + } /** * Load CSS file @@ -39,9 +39,7 @@ class WebpackTemplateProvider extends Object implements TemplateGlobalProvider */ public static function loadCSS($path) { - if (!self::isActive()) { - Requirements::css(self::_toPublicPath($path)); - } + Requirements::css(self::_getPath($path)); } /** @@ -50,11 +48,7 @@ class WebpackTemplateProvider extends Object implements TemplateGlobalProvider */ public static function loadJS($path) { - $path = self::isActive() ? - self::_toDevServerPath($path) : - self::_toPublicPath($path); - - Requirements::javascript($path); + Requirements::javascript(self::_getPath($path)); } @@ -66,9 +60,16 @@ class WebpackTemplateProvider extends Object implements TemplateGlobalProvider { $class = __CLASS__; return Director::isDev() && !!@fsockopen( - $class::config()->get('hostname'), - $class::config()->get('port') - ); + $class::config()->get('HOSTNAME'), + $class::config()->get('PORT') + ); + } + + protected static function _getPath($path) + { + return self::isActive() && strpos($path,'//') === false ? + self::_toDevServerPath($path) : + self::_toPublicPath($path); } protected static function _toDevServerPath($path) @@ -77,15 +78,21 @@ class WebpackTemplateProvider extends Object implements TemplateGlobalProvider return sprintf( '%s%s:%s/%s', Director::protocol(), - $class::config()->get('hostname'), - $class::config()->get('port'), - $path + $class::config()->get('HOSTNAME'), + $class::config()->get('PORT'), + basename($path) ); } protected static function _toPublicPath($path) { $class = __CLASS__; - return $class::config()->get('distDir') . '/' . $path; + return strpos($path,'//') === false ? + Controller::join_links( + $class::config()->get('DIST'), + (strpos($path,'.css') ? 'css' : 'js' ), + $path + ) + : $path; } } diff --git a/site/src/js/app.js b/site/src/js/app.js index 372e7ef..950bdca 100644 --- a/site/src/js/app.js +++ b/site/src/js/app.js @@ -18,9 +18,6 @@ import 'bootstrap/js/dist/tab'; // import your custom UI components import './main'; -// bootstrap fix -window.Popper = Popper; - // import images function importAll(r) { return r.keys().map(r); diff --git a/site/templates/Includes/Prestyling.ss b/site/templates/Includes/Prestyling.ss new file mode 100644 index 0000000..883b546 --- /dev/null +++ b/site/templates/Includes/Prestyling.ss @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/site/templates/Page.ss b/site/templates/Page.ss index e2cf0f0..8422260 100644 --- a/site/templates/Page.ss +++ b/site/templates/Page.ss @@ -40,8 +40,19 @@ + + <% include Prestyling %>
+ <%-- Upgrade your Browser notice --%> + + + <%-- No JS enabled notice --%> + + + <%-- Loading Spinner --%> +