IMPROVEMENT: input.mask, babel, terser

This commit is contained in:
Tony Air 2020-02-08 02:51:42 +07:00
parent f1cdf0fb50
commit af1db85bca
20 changed files with 527 additions and 246 deletions

View File

@ -1,7 +1,6 @@
--- ---
Name: webapp Name: webapp
--- ---
SilverStripe\Core\Manifest\ModuleManifest: SilverStripe\Core\Manifest\ModuleManifest:
project: app project: app
@ -16,8 +15,10 @@ Page:
# - 'colymba/gridfield-bulk-editing-tools:client/dist/styles/main.css' # - 'colymba/gridfield-bulk-editing-tools:client/dist/styles/main.css'
SilverStripe\Admin\LeftAndMain: SilverStripe\Admin\LeftAndMain:
extra_requirements_js:
- 'app/client/dist/css/app_cms.js'
extra_requirements_css: extra_requirements_css:
- 'app/client/dist/css/app_cms.css' - 'app/client/dist/css/app_cms.css'
SilverStripe\Forms\HTMLEditor\TinyMCEConfig: SilverStripe\Forms\HTMLEditor\TinyMCEConfig:
editor_css: editor_css:

View File

@ -5,11 +5,14 @@ After:
- elemental-list - elemental-list
- elementalvirtual - elementalvirtual
--- ---
Page: Page:
extensions: extensions:
- DNADesign\Elemental\Extensions\ElementalPageExtension - DNADesign\Elemental\Extensions\ElementalPageExtension
DNADesign\Elemental\Models\ElementalArea:
extensions:
- Site\Extensions\ElementalArea
DNADesign\Elemental\Models\BaseElement: DNADesign\Elemental\Models\BaseElement:
default_global_elements: true default_global_elements: true
extensions: extensions:
@ -17,34 +20,34 @@ DNADesign\Elemental\Models\BaseElement:
SilverStripe\CMS\Model\SiteTree: SilverStripe\CMS\Model\SiteTree:
allowed_elements: allowed_elements:
- DNADesign\ElementalList\Model\ElementList - DNADesign\ElementalList\Model\ElementList
- DNADesign\Elemental\Models\ElementContent - DNADesign\Elemental\Models\ElementContent
- DNADesign\ElementalUserForms\Model\ElementForm - DNADesign\ElementalUserForms\Model\ElementForm
- Dynamic\Elements\Image\Elements\ElementImage - Dynamic\Elements\Image\Elements\ElementImage
- Dynamic\Elements\Blog\Elements\ElementBlogPosts - Dynamic\Elements\Blog\Elements\ElementBlogPosts
- Dynamic\Elements\Oembed\Elements\ElementOembed - Dynamic\Elements\Oembed\Elements\ElementOembed
- Dynamic\Elements\Elements\ElementTestimonials - Dynamic\Elements\Elements\ElementTestimonials
#- Site\Elements\TeamMembersElement #- Site\Elements\TeamMembersElement
- Site\Elements\SliderElement - Site\Elements\SliderElement
- Site\Elements\BlockElement - Site\Elements\BlockElement
- Site\Elements\MapElement - Site\Elements\MapElement
- DNADesign\ElementalVirtual\Model\ElementVirtual - DNADesign\ElementalVirtual\Model\ElementVirtual
DNADesign\ElementalList\Model\ElementList: DNADesign\ElementalList\Model\ElementList:
inline_editable: false inline_editable: false
default_global_elements: false default_global_elements: false
allowed_elements: allowed_elements:
- DNADesign\ElementalList\Model\ElementList - DNADesign\ElementalList\Model\ElementList
- DNADesign\Elemental\Models\ElementContent - DNADesign\Elemental\Models\ElementContent
- DNADesign\ElementalUserForms\Model\ElementForm - DNADesign\ElementalUserForms\Model\ElementForm
- Dynamic\Elements\Image\Elements\ElementImage - Dynamic\Elements\Image\Elements\ElementImage
- Dynamic\Elements\Blog\Elements\ElementBlogPosts - Dynamic\Elements\Blog\Elements\ElementBlogPosts
- Dynamic\Elements\Oembed\Elements\ElementOembed - Dynamic\Elements\Oembed\Elements\ElementOembed
- Dynamic\Elements\Elements\ElementTestimonials - Dynamic\Elements\Elements\ElementTestimonials
#- Site\Elements\TeamMembersElement #- Site\Elements\TeamMembersElement
- Site\Elements\SliderElement - Site\Elements\SliderElement
- Site\Elements\BlockElement - Site\Elements\BlockElement
- Site\Elements\MapElement - Site\Elements\MapElement
styles: styles:
whiteframe: 'White Frame' whiteframe: 'White Frame'
greybg: 'Grey Background' greybg: 'Grey Background'

View File

@ -1,9 +1,9 @@
"use strict"; 'use strict';
import $ from 'jquery'; import $ from 'jquery';
import Events from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_events'; import Events from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_events';
const LayoutUI = (($) => { const LayoutUI = ($ => {
// Constants // Constants
const W = window; const W = window;
const D = document; const D = document;
@ -19,6 +19,33 @@ const LayoutUI = (($) => {
console.log(`Initializing: ${NAME}`); console.log(`Initializing: ${NAME}`);
// your custom UI // your custom UI
// Custom fonts
$Body.append(
'<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,400i,700,700i&display=swap" rel="stylesheet">',
);
/*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() { static dispose() {

View File

@ -1,5 +1,6 @@
import $ from 'jquery'; 'use strict';
import './_consts';
import '../scss/app.scss';
// import Bootstrap // import Bootstrap
import 'popper.js'; import 'popper.js';
@ -8,7 +9,21 @@ import 'bootstrap/js/dist/alert';
import 'bootstrap/js/dist/button'; import 'bootstrap/js/dist/button';
import 'bootstrap/js/dist/carousel'; import 'bootstrap/js/dist/carousel';
import 'bootstrap/js/dist/collapse'; 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/modal';
import 'bootstrap/js/dist/tooltip'; import 'bootstrap/js/dist/tooltip';
import 'bootstrap/js/dist/popover'; import 'bootstrap/js/dist/popover';
@ -16,27 +31,58 @@ import 'bootstrap/js/dist/scrollspy';
import 'bootstrap/js/dist/tab'; 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 // Offcanvas menu
//import 'offcanvas-bootstrap/dist/js/bootstrap.offcanvas'; //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 // Uncomment it to enable meta-lightbox zooming on hover
//import 'jquery-zoom/jquery.zoom'; //import 'jquery-zoom/jquery.zoom';
// Forms UI // Toggle bootstrap form fields
import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.form.basics'; //import FormToggleUI from '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/_ui.form.fields.toggle';
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'; // 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) { function importAll(r) {
return r.keys().map(r); return r.keys().map(r);
} }
@ -48,5 +94,5 @@ const fontAwesome = importAll(
require.context('font-awesome', false, /\.(otf|eot|svg|ttf|woff|woff2)$/), require.context('font-awesome', false, /\.(otf|eot|svg|ttf|woff|woff2)$/),
); );
// Your custom JS // Google Analytics
import './_layout'; import '@a2nt/ss-bootstrap-ui-webpack-boilerplate/src/js/_components/drivers/_google.track.external.links';

View File

@ -1,6 +1,17 @@
/** /**
* Your custom style * 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 { .bg-alt {
@extend .bg-dark; @extend .bg-dark;

View File

@ -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;
}

View File

@ -8,6 +8,7 @@
namespace Site\Extensions; namespace Site\Extensions;
use DNADesign\Elemental\Models\BaseElement;
use DNADesign\ElementalList\Model\ElementList; use DNADesign\ElementalList\Model\ElementList;
use SilverStripe\Core\Config\Config; use SilverStripe\Core\Config\Config;
use SilverStripe\Forms\CheckboxField; use SilverStripe\Forms\CheckboxField;
@ -28,6 +29,7 @@ class ElementRows extends DataExtension
private static $db = [ private static $db = [
'ContainerType' => 'Varchar(254)', 'ContainerType' => 'Varchar(254)',
//'SidebarOnly' => 'Boolean(0)',
'Size' => 'Enum("1,2,3,4,5,6,7,8,9,10,11,12,auto","auto")', '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 // move available globaly to main tab
$fields->removeByName('AvailableGlobally'); $fields->removeByName('AvailableGlobally');
//$fields->removeByName('SidebarOnly');
$tab = $fields->findOrMakeTab('Root.Main'); $tab = $fields->findOrMakeTab('Root.Main');
$tab->push(CheckboxField::create('AvailableGlobally')); $tab->push(CheckboxField::create('AvailableGlobally'));
//$tab->push(CheckboxField::create('SidebarOnly', 'Hidden (Sidebar Only)'));
// container type // container type
if ($this->isRoot()) { if ($this->isRoot()) {
@ -97,14 +101,31 @@ class ElementRows extends DataExtension
$fields->removeByName('Size'); $fields->removeByName('Size');
} }
$tab = $fields->findOrMakeTab('Root.Settings') // move parent elements
->push(LiteralField::create( if($this->isList()){
'ClassName', $tab->push(DropdownField::create(
'<div class="form-group field text">' 'MoveElementIDToParent',
.'<div class="form__field-label">Class</div>' 'Move an element from the list to parent',
.'<div class="form__field-holder">'.$this->owner->getField('ClassName').'</div>' $this->owner->getField('Elements')->Elements()->map('ID', 'Title')
.'</div>' )->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',
'<div class="form-group field text">'
.'<div class="form__field-label">Class</div>'
.'<div class="form__field-holder">'.$this->owner->getField('ClassName').'</div>'
.'</div>'
));
} }
public function getWidthPercetage() public function getWidthPercetage()
@ -247,4 +268,35 @@ class ElementRows extends DataExtension
return $type; 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);
}
}
} }

View File

@ -0,0 +1,49 @@
<?php
/**
* Created by PhpStorm.
* User: tony
* Date: 6/23/18
* Time: 1:23 PM
*/
namespace Site\Extensions;
use DNADesign\Elemental\Models\BaseElement;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataExtension;
use SilverStripe\ORM\HasManyList;
use SilverStripe\ORM\UnsavedRelationList;
class ElementalArea extends DataExtension
{
public function ElementFilteredControllers()
{
// Don't try and process unsaved lists
if ($this->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);
}
}

View File

@ -24,7 +24,7 @@ class SocialExtension extends DataExtension
private static $has_one = [ private static $has_one = [
'Facebook' => Link::class, 'Facebook' => Link::class,
'LinkedIn' => Link::class, 'LinkedIn' => Link::class,
'GooglePlus' => Link::class, 'Pinterest' => Link::class,
'Instagram' => Link::class, 'Instagram' => Link::class,
'Twitter' => Link::class, 'Twitter' => Link::class,
'PublicEmail' => Link::class, 'PublicEmail' => Link::class,
@ -38,7 +38,7 @@ class SocialExtension extends DataExtension
$linkFields = [ $linkFields = [
LinkField::create('FacebookID'), LinkField::create('FacebookID'),
LinkField::create('LinkedInID'), LinkField::create('LinkedInID'),
LinkField::create('GooglePlusID'), LinkField::create('PinterestID'),
LinkField::create('InstagramID'), LinkField::create('InstagramID'),
LinkField::create('TwitterID'), LinkField::create('TwitterID'),
]; ];

View File

@ -10,6 +10,7 @@ use DNADesign\Elemental\Models\ElementContent;
class Page extends SiteTree class Page extends SiteTree
{ {
private static $default_container_class = 'container'; private static $default_container_class = 'container';
protected $_cached = [];
public static function DefaultContainer() public static function DefaultContainer()
{ {
@ -22,9 +23,14 @@ class Page extends SiteTree
*/ */
public function Summary($wordsToDisplay = 30) public function Summary($wordsToDisplay = 30)
{ {
if (isset($this->_cached['summary'.$wordsToDisplay])) {
return $this->_cached['summary'.$wordsToDisplay];
}
$summary = $this->getField('Summary'); $summary = $this->getField('Summary');
if ($summary) { if ($summary) {
return $summary; $this->_cached['summary'.$wordsToDisplay] = $summary;
return $this->_cached['summary'.$wordsToDisplay];
} }
$element = ElementContent::get()->filter([ $element = ElementContent::get()->filter([
@ -33,10 +39,12 @@ class Page extends SiteTree
])->first(); ])->first();
if ($element) { 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() public function CSSClass()

View File

@ -0,0 +1,5 @@
<% if $ElementFilteredControllers %>
<% loop $ElementFilteredControllers %>
$Me
<% end_loop %>
<% end_if %>

View File

@ -1,7 +1,10 @@
<% if $ImageResized %> <% if $ImageResized %>
<div class="image-element__image<% if $Resize %><% if $Height %> height{$Height}<% end_if %><% if $Width %> width{$Width}<% end_if %><% end_if %>"> <div class="image-element__image<% if $Resize %><% if $Height %> height{$Height}<% end_if %><% if $Width %> width{$Width}<% end_if %><% end_if %>">
<% if $ImageLink %><a href="$ImageLink.URL"><% end_if %> <% if $ImageLink %><a href="$ImageLink.URL"><% end_if %>
<img src="$ImageResized.URL" class="img-responsive" alt="$Title.ATT" /> <img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
data-lazy-src="$ImageResized.URL" class="img-responsive" alt="$Title.ATT"
/>
<% if $ImageLink %></a><% end_if %> <% if $ImageLink %></a><% end_if %>
</div> </div>
<% end_if %> <% end_if %>

View File

@ -5,7 +5,12 @@
</div> </div>
<% if $FeaturedImage %> <% if $FeaturedImage %>
<div class="img card-img-top"> <div class="img card-img-top">
<a href="$Link">$FeaturedImage.Fill(350,200)</a> <a href="$Link">
<img
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
data-lazy-src="$FeaturedImage.Fill(350,200).URL" alt="$Title.ATT"
/>
</a>
</div> </div>
<% end_if %> <% end_if %>

View File

@ -1,4 +1,4 @@
<div class="hidden-print"> <div class="hidden-print hidden-md">
$BetterNavigator $BetterNavigator
</div> </div>
@ -9,7 +9,6 @@ $AutoRequirements($ClassName).RAW
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.js"></script> <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.js"></script>
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.css" rel="stylesheet" />--%> <link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.css" rel="stylesheet" />--%>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700,700i|Roboto:400,400i,700,700i&display=swap&subset=latin-ext" rel="stylesheet" />
<%-- place extra requirements after this line --%> <%-- place extra requirements after this line --%>
<div class="extra-code extra-code-site"> <div class="extra-code extra-code-site">
$SiteConfig.ExtraCode $SiteConfig.ExtraCode

View File

@ -32,12 +32,21 @@ $MetaTags
<link rel="author" type="text/plain" href="{$AbsoluteBaseURL}humans.txt" /> <link rel="author" type="text/plain" href="{$AbsoluteBaseURL}humans.txt" />
<link rel="sitemap" type="application/xml" title="Sitemap" href="{$AbsoluteBaseURL}sitemap.xml" /> <link rel="sitemap" type="application/xml" title="Sitemap" href="{$AbsoluteBaseURL}sitemap.xml" />
<link rel="dns-prefetch" href="https://fonts.gstatic.com" />
<link rel="dns-prefetch" href="https://use.fontawesome.com" />
<link rel="dns-prefetch" href="https://ajax.googleapis.com" />
<link rel="preconnect" href="https://use.fontawesome.com/" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="preconnect" href="https://maps.google.com" /> <link rel="preconnect" href="https://use.fontawesome.com" crossorigin />
<link rel="preconnect" href="https://ajax.googleapis.com" /> <link rel="preconnect" href="https://ajax.googleapis.com" crossorigin />
<link rel="dns-prefetch" href="https://csi.gstatic.com" />
<link rel="dns-prefetch" href="https://maps.google.com" />
<link rel="dns-prefetch" href="https://maps.googleapis.com" />
<link rel="preconnect" href="https://csi.gstatic.com" /> <link rel="preconnect" href="https://csi.gstatic.com" />
<link rel="preconnect" href="https://maps.google.com" />
<link rel="preconnect" href="https://maps.googleapis.com" /> <link rel="preconnect" href="https://maps.googleapis.com" />
<link rel="preconnect" href="https://www.youtube.com" /> <link rel="preconnect" href="https://www.youtube.com" />

View File

@ -7,7 +7,8 @@
<% if $Image || $ImageURL %> <% if $Image || $ImageURL %>
<span class="img"> <span class="img">
<img class="d-block w-100" <img class="d-block w-100"
src="<% if $ImageURL %>$ImageURL<% else %>$Image.Fill(1400,650).URL<% end_if %>" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
data-lazy-src="<% if $ImageURL %>$ImageURL<% else %>$Image.Fill(1400,650).URL<% end_if %>"
alt="<% if $Headline %>$Headline.XML<% end_if %>" alt="<% if $Headline %>$Headline.XML<% end_if %>"
/> />
</span> </span>

View File

@ -1,20 +1,20 @@
<div class="sc-links"> <div class="sc-links">
<% if $Facebook %> <% if $Facebook %>
<a href="$Facebook.LinkURL" title="Facebook" target="_blank"> <a href="$Facebook.LinkURL" title="Facebook" target="_blank">
<i class="fab fa-facebook"></i> <i class="fab fa-facebook-f"></i>
<i class="sr-only">Facebook</i> <i class="sr-only">Facebook</i>
</a> </a>
<% end_if %> <% end_if %>
<% if $LinkedIn %> <% if $LinkedIn %>
<a href="$LinkedIn.LinkURL" title="LinkedIn" target="_blank"> <a href="$LinkedIn.LinkURL" title="LinkedIn" target="_blank">
<i class="fab fa-linkedin"></i> <i class="fab fa-linkedin-in"></i>
<i class="sr-only">LinkedIn</i> <i class="sr-only">LinkedIn</i>
</a> </a>
<% end_if %> <% end_if %>
<% if $GooglePlus %> <% if $Pinterest %>
<a href="$GooglePlus.LinkURL" title="Google+" target="_blank"> <a href="$Pinterest.LinkURL" title="Pinterest" target="_blank">
<i class="fab fa-google-plus-g"></i> <i class="fab fa-pinterest-p"></i>
<i class="sr-only">Google+</i> <i class="sr-only">Pinterest</i>
</a> </a>
<% end_if %> <% end_if %>
<% if $Instagram %> <% if $Instagram %>

View File

@ -43,8 +43,10 @@
$Layout $Layout
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<div class="page-content-sidebar page-content"> <div class="page-content-sidebar page-content jsSidebarUI">
$SideBarView <div class="jsSidebarUI__inner">
$SideBarView
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,166 +1,168 @@
{ {
"name": "ss-webpack-boilerplate", "name": "ss-webpack-boilerplate",
"version": "2.0.0", "version": "2.0.1",
"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",
"private": false, "private": false,
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/a2nt/silverstripe-webpack" "url": "git+https://github.com/a2nt/silverstripe-webpack"
}, },
"engines": { "engines": {
"yarn": ">= 1.0.0" "yarn": ">= 1.0.0"
}, },
"scripts": { "scripts": {
"start": "cross-env NODE_ENV=development webpack-dev-server --https -d --config webpack.config.dev.js", "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", "dash": "cross-env NODE_ENV=development webpack-dashboard -- webpack-dev-server --config webpack.config.dev.js",
"prebuild": "rimraf app/client/dist", "prebuild": "rimraf app/client/dist",
"build": "cross-env NODE_ENV=production webpack -p --config webpack.config.prod.js --progress", "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: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: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:js": "eslint ./app/client/src --config .eslintrc",
"lint:sass": "sass-lint ./app/client/src --config .sasslintrc -v -q" "lint:sass": "sass-lint ./app/client/src --config .sasslintrc -v -q"
}, },
"browserslist": [ "browserslist": [
"defaults" "defaults",
], "ie>=11"
"dependencies": { ],
"@a2nt/meta-lightbox": "^1.2.2", "dependencies": {
"@a2nt/ss-bootstrap-ui-webpack-boilerplate": "^1.5.9", "@a2nt/meta-lightbox": "^1.2.2",
"yarn": "^1.21.1" "@a2nt/ss-bootstrap-ui-webpack-boilerplate": "^1.7.3",
}, "browserslist": "^4.8.6",
"devDependencies": { "caniuse-lite": "^1.0.30001025",
"@a2nt/image-sprite-webpack-plugin": "^0.2.5", "inputmask": "^5.0.3",
"@google/markerclusterer": "^1.0.3", "yarn": "^1.22.0"
"animate.css": "^3.7.0", },
"autoprefixer": "^7.2.5", "devDependencies": {
"babel-core": "^6.26.3", "@a2nt/image-sprite-webpack-plugin": "^0.2.5",
"babel-eslint": "^8.2.6", "@babel/core": "^7.8.4",
"babel-loader": "^7.1.2", "@babel/plugin-proposal-object-rest-spread": "^7.8.3",
"babel-plugin-transform-react-jsx": "^6.24.1", "@babel/plugin-transform-react-jsx": "*",
"babel-preset-es2015": "^6.24.1", "@babel/preset-env": "^7.8.4",
"babel-preset-react": "^6.24.1", "babel-eslint": "^8.2.6",
"babel-preset-stage-2": "^6.24.1", "babel-loader": "^8.0.6",
"bootbox": "^4.4.0", "@google/markerclusterer": "^1.0.3",
"bootstrap": "^4.4.1", "animate.css": "^3.7.0",
"bootstrap-confirmation2": "^4.1.0", "autoprefixer": "^9.7.4",
"bootstrap-datepicker": "^1.9.0", "bootbox": "^4.4.0",
"bootstrap-offcanvas": "^1.0.0", "bootstrap": "^4.4.1",
"bootstrap-table": "^1.15.3", "bootstrap-confirmation2": "^4.1.0",
"bootstrap-timepicker": "^0.5.2", "bootstrap-datepicker": "^1.9.0",
"browser-sync": "^2.24.5", "bootstrap-offcanvas": "^1.0.0",
"browser-sync-webpack-plugin": "^2.2.2", "bootstrap-table": "^1.15.3",
"copy-webpack-plugin": "^4.6.0", "bootstrap-timepicker": "^0.5.2",
"copyfiles": "^1.2.0", "browser-sync": "^2.24.5",
"core-util-is": "^1.0.2", "browser-sync-webpack-plugin": "^2.2.2",
"croppie": "^2.6.4", "copy-webpack-plugin": "^4.6.0",
"cross-env": "^5.2.1", "copyfiles": "^1.2.0",
"css-loader": "^3.4.2", "core-util-is": "^1.0.2",
"eslint": "^4.18.1", "croppie": "^2.6.4",
"eslint-plugin-import": "^2.20.0", "cross-env": "^5.2.1",
"eslint-plugin-jquery": "^1.5.1", "css-loader": "^3.4.2",
"eslint-plugin-react": "^7.18.0", "eslint": "^4.18.1",
"exif-js": "^2.3.0", "eslint-plugin-import": "^2.20.1",
"exports-loader": "^0.7.0", "eslint-plugin-jquery": "^1.5.1",
"extract-text-webpack-plugin": "^4.0.0-beta.0", "eslint-plugin-react": "^7.18.3",
"favicons-webpack-plugin": "0.0.9", "exif-js": "^2.3.0",
"file-loader": "^1.1.5", "exports-loader": "^0.7.0",
"font-awesome": "^4.7.0", "extract-text-webpack-plugin": "^4.0.0-beta.0",
"foundation-emails": "^2.2.1", "favicons-webpack-plugin": "0.0.9",
"gijgo": "^1.9.13", "file-loader": "^1.1.5",
"html-webpack-plugin": "^4.0.0-beta.11", "font-awesome": "^4.7.0",
"imagemin-gifsicle": "^7.0.0", "foundation-emails": "^2.2.1",
"imagemin-jpegtran": "^6.0.0", "gijgo": "^1.9.13",
"imagemin-optipng": "^7.1.0", "html-webpack-plugin": "^4.0.0-beta.11",
"imagemin-svgo": "^7.0.0", "imagemin-gifsicle": "^7.0.0",
"imagemin-webpack": "^5.1.1", "imagemin-jpegtran": "^6.0.0",
"jquery": "^3.4.1", "imagemin-optipng": "^7.1.0",
"jquery-hammerjs": "^2.0.0", "imagemin-svgo": "^7.0.0",
"jquery-hoverintent": "*", "imagemin-webpack": "^5.1.1",
"jquery-zoom": "^1.7.21", "jquery": "^3.4.1",
"jquery.appear": "^1.0.1", "jquery-hammerjs": "^2.0.0",
"jquery.inputmask": "^3.3.4", "jquery-hoverintent": "*",
"laravel-mix": "^4.1.2", "jquery-zoom": "^1.7.21",
"lost": "^8.3.1", "jquery.appear": "^1.0.1",
"mapbox-gl": "^1.6.1", "laravel-mix": "^4.1.2",
"material-design-color": "^2.3.2", "lost": "^8.3.1",
"node-sass": "^4.13.1", "mapbox-gl": "^1.6.1",
"object-assign": "^4.1.1", "material-design-color": "^2.3.2",
"offcanvas-bootstrap": "^2.5.2", "node-sass": "^4.13.1",
"optimize-css-assets-webpack-plugin": "^5.0.3", "object-assign": "^4.1.1",
"popper.js": "^1.16.0", "offcanvas-bootstrap": "^2.5.2",
"postcss-loader": "^2.1.5", "optimize-css-assets-webpack-plugin": "^5.0.3",
"pouchdb": "^6.4.3", "popper.js": "^1.16.0",
"quill": "^1.3.7", "postcss-loader": "^2.1.5",
"react": "^16.12.0", "pouchdb": "^6.4.3",
"react-bootstrap4-form-validation": "^1.0.10", "quill": "^1.3.7",
"react-dom": "^16.12.0", "react": "^16.12.0",
"react-hot-loader": "^3.1.3", "react-bootstrap4-form-validation": "^1.0.10",
"redux": "^3.7.2", "react-dom": "^16.12.0",
"redux-devtools-extension": "^2.13.8", "react-hot-loader": "^3.1.3",
"resolve-url-loader": "^2.3.2", "redux": "^3.7.2",
"rimraf": "^2.7.1", "redux-devtools-extension": "^2.13.8",
"routie": "0.0.1", "resolve-url-loader": "^2.3.2",
"sass-lint": "^1.13.1", "rimraf": "^2.7.1",
"sass-lint-fix": "^1.12.1", "routie": "0.0.1",
"sass-loader": "^6.0.6", "sass-lint": "^1.13.1",
"script-ext-html-webpack-plugin": "^2.1.4", "sass-lint-fix": "^1.12.1",
"select2": "^4.0.8", "sass-loader": "^6.0.6",
"smooth-scroll": "^14.2.1", "script-ext-html-webpack-plugin": "^2.1.4",
"style-loader": "^0.19.0", "select2": "^4.0.8",
"svg-url-loader": "^2.3.3", "smooth-scroll": "^14.2.1",
"terser-webpack-plugin": "^2.3.2", "style-loader": "^0.19.0",
"uglify-js": "git://github.com/mishoo/UglifyJS2.git#harmony-v2.8.22", "svg-url-loader": "^2.3.3",
"uglifyjs-webpack-plugin": "^2.2.0", "terser-webpack-plugin": "^2.3.2",
"url-loader": "^0.6.2", "uglify-js": "git://github.com/mishoo/UglifyJS2.git#harmony-v2.8.22",
"webpack": "^4.41.5", "uglifyjs-webpack-plugin": "^2.2.0",
"webpack-cli": "^3.3.10", "url-loader": "^0.6.2",
"webpack-dev-server": "^3.10.1", "webpack": "^4.41.5",
"webpack-manifest-plugin": "^1.3.2", "webpack-cli": "^3.3.10",
"webpack-merge": "^4.2.2" "webpack-dev-server": "^3.10.3",
}, "webpack-manifest-plugin": "^1.3.2",
"stylelint": { "webpack-merge": "^4.2.2"
"rules": { },
"block-no-empty": null, "stylelint": {
"color-no-invalid-hex": true, "rules": {
"comment-empty-line-before": [ "block-no-empty": null,
"always", "color-no-invalid-hex": true,
{ "comment-empty-line-before": [
"ignore": [ "always",
"stylelint-commands", {
"after-comment" "ignore": [
] "stylelint-commands",
} "after-comment"
], ]
"declaration-colon-space-after": "always", }
"indentation": [ ],
4, "declaration-colon-space-after": "always",
{ "indentation": [
"except": [ 4,
"value" {
] "except": [
} "value"
], ]
"max-empty-lines": 2, }
"rule-empty-line-before": [ ],
"always", "max-empty-lines": 2,
{ "rule-empty-line-before": [
"except": [ "always",
"first-nested" {
], "except": [
"ignore": [ "first-nested"
"after-comment" ],
] "ignore": [
} "after-comment"
], ]
"unit-whitelist": [ }
"em", ],
"rem", "unit-whitelist": [
"%", "em",
"s", "rem",
"px" "%",
] "s",
} "px"
} ]
}
}
} }

View File

@ -39,6 +39,70 @@ ServerSignature Off
php_flag expose_php Off php_flag expose_php Off
</IfModule> </IfModule>
# Enable Compression
<IfModule mod_deflate.c>
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
</IfModule>
<IfModule mod_gzip.c>
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.*
</IfModule>
# Leverage Browser Caching
<IfModule mod_expires.c>
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"
</IfModule>
<IfModule mod_headers.c>
<filesmatch "\.(ico|flv|jpg|jpeg|png|gif|css|swf)$">
Header set Cache-Control "max-age=2678400, public"
</filesmatch>
<filesmatch "\.(html|htm)$">
Header set Cache-Control "max-age=7200, private, must-revalidate"
</filesmatch>
<filesmatch "\.(pdf)$">
Header set Cache-Control "max-age=86400, public"
</filesmatch>
<filesmatch "\.(js)$">
Header set Cache-Control "max-age=2678400, private"
</filesmatch>
</IfModule>
### SILVERSTRIPE START ### ### SILVERSTRIPE START ###
# Deny access to templates (but allow from localhost) # Deny access to templates (but allow from localhost)