diff --git a/app/_config/config.yml b/app/_config/config.yml index 785c22a..2ceb95b 100644 --- a/app/_config/config.yml +++ b/app/_config/config.yml @@ -1,7 +1,6 @@ --- Name: webapp --- - SilverStripe\Core\Manifest\ModuleManifest: project: app @@ -16,8 +15,10 @@ Page: # - 'colymba/gridfield-bulk-editing-tools:client/dist/styles/main.css' SilverStripe\Admin\LeftAndMain: + extra_requirements_js: + - 'app/client/dist/css/app_cms.js' extra_requirements_css: - - 'app/client/dist/css/app_cms.css' + - 'app/client/dist/css/app_cms.css' SilverStripe\Forms\HTMLEditor\TinyMCEConfig: editor_css: diff --git a/app/_config/elements.yml b/app/_config/elements.yml index 6f3ce51..7a8123a 100644 --- a/app/_config/elements.yml +++ b/app/_config/elements.yml @@ -5,11 +5,14 @@ After: - elemental-list - elementalvirtual --- - Page: extensions: - DNADesign\Elemental\Extensions\ElementalPageExtension +DNADesign\Elemental\Models\ElementalArea: + extensions: + - Site\Extensions\ElementalArea + DNADesign\Elemental\Models\BaseElement: default_global_elements: true extensions: @@ -17,34 +20,34 @@ DNADesign\Elemental\Models\BaseElement: SilverStripe\CMS\Model\SiteTree: allowed_elements: - - DNADesign\ElementalList\Model\ElementList - - DNADesign\Elemental\Models\ElementContent - - DNADesign\ElementalUserForms\Model\ElementForm - - Dynamic\Elements\Image\Elements\ElementImage - - Dynamic\Elements\Blog\Elements\ElementBlogPosts - - Dynamic\Elements\Oembed\Elements\ElementOembed - - Dynamic\Elements\Elements\ElementTestimonials - #- Site\Elements\TeamMembersElement - - Site\Elements\SliderElement - - Site\Elements\BlockElement - - Site\Elements\MapElement - - DNADesign\ElementalVirtual\Model\ElementVirtual + - DNADesign\ElementalList\Model\ElementList + - DNADesign\Elemental\Models\ElementContent + - DNADesign\ElementalUserForms\Model\ElementForm + - Dynamic\Elements\Image\Elements\ElementImage + - Dynamic\Elements\Blog\Elements\ElementBlogPosts + - Dynamic\Elements\Oembed\Elements\ElementOembed + - Dynamic\Elements\Elements\ElementTestimonials + #- Site\Elements\TeamMembersElement + - Site\Elements\SliderElement + - Site\Elements\BlockElement + - Site\Elements\MapElement + - DNADesign\ElementalVirtual\Model\ElementVirtual DNADesign\ElementalList\Model\ElementList: inline_editable: false default_global_elements: false allowed_elements: - - DNADesign\ElementalList\Model\ElementList - - DNADesign\Elemental\Models\ElementContent - - DNADesign\ElementalUserForms\Model\ElementForm - - Dynamic\Elements\Image\Elements\ElementImage - - Dynamic\Elements\Blog\Elements\ElementBlogPosts - - Dynamic\Elements\Oembed\Elements\ElementOembed - - Dynamic\Elements\Elements\ElementTestimonials - #- Site\Elements\TeamMembersElement - - Site\Elements\SliderElement - - Site\Elements\BlockElement - - Site\Elements\MapElement + - DNADesign\ElementalList\Model\ElementList + - DNADesign\Elemental\Models\ElementContent + - DNADesign\ElementalUserForms\Model\ElementForm + - Dynamic\Elements\Image\Elements\ElementImage + - Dynamic\Elements\Blog\Elements\ElementBlogPosts + - Dynamic\Elements\Oembed\Elements\ElementOembed + - Dynamic\Elements\Elements\ElementTestimonials + #- Site\Elements\TeamMembersElement + - Site\Elements\SliderElement + - Site\Elements\BlockElement + - Site\Elements\MapElement styles: whiteframe: 'White Frame' greybg: 'Grey Background' diff --git a/app/client/src/js/_layout.js b/app/client/src/js/_layout.js index 822aa75..4f4d2e4 100644 --- a/app/client/src/js/_layout.js +++ b/app/client/src/js/_layout.js @@ -1,9 +1,9 @@ -"use strict"; +'use strict'; import $ from 'jquery'; import Events from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_events'; -const LayoutUI = (($) => { +const LayoutUI = ($ => { // Constants const W = window; const D = document; @@ -19,6 +19,33 @@ const LayoutUI = (($) => { console.log(`Initializing: ${NAME}`); // your custom UI + // Custom fonts + $Body.append( + '', + ); + + /*google analytics */ + /*(function(i, s, o, g, r, a, m) { + i['GoogleAnalyticsObject'] = r; + (i[r] = + i[r] || + function() { + (i[r].q = i[r].q || []).push(arguments); + }), + (i[r].l = 1 * new Date()); + (a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]); + a.async = 1; + a.src = g; + m.parentNode.insertBefore(a, m); + })( + window, + document, + 'script', + '//www.google-analytics.com/analytics.js', + 'ga', + ); + ga('create', 'UA-********-*', 'auto'); + ga('send', 'pageview');*/ } static dispose() { diff --git a/app/client/src/js/app.js b/app/client/src/js/app.js index 17c81c8..33ad5c4 100644 --- a/app/client/src/js/app.js +++ b/app/client/src/js/app.js @@ -1,5 +1,6 @@ -import $ from 'jquery'; -import './_consts'; +'use strict'; + +import '../scss/app.scss'; // import Bootstrap import 'popper.js'; @@ -8,7 +9,21 @@ import 'bootstrap/js/dist/alert'; import 'bootstrap/js/dist/button'; import 'bootstrap/js/dist/carousel'; import 'bootstrap/js/dist/collapse'; -import 'bootstrap/js/dist/dropdown'; + +import 'hammerjs/hammer'; +import 'jquery-hammerjs/jquery.hammer'; + +// Routie +//import 'pouchdb/dist/pouchdb'; +//import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/routes/index'; + +// conflicts with _components/_ui.hover.js (shows dropdown on hover) +//import 'bootstrap/js/dist/dropdown'; +import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.hover'; + +import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.carousel'; +import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.menu'; + import 'bootstrap/js/dist/modal'; import 'bootstrap/js/dist/tooltip'; import 'bootstrap/js/dist/popover'; @@ -16,27 +31,58 @@ import 'bootstrap/js/dist/scrollspy'; import 'bootstrap/js/dist/tab'; // +import Spinner from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.spinner'; + +// Sticky sidebar +import SidebarUI from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.sidebar'; + +//import Multislider from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.multislider'; + +// Flyout UI +//import Flyout from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.flyout'; + // Offcanvas menu //import 'offcanvas-bootstrap/dist/js/bootstrap.offcanvas'; -import '../scss/app.scss'; - -import '@a2nt/meta-lightbox/src/js/meta-lightbox'; -// youtube video preview image -import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.video.preview'; - -// MainUI -import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_main'; - // Uncomment it to enable meta-lightbox zooming on hover //import 'jquery-zoom/jquery.zoom'; -// Forms UI -import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.form.basics'; -import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.form.validate'; -import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.form.stepped'; +// Toggle bootstrap form fields +//import FormToggleUI from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.form.fields.toggle'; + +// Bootstrap Date & Time fields +//import FormDatetime from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.form.datetime'; + +// Stepped forms functionality +//import FormStepped from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.form.stepped'; + +// Forms validation functionality +//import FormValidate from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.form.validate'; + +// Store forms data into localStorage +//import FormStorage from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.form.storage'; + +// client-side images cropping +//import FormCroppie from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.form.croppie'; + +// Google NoCaptcha fields +//import NoCaptcha from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.nocaptcha'; + +// youtube video preview image +import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.video.preview'; + +// Meta Lightbox +import '@a2nt/meta-lightbox/src/js/index'; + +//import Confirmation from 'bootstrap-confirmation2/dist/bootstrap-confirmation'; +//import Table from 'bootstrap-table/dist/bootstrap-table'; + +// AJAX UI +//import AjaxUI from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.ajax'; + +import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_main'; +import './_layout'; -// Import fonts and images function importAll(r) { return r.keys().map(r); } @@ -48,5 +94,5 @@ const fontAwesome = importAll( require.context('font-awesome', false, /\.(otf|eot|svg|ttf|woff|woff2)$/), ); -// Your custom JS -import './_layout'; +// Google Analytics +import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/drivers/_google.track.external.links'; diff --git a/app/client/src/scss/_layout.scss b/app/client/src/scss/_layout.scss index 852e4c7..dee521d 100644 --- a/app/client/src/scss/_layout.scss +++ b/app/client/src/scss/_layout.scss @@ -1,6 +1,17 @@ /** * Your custom style */ +.field { + margin: 2rem 0; + &.required:after { + display: none; + } +} +.form-control, +.select2-container--default .select2-selection, +.select2-dropdown .select2-search__field { + border-width: 0 0 1px 0; +} .bg-alt { @extend .bg-dark; diff --git a/app/client/src/scss/types/cms.scss b/app/client/src/scss/types/cms.scss deleted file mode 100644 index c1b404f..0000000 --- a/app/client/src/scss/types/cms.scss +++ /dev/null @@ -1,6 +0,0 @@ -#Menu-SilverStripe-CampaignAdmin-CampaignAdmin, -#Menu-Dynamic-Elements-Sponsors-Admin-SponsorsAdmin, -#Menu-Dynamic-Elements-Admin-TestimonialsAdmin, -#Menu-Dynamic-Elements-Promos-Admin-PromosAdmin { - display: none; -} diff --git a/app/src/Extensions/ElementRows.php b/app/src/Extensions/ElementRows.php index 904e0fd..ceeb5e3 100644 --- a/app/src/Extensions/ElementRows.php +++ b/app/src/Extensions/ElementRows.php @@ -8,6 +8,7 @@ namespace Site\Extensions; +use DNADesign\Elemental\Models\BaseElement; use DNADesign\ElementalList\Model\ElementList; use SilverStripe\Core\Config\Config; use SilverStripe\Forms\CheckboxField; @@ -28,6 +29,7 @@ class ElementRows extends DataExtension private static $db = [ 'ContainerType' => 'Varchar(254)', + //'SidebarOnly' => 'Boolean(0)', 'Size' => 'Enum("1,2,3,4,5,6,7,8,9,10,11,12,auto","auto")', ]; @@ -37,9 +39,11 @@ class ElementRows extends DataExtension // move available globaly to main tab $fields->removeByName('AvailableGlobally'); + //$fields->removeByName('SidebarOnly'); $tab = $fields->findOrMakeTab('Root.Main'); $tab->push(CheckboxField::create('AvailableGlobally')); + //$tab->push(CheckboxField::create('SidebarOnly', 'Hidden (Sidebar Only)')); // container type if ($this->isRoot()) { @@ -97,14 +101,31 @@ class ElementRows extends DataExtension $fields->removeByName('Size'); } - $tab = $fields->findOrMakeTab('Root.Settings') - ->push(LiteralField::create( - 'ClassName', - '
' - .'
Class
' - .'
'.$this->owner->getField('ClassName').'
' - .'
' - )); + // move parent elements + if($this->isList()){ + $tab->push(DropdownField::create( + 'MoveElementIDToParent', + 'Move an element from the list to parent', + $this->owner->getField('Elements')->Elements()->map('ID', 'Title') + )->setEmptyString('(select an element to move)')); + + $tab->push(DropdownField::create( + 'MoveElementIDFromParent', + 'Move an element from parent to the list', + $this->owner->Parent()->Elements() + ->exclude('ID', $this->owner->ID) + ->map('ID', 'Title') + )->setEmptyString('(select an element to move)')); + } + + $fields->findOrMakeTab('Root.Settings') + ->push(LiteralField::create( + 'ClassName', + '
' + .'
Class
' + .'
'.$this->owner->getField('ClassName').'
' + .'
' + )); } public function getWidthPercetage() @@ -247,4 +268,35 @@ class ElementRows extends DataExtension return $type; } + + public static function MoveElement($moveID, $targetID) { + $el = BaseElement::get_by_id($moveID); + if(!$el) { + return false; + } + + $el->setField('ParentID', $targetID); + $el->write(); + + return true; + } + + public function onBeforeWrite() + { + parent::onBeforeWrite(); + + $moveID = $this->owner->getField('MoveElementIDFromParent'); + $targetID = $moveID ? $this->owner->Elements()->ID : null; + + if($moveID && $targetID) { + self::MoveElement($moveID, $targetID); + } + + $moveID = $this->owner->getField('MoveElementIDToParent'); + $targetID = $moveID ? $this->owner->Parent()->ID : null; + + if($moveID && $targetID) { + self::MoveElement($moveID, $targetID); + } + } } diff --git a/app/src/Extensions/ElementalArea.php b/app/src/Extensions/ElementalArea.php new file mode 100644 index 0000000..22dde8a --- /dev/null +++ b/app/src/Extensions/ElementalArea.php @@ -0,0 +1,49 @@ +Elements() instanceof UnsavedRelationList) { + return ArrayList::create(); + } + + $controllers = ArrayList::create(); + $items = $this->Elements()->filterByCallback(static function (BaseElement $item) { + return $item->canView(); + }); + + if ($items !== null) { + foreach ($items as $element) { + $controller = $element->getController(); + $controllers->push($controller); + } + } + + return $controllers; + } + + /** + * A cache-aware accessor for the elements + * @return ArrayList|HasManyList|BaseElement[] + */ + public function Elements() + { + return $this->owner->Elements();//->exclude('SidebarOnly', true); + } +} diff --git a/app/src/Extensions/SocialExtension.php b/app/src/Extensions/SocialExtension.php index 1dd7672..937ecdb 100644 --- a/app/src/Extensions/SocialExtension.php +++ b/app/src/Extensions/SocialExtension.php @@ -24,7 +24,7 @@ class SocialExtension extends DataExtension private static $has_one = [ 'Facebook' => Link::class, 'LinkedIn' => Link::class, - 'GooglePlus' => Link::class, + 'Pinterest' => Link::class, 'Instagram' => Link::class, 'Twitter' => Link::class, 'PublicEmail' => Link::class, @@ -38,7 +38,7 @@ class SocialExtension extends DataExtension $linkFields = [ LinkField::create('FacebookID'), LinkField::create('LinkedInID'), - LinkField::create('GooglePlusID'), + LinkField::create('PinterestID'), LinkField::create('InstagramID'), LinkField::create('TwitterID'), ]; diff --git a/app/src/Pages/Page.php b/app/src/Pages/Page.php index d1365cd..2ee6ffe 100644 --- a/app/src/Pages/Page.php +++ b/app/src/Pages/Page.php @@ -10,6 +10,7 @@ use DNADesign\Elemental\Models\ElementContent; class Page extends SiteTree { private static $default_container_class = 'container'; + protected $_cached = []; public static function DefaultContainer() { @@ -22,9 +23,14 @@ class Page extends SiteTree */ public function Summary($wordsToDisplay = 30) { + if (isset($this->_cached['summary'.$wordsToDisplay])) { + return $this->_cached['summary'.$wordsToDisplay]; + } + $summary = $this->getField('Summary'); if ($summary) { - return $summary; + $this->_cached['summary'.$wordsToDisplay] = $summary; + return $this->_cached['summary'.$wordsToDisplay]; } $element = ElementContent::get()->filter([ @@ -33,10 +39,12 @@ class Page extends SiteTree ])->first(); if ($element) { - return $element->dbObject('HTML')->Summary($wordsToDisplay); + $this->_cached['summary'.$wordsToDisplay] = $element->dbObject('HTML')->Summary($wordsToDisplay); + return $this->_cached['summary'.$wordsToDisplay]; } - return false; + $this->_cached['summary'.$wordsToDisplay] = false; + return $this->_cached['summary'.$wordsToDisplay]; } public function CSSClass() diff --git a/app/templates/DNADesign/Elemental/Models/ElementalArea.ss b/app/templates/DNADesign/Elemental/Models/ElementalArea.ss new file mode 100644 index 0000000..6445f8a --- /dev/null +++ b/app/templates/DNADesign/Elemental/Models/ElementalArea.ss @@ -0,0 +1,5 @@ +<% if $ElementFilteredControllers %> + <% loop $ElementFilteredControllers %> + $Me + <% end_loop %> +<% end_if %> diff --git a/app/templates/Dynamic/Elements/Image/Elements/ElementImage.ss b/app/templates/Dynamic/Elements/Image/Elements/ElementImage.ss index d5d4b02..4522446 100644 --- a/app/templates/Dynamic/Elements/Image/Elements/ElementImage.ss +++ b/app/templates/Dynamic/Elements/Image/Elements/ElementImage.ss @@ -1,7 +1,10 @@ <% if $ImageResized %>
<% if $ImageLink %><% end_if %> - $Title.ATT + $Title.ATT <% if $ImageLink %><% end_if %>
<% end_if %> diff --git a/app/templates/Includes/BlogPostInfo.ss b/app/templates/Includes/BlogPostInfo.ss index 4f7f0fb..97eedc8 100644 --- a/app/templates/Includes/BlogPostInfo.ss +++ b/app/templates/Includes/BlogPostInfo.ss @@ -5,7 +5,12 @@ <% if $FeaturedImage %>
- $FeaturedImage.Fill(350,200) + + $Title.ATT +
<% end_if %> diff --git a/app/templates/Includes/Last.ss b/app/templates/Includes/Last.ss index 6a35d0e..590b3b5 100644 --- a/app/templates/Includes/Last.ss +++ b/app/templates/Includes/Last.ss @@ -1,4 +1,4 @@ -
+
$BetterNavigator
@@ -9,7 +9,6 @@ $AutoRequirements($ClassName).RAW --%> - <%-- place extra requirements after this line --%>
$SiteConfig.ExtraCode diff --git a/app/templates/Includes/MetaHead.ss b/app/templates/Includes/MetaHead.ss index 9995f2f..4473dc7 100644 --- a/app/templates/Includes/MetaHead.ss +++ b/app/templates/Includes/MetaHead.ss @@ -32,12 +32,21 @@ $MetaTags + + + - - - + + + + + + + + + diff --git a/app/templates/Includes/SlideItem.ss b/app/templates/Includes/SlideItem.ss index 4c6b015..cf3d8f6 100644 --- a/app/templates/Includes/SlideItem.ss +++ b/app/templates/Includes/SlideItem.ss @@ -7,7 +7,8 @@ <% if $Image || $ImageURL %> <% if $Headline %>$Headline.XML<% end_if %> diff --git a/app/templates/Objects/SocialLinks.ss b/app/templates/Objects/SocialLinks.ss index 392ce64..fd0eae7 100644 --- a/app/templates/Objects/SocialLinks.ss +++ b/app/templates/Objects/SocialLinks.ss @@ -1,20 +1,20 @@
-
diff --git a/package.json b/package.json index 0632488..ff94420 100755 --- a/package.json +++ b/package.json @@ -1,166 +1,168 @@ { - "name": "ss-webpack-boilerplate", - "version": "2.0.0", - "description": "Lets you create SilverStripe faster", - "author": "Tony Air ", - "license": "MIT", - "private": false, - "repository": { - "type": "git", - "url": "git+https://github.com/a2nt/silverstripe-webpack" - }, - "engines": { - "yarn": ">= 1.0.0" - }, - "scripts": { - "start": "cross-env NODE_ENV=development webpack-dev-server --https -d --config webpack.config.dev.js", - "dash": "cross-env NODE_ENV=development webpack-dashboard -- webpack-dev-server --config webpack.config.dev.js", - "prebuild": "rimraf app/client/dist", - "build": "cross-env NODE_ENV=production webpack -p --config webpack.config.prod.js --progress", - "lint:check": "eslint ./app/client/src --config .eslintrc && sass-lint ./app/client/src --config .sasslintrc -v -q", - "lint:fix": "eslint ./app/client/src --config .eslintrc --fix && sass-lint ./app/client/src --config .sasslintrc -v -q --fix", - "lint:js": "eslint ./app/client/src --config .eslintrc", - "lint:sass": "sass-lint ./app/client/src --config .sasslintrc -v -q" - }, - "browserslist": [ - "defaults" - ], - "dependencies": { - "@a2nt/meta-lightbox": "^1.2.2", - "@a2nt/ss-bootstrap-ui-webpack-boilerplate": "^1.5.9", - "yarn": "^1.21.1" - }, - "devDependencies": { - "@a2nt/image-sprite-webpack-plugin": "^0.2.5", - "@google/markerclusterer": "^1.0.3", - "animate.css": "^3.7.0", - "autoprefixer": "^7.2.5", - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.6", - "babel-loader": "^7.1.2", - "babel-plugin-transform-react-jsx": "^6.24.1", - "babel-preset-es2015": "^6.24.1", - "babel-preset-react": "^6.24.1", - "babel-preset-stage-2": "^6.24.1", - "bootbox": "^4.4.0", - "bootstrap": "^4.4.1", - "bootstrap-confirmation2": "^4.1.0", - "bootstrap-datepicker": "^1.9.0", - "bootstrap-offcanvas": "^1.0.0", - "bootstrap-table": "^1.15.3", - "bootstrap-timepicker": "^0.5.2", - "browser-sync": "^2.24.5", - "browser-sync-webpack-plugin": "^2.2.2", - "copy-webpack-plugin": "^4.6.0", - "copyfiles": "^1.2.0", - "core-util-is": "^1.0.2", - "croppie": "^2.6.4", - "cross-env": "^5.2.1", - "css-loader": "^3.4.2", - "eslint": "^4.18.1", - "eslint-plugin-import": "^2.20.0", - "eslint-plugin-jquery": "^1.5.1", - "eslint-plugin-react": "^7.18.0", - "exif-js": "^2.3.0", - "exports-loader": "^0.7.0", - "extract-text-webpack-plugin": "^4.0.0-beta.0", - "favicons-webpack-plugin": "0.0.9", - "file-loader": "^1.1.5", - "font-awesome": "^4.7.0", - "foundation-emails": "^2.2.1", - "gijgo": "^1.9.13", - "html-webpack-plugin": "^4.0.0-beta.11", - "imagemin-gifsicle": "^7.0.0", - "imagemin-jpegtran": "^6.0.0", - "imagemin-optipng": "^7.1.0", - "imagemin-svgo": "^7.0.0", - "imagemin-webpack": "^5.1.1", - "jquery": "^3.4.1", - "jquery-hammerjs": "^2.0.0", - "jquery-hoverintent": "*", - "jquery-zoom": "^1.7.21", - "jquery.appear": "^1.0.1", - "jquery.inputmask": "^3.3.4", - "laravel-mix": "^4.1.2", - "lost": "^8.3.1", - "mapbox-gl": "^1.6.1", - "material-design-color": "^2.3.2", - "node-sass": "^4.13.1", - "object-assign": "^4.1.1", - "offcanvas-bootstrap": "^2.5.2", - "optimize-css-assets-webpack-plugin": "^5.0.3", - "popper.js": "^1.16.0", - "postcss-loader": "^2.1.5", - "pouchdb": "^6.4.3", - "quill": "^1.3.7", - "react": "^16.12.0", - "react-bootstrap4-form-validation": "^1.0.10", - "react-dom": "^16.12.0", - "react-hot-loader": "^3.1.3", - "redux": "^3.7.2", - "redux-devtools-extension": "^2.13.8", - "resolve-url-loader": "^2.3.2", - "rimraf": "^2.7.1", - "routie": "0.0.1", - "sass-lint": "^1.13.1", - "sass-lint-fix": "^1.12.1", - "sass-loader": "^6.0.6", - "script-ext-html-webpack-plugin": "^2.1.4", - "select2": "^4.0.8", - "smooth-scroll": "^14.2.1", - "style-loader": "^0.19.0", - "svg-url-loader": "^2.3.3", - "terser-webpack-plugin": "^2.3.2", - "uglify-js": "git://github.com/mishoo/UglifyJS2.git#harmony-v2.8.22", - "uglifyjs-webpack-plugin": "^2.2.0", - "url-loader": "^0.6.2", - "webpack": "^4.41.5", - "webpack-cli": "^3.3.10", - "webpack-dev-server": "^3.10.1", - "webpack-manifest-plugin": "^1.3.2", - "webpack-merge": "^4.2.2" - }, - "stylelint": { - "rules": { - "block-no-empty": null, - "color-no-invalid-hex": true, - "comment-empty-line-before": [ - "always", - { - "ignore": [ - "stylelint-commands", - "after-comment" - ] - } - ], - "declaration-colon-space-after": "always", - "indentation": [ - 4, - { - "except": [ - "value" - ] - } - ], - "max-empty-lines": 2, - "rule-empty-line-before": [ - "always", - { - "except": [ - "first-nested" - ], - "ignore": [ - "after-comment" - ] - } - ], - "unit-whitelist": [ - "em", - "rem", - "%", - "s", - "px" - ] - } - } + "name": "ss-webpack-boilerplate", + "version": "2.0.1", + "description": "Lets you create SilverStripe faster", + "author": "Tony Air ", + "license": "MIT", + "private": false, + "repository": { + "type": "git", + "url": "git+https://github.com/a2nt/silverstripe-webpack" + }, + "engines": { + "yarn": ">= 1.0.0" + }, + "scripts": { + "start": "cross-env NODE_ENV=development webpack-dev-server --https -d --config webpack.config.dev.js", + "dash": "cross-env NODE_ENV=development webpack-dashboard -- webpack-dev-server --config webpack.config.dev.js", + "prebuild": "rimraf app/client/dist", + "build": "cross-env NODE_ENV=production webpack -p --config webpack.config.prod.js --progress", + "lint:check": "eslint ./app/client/src --config .eslintrc && sass-lint ./app/client/src --config .sasslintrc -v -q", + "lint:fix": "eslint ./app/client/src --config .eslintrc --fix && sass-lint ./app/client/src --config .sasslintrc -v -q --fix", + "lint:js": "eslint ./app/client/src --config .eslintrc", + "lint:sass": "sass-lint ./app/client/src --config .sasslintrc -v -q" + }, + "browserslist": [ + "defaults", + "ie>=11" + ], + "dependencies": { + "@a2nt/meta-lightbox": "^1.2.2", + "@a2nt/ss-bootstrap-ui-webpack-boilerplate": "^1.7.3", + "browserslist": "^4.8.6", + "caniuse-lite": "^1.0.30001025", + "inputmask": "^5.0.3", + "yarn": "^1.22.0" + }, + "devDependencies": { + "@a2nt/image-sprite-webpack-plugin": "^0.2.5", + "@babel/core": "^7.8.4", + "@babel/plugin-proposal-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-react-jsx": "*", + "@babel/preset-env": "^7.8.4", + "babel-eslint": "^8.2.6", + "babel-loader": "^8.0.6", + "@google/markerclusterer": "^1.0.3", + "animate.css": "^3.7.0", + "autoprefixer": "^9.7.4", + "bootbox": "^4.4.0", + "bootstrap": "^4.4.1", + "bootstrap-confirmation2": "^4.1.0", + "bootstrap-datepicker": "^1.9.0", + "bootstrap-offcanvas": "^1.0.0", + "bootstrap-table": "^1.15.3", + "bootstrap-timepicker": "^0.5.2", + "browser-sync": "^2.24.5", + "browser-sync-webpack-plugin": "^2.2.2", + "copy-webpack-plugin": "^4.6.0", + "copyfiles": "^1.2.0", + "core-util-is": "^1.0.2", + "croppie": "^2.6.4", + "cross-env": "^5.2.1", + "css-loader": "^3.4.2", + "eslint": "^4.18.1", + "eslint-plugin-import": "^2.20.1", + "eslint-plugin-jquery": "^1.5.1", + "eslint-plugin-react": "^7.18.3", + "exif-js": "^2.3.0", + "exports-loader": "^0.7.0", + "extract-text-webpack-plugin": "^4.0.0-beta.0", + "favicons-webpack-plugin": "0.0.9", + "file-loader": "^1.1.5", + "font-awesome": "^4.7.0", + "foundation-emails": "^2.2.1", + "gijgo": "^1.9.13", + "html-webpack-plugin": "^4.0.0-beta.11", + "imagemin-gifsicle": "^7.0.0", + "imagemin-jpegtran": "^6.0.0", + "imagemin-optipng": "^7.1.0", + "imagemin-svgo": "^7.0.0", + "imagemin-webpack": "^5.1.1", + "jquery": "^3.4.1", + "jquery-hammerjs": "^2.0.0", + "jquery-hoverintent": "*", + "jquery-zoom": "^1.7.21", + "jquery.appear": "^1.0.1", + "laravel-mix": "^4.1.2", + "lost": "^8.3.1", + "mapbox-gl": "^1.6.1", + "material-design-color": "^2.3.2", + "node-sass": "^4.13.1", + "object-assign": "^4.1.1", + "offcanvas-bootstrap": "^2.5.2", + "optimize-css-assets-webpack-plugin": "^5.0.3", + "popper.js": "^1.16.0", + "postcss-loader": "^2.1.5", + "pouchdb": "^6.4.3", + "quill": "^1.3.7", + "react": "^16.12.0", + "react-bootstrap4-form-validation": "^1.0.10", + "react-dom": "^16.12.0", + "react-hot-loader": "^3.1.3", + "redux": "^3.7.2", + "redux-devtools-extension": "^2.13.8", + "resolve-url-loader": "^2.3.2", + "rimraf": "^2.7.1", + "routie": "0.0.1", + "sass-lint": "^1.13.1", + "sass-lint-fix": "^1.12.1", + "sass-loader": "^6.0.6", + "script-ext-html-webpack-plugin": "^2.1.4", + "select2": "^4.0.8", + "smooth-scroll": "^14.2.1", + "style-loader": "^0.19.0", + "svg-url-loader": "^2.3.3", + "terser-webpack-plugin": "^2.3.2", + "uglify-js": "git://github.com/mishoo/UglifyJS2.git#harmony-v2.8.22", + "uglifyjs-webpack-plugin": "^2.2.0", + "url-loader": "^0.6.2", + "webpack": "^4.41.5", + "webpack-cli": "^3.3.10", + "webpack-dev-server": "^3.10.3", + "webpack-manifest-plugin": "^1.3.2", + "webpack-merge": "^4.2.2" + }, + "stylelint": { + "rules": { + "block-no-empty": null, + "color-no-invalid-hex": true, + "comment-empty-line-before": [ + "always", + { + "ignore": [ + "stylelint-commands", + "after-comment" + ] + } + ], + "declaration-colon-space-after": "always", + "indentation": [ + 4, + { + "except": [ + "value" + ] + } + ], + "max-empty-lines": 2, + "rule-empty-line-before": [ + "always", + { + "except": [ + "first-nested" + ], + "ignore": [ + "after-comment" + ] + } + ], + "unit-whitelist": [ + "em", + "rem", + "%", + "s", + "px" + ] + } + } } diff --git a/public/htaccess-dist b/public/htaccess-dist index f9e49c2..9ae2161 100644 --- a/public/htaccess-dist +++ b/public/htaccess-dist @@ -39,6 +39,70 @@ ServerSignature Off php_flag expose_php Off +# Enable Compression + + AddOutputFilterByType DEFLATE application/javascript + AddOutputFilterByType DEFLATE application/rss+xml + AddOutputFilterByType DEFLATE application/vnd.ms-fontobject + AddOutputFilterByType DEFLATE application/x-font + AddOutputFilterByType DEFLATE application/x-font-opentype + AddOutputFilterByType DEFLATE application/x-font-otf + AddOutputFilterByType DEFLATE application/x-font-truetype + AddOutputFilterByType DEFLATE application/x-font-ttf + AddOutputFilterByType DEFLATE application/x-javascript + AddOutputFilterByType DEFLATE application/xhtml+xml + AddOutputFilterByType DEFLATE application/xml + AddOutputFilterByType DEFLATE font/opentype + AddOutputFilterByType DEFLATE font/otf + AddOutputFilterByType DEFLATE font/ttf + AddOutputFilterByType DEFLATE image/svg+xml + AddOutputFilterByType DEFLATE image/x-icon + AddOutputFilterByType DEFLATE text/css + AddOutputFilterByType DEFLATE text/html + AddOutputFilterByType DEFLATE text/javascript + AddOutputFilterByType DEFLATE text/plain + + + mod_gzip_on Yes + mod_gzip_dechunk Yes + mod_gzip_item_include file .(html?|txt|css|js|php|pl)$ + mod_gzip_item_include handler ^cgi-script$ + mod_gzip_item_include mime ^text/.* + mod_gzip_item_include mime ^application/x-javascript.* + mod_gzip_item_exclude mime ^image/.* + mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.* + + +# Leverage Browser Caching + + ExpiresActive On + ExpiresByType image/jpg "access 1 year" + ExpiresByType image/jpeg "access 1 year" + ExpiresByType image/gif "access 1 year" + ExpiresByType image/png "access 1 year" + ExpiresByType text/css "access 1 month" + ExpiresByType text/html "access 1 month" + ExpiresByType application/pdf "access 1 month" + ExpiresByType text/x-javascript "access 1 month" + ExpiresByType application/x-shockwave-flash "access 1 month" + ExpiresByType image/x-icon "access 1 year" + ExpiresDefault "access 1 month" + + + + Header set Cache-Control "max-age=2678400, public" + + + Header set Cache-Control "max-age=7200, private, must-revalidate" + + + Header set Cache-Control "max-age=86400, public" + + + Header set Cache-Control "max-age=2678400, private" + + + ### SILVERSTRIPE START ### # Deny access to templates (but allow from localhost)