mirror of
https://github.com/a2nt/silverstripe-webpack.git
synced 2024-10-22 17:05:31 +02:00
Initial theming support
This commit is contained in:
parent
003d282905
commit
8429a6739a
@ -20,5 +20,12 @@ $config->enablePlugins([
|
|||||||
$config->addButtonsToLine(2, 'hr');
|
$config->addButtonsToLine(2, 'hr');
|
||||||
$config->setOption('block_formats', 'Paragraph=p;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6;Address=address;Pre=pre');
|
$config->setOption('block_formats', 'Paragraph=p;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6;Address=address;Pre=pre');
|
||||||
$config->setOption('invalid_elements', 'h1');
|
$config->setOption('invalid_elements', 'h1');
|
||||||
|
$config->setOption(
|
||||||
|
'table_class_list',
|
||||||
|
[
|
||||||
|
['title' => 'Transparent Table', 'value' => 'table-none'],
|
||||||
|
['title' => 'Shaded rows', 'value' => 'table table-striped table-bordered'],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
FulltextSearchable::enable();
|
FulltextSearchable::enable();
|
||||||
|
@ -19,8 +19,8 @@ SilverStripe\View\SSViewer:
|
|||||||
|
|
||||||
SilverStripe\Admin\LeftAndMain:
|
SilverStripe\Admin\LeftAndMain:
|
||||||
extra_requirements_css:
|
extra_requirements_css:
|
||||||
- 'app/client/dist/css/cms.css'
|
- 'app/client/dist/css/app_cms.css'
|
||||||
|
|
||||||
SilverStripe\Forms\HTMLEditor\TinyMCEConfig:
|
SilverStripe\Forms\HTMLEditor\TinyMCEConfig:
|
||||||
editor_css:
|
editor_css:
|
||||||
- 'app/client/dist/css/editor.css'
|
- 'app/client/dist/css/app_editor.css'
|
||||||
|
@ -25,6 +25,7 @@ SilverStripe\CMS\Model\SiteTree:
|
|||||||
- 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
|
||||||
|
|
||||||
DNADesign\ElementalList\Model\ElementList:
|
DNADesign\ElementalList\Model\ElementList:
|
||||||
default_global_elements: false
|
default_global_elements: false
|
||||||
@ -50,4 +51,3 @@ DNADesign\Elemental\Models\ElementContent:
|
|||||||
Dynamic\Elements\Image\Elements\ElementImage:
|
Dynamic\Elements\Image\Elements\ElementImage:
|
||||||
extensions:
|
extensions:
|
||||||
- Site\Extensions\ElementImageWidget
|
- Site\Extensions\ElementImageWidget
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
SilverStripe\SiteConfig\SiteConfig:
|
SilverStripe\SiteConfig\SiteConfig:
|
||||||
extensions:
|
extensions:
|
||||||
- Broarm\OpeningHours\OpeningHours
|
|
||||||
- Site\Extensions\SiteConfigExtension
|
- Site\Extensions\SiteConfigExtension
|
||||||
- Site\Extensions\SocialExtension
|
- Site\Extensions\SocialExtension
|
||||||
|
|
||||||
@ -19,3 +18,18 @@ Dynamic\FlexSlider\Model\SlideImage:
|
|||||||
SilverStripe\Core\Injector\Injector:
|
SilverStripe\Core\Injector\Injector:
|
||||||
SilverStripe\UserForms\Model\UserDefinedForm:
|
SilverStripe\UserForms\Model\UserDefinedForm:
|
||||||
class: Site\Extensions\CMSMain_HiddenClass
|
class: Site\Extensions\CMSMain_HiddenClass
|
||||||
|
SilverStripe\Security\MemberAuthenticator\LostPasswordHandler:
|
||||||
|
class: Site\Extensions\LostPasswordHandlerExtension
|
||||||
|
|
||||||
|
# User Forms
|
||||||
|
SilverStripe\UserForms\Form\UserForm:
|
||||||
|
extensions:
|
||||||
|
- Site\Extensions\PlaceholderFormExtension
|
||||||
|
|
||||||
|
SilverStripe\UserForms\Model\UserDefinedForm:
|
||||||
|
extensions:
|
||||||
|
- Site\Extensions\UserDefinedFormExtension
|
||||||
|
|
||||||
|
DNADesign\ElementalUserForms\Model\ElementForm:
|
||||||
|
extensions:
|
||||||
|
- Site\Extensions\UserDefinedFormExtension
|
||||||
|
79
app/_config/files.yml
Normal file
79
app/_config/files.yml
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
---
|
||||||
|
Name: webapp-files
|
||||||
|
---
|
||||||
|
|
||||||
|
SilverStripe\Assets\Upload_Validator:
|
||||||
|
allowedExtensions:
|
||||||
|
- 'stl'
|
||||||
|
|
||||||
|
SilverStripe\Assets\File:
|
||||||
|
allowed_extensions:
|
||||||
|
- 'ace'
|
||||||
|
- 'arc'
|
||||||
|
- 'arj'
|
||||||
|
- 'asf'
|
||||||
|
- 'au'
|
||||||
|
- 'avi'
|
||||||
|
- 'bmp'
|
||||||
|
- 'bz2'
|
||||||
|
- 'cab'
|
||||||
|
- 'cda'
|
||||||
|
- 'csv'
|
||||||
|
- 'dmg'
|
||||||
|
- 'doc'
|
||||||
|
- 'docx'
|
||||||
|
- 'dotx'
|
||||||
|
- 'flv'
|
||||||
|
- 'gif'
|
||||||
|
- 'gpx'
|
||||||
|
- 'gz'
|
||||||
|
- 'hqx'
|
||||||
|
- 'ico'
|
||||||
|
- 'jpeg'
|
||||||
|
- 'jpg'
|
||||||
|
- 'kml'
|
||||||
|
- 'm4a'
|
||||||
|
- 'm4v'
|
||||||
|
- 'mid'
|
||||||
|
- 'midi'
|
||||||
|
- 'mkv'
|
||||||
|
- 'mov'
|
||||||
|
- 'mp3'
|
||||||
|
- 'mp4'
|
||||||
|
- 'mpa'
|
||||||
|
- 'mpeg'
|
||||||
|
- 'mpg'
|
||||||
|
- 'ogg'
|
||||||
|
- 'ogv'
|
||||||
|
- 'pages'
|
||||||
|
- 'pcx'
|
||||||
|
- 'pdf'
|
||||||
|
- 'png'
|
||||||
|
- 'pps'
|
||||||
|
- 'ppt'
|
||||||
|
- 'pptx'
|
||||||
|
- 'potx'
|
||||||
|
- 'ra'
|
||||||
|
- 'ram'
|
||||||
|
- 'rm'
|
||||||
|
- 'rtf'
|
||||||
|
- 'sit'
|
||||||
|
- 'sitx'
|
||||||
|
- 'tar'
|
||||||
|
- 'tgz'
|
||||||
|
- 'tif'
|
||||||
|
- 'tiff'
|
||||||
|
- 'txt'
|
||||||
|
- 'wav'
|
||||||
|
- 'webm'
|
||||||
|
- 'wma'
|
||||||
|
- 'wmv'
|
||||||
|
- 'xls'
|
||||||
|
- 'xlsx'
|
||||||
|
- 'xltx'
|
||||||
|
- 'zip'
|
||||||
|
- 'zipx'
|
||||||
|
- 'stl'
|
||||||
|
app_categories:
|
||||||
|
document:
|
||||||
|
- 'stl'
|
@ -3,9 +3,11 @@
|
|||||||
# Cuz WebPack compiling script use it to set configuration
|
# Cuz WebPack compiling script use it to set configuration
|
||||||
|
|
||||||
Site\Templates\WebpackTemplateProvider:
|
Site\Templates\WebpackTemplateProvider:
|
||||||
SRC: app/client/src
|
APPDIR: app
|
||||||
DIST: app/client/dist
|
THEMESDIR: themes
|
||||||
HOSTNAME: localhost
|
HOSTNAME: localhost
|
||||||
PORT: 3000
|
PORT: 3000
|
||||||
TYPESJS: app/client/src/js/types
|
SRC: client/src
|
||||||
TYPESSCSS: app/client/src/scss/types
|
DIST: client/dist
|
||||||
|
TYPESJS: client/src/js/types
|
||||||
|
TYPESSCSS: client/src/scss/types
|
@ -43,8 +43,7 @@ const CarouselUI = (($) => {
|
|||||||
|
|
||||||
// create arrows
|
// create arrows
|
||||||
if ($e.data('arrows')) {
|
if ($e.data('arrows')) {
|
||||||
let $prev = $('<i class="carousel-control-prev" data-target="#' + id + '" role="button" data-slide="prev"><i class="fas fa-chevron-left" aria-hidden="true"></i><i class="sr-only">Previous</i></i>');
|
$e.prepend('<i class="carousel-control-prev" data-target="#' + id + '" role="button" data-slide="prev"><i class="fas fa-chevron-left" aria-hidden="true"></i><i class="sr-only">Previous</i></i>');
|
||||||
$e.prepend($prev);
|
|
||||||
$e.prepend('<i class="carousel-control-next" data-target="#' + id + '" role="button" data-slide="next"><i class="fas fa-chevron-right" aria-hidden="true"></i><i class="sr-only">Next</i></i>');
|
$e.prepend('<i class="carousel-control-next" data-target="#' + id + '" role="button" data-slide="next"><i class="fas fa-chevron-right" aria-hidden="true"></i><i class="sr-only">Next</i></i>');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,8 +67,8 @@ const CarouselUI = (($) => {
|
|||||||
$(event.target).carousel('prev');
|
$(event.target).carousel('prev');
|
||||||
});
|
});
|
||||||
|
|
||||||
$e.find('img').hammer().bind('tap', (event) => {
|
$e.hammer().bind('tap', (event) => {
|
||||||
$e.carousel('next');
|
$(event.target).carousel('next');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,26 @@ const FormBasics = (($) => {
|
|||||||
const $el = $(el);
|
const $el = $(el);
|
||||||
|
|
||||||
$el.selectpicker({
|
$el.selectpicker({
|
||||||
liveSearch: $el.data('live-search')
|
iconBase: 'fas',
|
||||||
|
tickIcon: 'fa-check',
|
||||||
|
liveSearch: $el.data('live-search'),
|
||||||
|
noneSelectedText: $el.data('none-selected-text') || 'Nothing selected',
|
||||||
|
maxOptions: $el.data('max-options') || false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// FIX: hidden picker
|
||||||
|
$el.parents('.field.dropdown').find('.dropdown-toggle').click();
|
||||||
|
$el.parents('.field.dropdown').find('.dropdown-toggle').click();
|
||||||
|
$el.parents('.field.dropdown').find('.dropdown-toggle').blur();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// FIX: hidden picker click
|
||||||
|
if ($selectFields.length) {
|
||||||
|
setTimeout(() => {
|
||||||
|
$(window).scrollTop(0, 0);
|
||||||
|
}, 600);
|
||||||
|
}
|
||||||
|
|
||||||
$fields.each((e, el) => {
|
$fields.each((e, el) => {
|
||||||
const $el = $(el);
|
const $el = $(el);
|
||||||
|
|
||||||
|
@ -104,6 +104,10 @@ const CroppieUI = (($) => {
|
|||||||
data.append(name, blob, name + '-image.png');
|
data.append(name, blob, name + '-image.png');
|
||||||
data.append('ajax', '1');
|
data.append('ajax', '1');
|
||||||
|
|
||||||
|
if (!$(form).data('jsFormValidate').validate()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: $(form).attr('action'),
|
url: $(form).attr('action'),
|
||||||
data: data,
|
data: data,
|
||||||
@ -112,27 +116,29 @@ const CroppieUI = (($) => {
|
|||||||
type: $(form).attr('method'),
|
type: $(form).attr('method'),
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
let IS_JSON = false;
|
let IS_JSON = false;
|
||||||
|
let json = {};
|
||||||
try {
|
try {
|
||||||
IS_JSON = true;
|
IS_JSON = true;
|
||||||
const json = $.parseJSON(data);
|
json = $.parseJSON(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
IS_JSON = false;
|
IS_JSON = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_JSON && typeof json === 'object') {
|
if (IS_JSON) {
|
||||||
for (let k in json) {
|
/*for (let k in json) {
|
||||||
$form.find('select[name="' + k + '"],input[name="' + k + '"],textarea[name="' + k + '"]').setError(true, json[k]);
|
$form.find('select[name="' + k + '"],input[name="' + k + '"],textarea[name="' + k + '"]').setError(true, json[k]);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (typeof json['status'] !== 'undefined' && json['status'] === 'success') {
|
if (typeof json['status'] !== 'undefined' && json['status'] === 'success') {
|
||||||
if (typeof json['link'] !== 'undefined') {
|
if (typeof json['link'] !== 'undefined') {
|
||||||
G.location = json['link'];
|
G.location = json['link'];
|
||||||
} else {
|
} else {
|
||||||
G.location.reload(false);
|
//G.location.reload(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
G.location.reload(false);
|
$(form).replaceWith(data);
|
||||||
|
//G.location.reload(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpinnerUI.hide();
|
SpinnerUI.hide();
|
||||||
|
@ -65,22 +65,26 @@ const FormValidateField = (($) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) {
|
|
||||||
this.removeError();
|
this.removeError();
|
||||||
|
if (valid) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
this.setError(scrollTo, msg);
|
this.setError(scrollTo, msg);
|
||||||
|
}, 500);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
valideURL(str) {
|
valideURL(str) {
|
||||||
const regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
|
const pattern = new RegExp('^(https?:\\/\\/){1}' + // protocol
|
||||||
if (!regex.test(str)) {
|
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' + // domain name
|
||||||
return false;
|
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
|
||||||
} else {
|
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
|
||||||
return true;
|
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
|
||||||
}
|
'(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator
|
||||||
|
return pattern.test(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
setError(scrollTo = true, msg = null) {
|
setError(scrollTo = true, msg = null) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Events from "../_events";
|
import Events from "../_events";
|
||||||
import FormValidateField from "./_ui.form.validate.field";
|
import FormValidateField from "./_ui.form.validate.field";
|
||||||
|
import SpinnerUI from './_ui.spinner';
|
||||||
|
|
||||||
const FormValidate = (($) => {
|
const FormValidate = (($) => {
|
||||||
// Constants
|
// Constants
|
||||||
@ -67,6 +68,7 @@ const FormValidate = (($) => {
|
|||||||
validate(scrollTo = true, badCallback = false) {
|
validate(scrollTo = true, badCallback = false) {
|
||||||
console.log('Checking the form ...');
|
console.log('Checking the form ...');
|
||||||
const ui = this;
|
const ui = this;
|
||||||
|
let valid = true;
|
||||||
|
|
||||||
ui._fields.each(function(i, el) {
|
ui._fields.each(function(i, el) {
|
||||||
const $el = $(el);
|
const $el = $(el);
|
||||||
@ -77,9 +79,14 @@ const FormValidate = (($) => {
|
|||||||
badCallback();
|
badCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('Invalid form data');
|
||||||
|
SpinnerUI.hide();
|
||||||
|
valid = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _jQueryInterface() {
|
static _jQueryInterface() {
|
||||||
|
@ -20,7 +20,7 @@ import FormDatetime from './_components/_ui.form.datetime';
|
|||||||
import FormStepped from './_components/_ui.form.stepped';
|
import FormStepped from './_components/_ui.form.stepped';
|
||||||
import FormValidate from './_components/_ui.form.validate';
|
import FormValidate from './_components/_ui.form.validate';
|
||||||
import FormStorage from './_components/_ui.form.storage';
|
import FormStorage from './_components/_ui.form.storage';
|
||||||
import FormCroppie from './_components/_ui.form.croppie';
|
//import FormCroppie from './_components/_ui.form.croppie';
|
||||||
|
|
||||||
import AjaxUI from './_components/_ui.ajax';
|
import AjaxUI from './_components/_ui.ajax';
|
||||||
|
|
||||||
|
@ -15,7 +15,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.carousel-indicators li {
|
.carousel-indicators li {
|
||||||
box-shadow: 1px 1px #000;
|
box-shadow: none;
|
||||||
|
|
||||||
|
// 1px 1px #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-title {
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel-title,
|
.carousel-title,
|
||||||
|
39
app/client/src/scss/_components/_ui.form.basics.scss
Normal file
39
app/client/src/scss/_components/_ui.form.basics.scss
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// date-time fields
|
||||||
|
input.date,
|
||||||
|
input.time {
|
||||||
|
&[readonly] {
|
||||||
|
background-color: $white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bootstrap-timepicker-widget,
|
||||||
|
.datepicker-dropdown {
|
||||||
|
border: 1px solid #ced4da;
|
||||||
|
box-shadow: 0 0 3px #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bootstrap-timepicker-widget {
|
||||||
|
.glyphicon {
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
display: inline-block;
|
||||||
|
font-style: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
text-rendering: auto;
|
||||||
|
line-height: 1;
|
||||||
|
font-family: Font Awesome\ 5 Free;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glyphicon-chevron-up:before {
|
||||||
|
content: "\f077";
|
||||||
|
}
|
||||||
|
|
||||||
|
.glyphicon-chevron-down:before {
|
||||||
|
content: "\f078";
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
border: 1px solid #ced4da;
|
||||||
|
}
|
||||||
|
}
|
@ -60,6 +60,55 @@ button, input, optgroup, select, textarea,
|
|||||||
|
|
||||||
.field {
|
.field {
|
||||||
margin: ($grid-gutter-height / 4) 0;
|
margin: ($grid-gutter-height / 4) 0;
|
||||||
|
|
||||||
|
&.composite {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.required {
|
||||||
|
&:after {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 2rem;
|
||||||
|
right: .5rem;
|
||||||
|
content: "*";
|
||||||
|
color: $red;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.holder-error,
|
||||||
|
&.error {
|
||||||
|
input, select, textarea {
|
||||||
|
border-color: $red;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
color: $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
@extend .alert;
|
||||||
|
|
||||||
|
@extend .alert-info;
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
margin: .5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message.validation,
|
||||||
|
.message.required,
|
||||||
|
.message.error {
|
||||||
|
@extend .alert;
|
||||||
|
|
||||||
|
@extend .alert-danger;
|
||||||
}
|
}
|
||||||
|
|
||||||
// stick navbar to top using mobile layout
|
// stick navbar to top using mobile layout
|
||||||
|
@ -53,42 +53,12 @@ body.shrink {}
|
|||||||
@extend .alert-danger;
|
@extend .alert-danger;
|
||||||
}
|
}
|
||||||
|
|
||||||
// date-time fields
|
.element {
|
||||||
input.date,
|
&.site__elements__sliderelement {
|
||||||
input.time {
|
.element-container {
|
||||||
&[readonly] {
|
width: 100%;
|
||||||
background-color: $white;
|
padding: 0;
|
||||||
}
|
max-width: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bootstrap-timepicker-widget,
|
|
||||||
.datepicker-dropdown {
|
|
||||||
border: 1px solid #ced4da;
|
|
||||||
box-shadow: 0 0 3px #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-timepicker-widget {
|
|
||||||
.glyphicon {
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
display: inline-block;
|
|
||||||
font-style: normal;
|
|
||||||
font-variant: normal;
|
|
||||||
text-rendering: auto;
|
|
||||||
line-height: 1;
|
|
||||||
font-family: Font Awesome\ 5 Free;
|
|
||||||
font-weight: 900;
|
|
||||||
}
|
|
||||||
|
|
||||||
.glyphicon-chevron-up:before {
|
|
||||||
content: "\f077";
|
|
||||||
}
|
|
||||||
|
|
||||||
.glyphicon-chevron-down:before {
|
|
||||||
content: "\f078";
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
border: 1px solid #ced4da;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
@import "_components/_ui.lightbox";
|
@import "_components/_ui.lightbox";
|
||||||
|
|
||||||
@import "_components/_ui.main";
|
@import "_components/_ui.main";
|
||||||
|
@import "_components/_ui.form.basics";
|
||||||
@import "_components/_ui.elemental";
|
@import "_components/_ui.elemental";
|
||||||
|
|
||||||
// Your custom styling
|
// Your custom styling
|
||||||
|
@ -45,6 +45,15 @@ table {
|
|||||||
@extend .table;
|
@extend .table;
|
||||||
|
|
||||||
@extend .table-bordered;
|
@extend .table-bordered;
|
||||||
|
}
|
||||||
@extend .table-striped;
|
|
||||||
|
table {
|
||||||
|
&.table-none {
|
||||||
|
border: 0;
|
||||||
|
|
||||||
|
tr, td, th {
|
||||||
|
border: 0;
|
||||||
|
background: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,10 @@ en:
|
|||||||
SilverStripe\Security\Member:
|
SilverStripe\Security\Member:
|
||||||
SURNAME: 'Last Name'
|
SURNAME: 'Last Name'
|
||||||
db_Surname: 'Last Name'
|
db_Surname: 'Last Name'
|
||||||
|
SUBJECTPASSWORDRESET: 'Your password reset link'
|
||||||
|
ENTEREMAIL: 'Please enter an email address to get a password reset link.'
|
||||||
|
PASSWORDRESETSENTHEADER: 'Password reset link sent'
|
||||||
|
PASSWORDRESETSENTTEXT: 'Thank you. A reset link has been sent, provided an account exists for this email address.'
|
||||||
Page:
|
Page:
|
||||||
LOADINGTEXT: "LOADING .."
|
LOADINGTEXT: "LOADING .."
|
||||||
JAVASCRIPTREQUIRED: "Please, enable javascript!"
|
JAVASCRIPTREQUIRED: "Please, enable javascript!"
|
||||||
@ -13,3 +17,7 @@ en:
|
|||||||
db_Surname: 'Last Name'
|
db_Surname: 'Last Name'
|
||||||
SilverShop\Page\CheckoutPage:
|
SilverShop\Page\CheckoutPage:
|
||||||
ProceedToPayment: 'Send Order to Store'
|
ProceedToPayment: 'Send Order to Store'
|
||||||
|
UndefinedOffset\NoCaptcha\Forms\NocaptchaField:
|
||||||
|
EMPTY: "Please prove you are human - check the Captcha box."
|
||||||
|
NOSCRIPT: "You must enable JavaScript to submit this form"
|
||||||
|
VALIDATE_ERROR: "Captcha could not be validated"
|
||||||
|
@ -61,6 +61,7 @@ class SliderElement extends ElementSlideshow
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$grid = $fields->dataFieldByName('Slides');
|
$grid = $fields->dataFieldByName('Slides');
|
||||||
|
if ($grid) {
|
||||||
$config = $grid->getConfig();
|
$config = $grid->getConfig();
|
||||||
|
|
||||||
$columns = new GridFieldEditableColumns();
|
$columns = new GridFieldEditableColumns();
|
||||||
@ -72,6 +73,7 @@ class SliderElement extends ElementSlideshow
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$config->addComponent($columns);
|
$config->addComponent($columns);
|
||||||
|
}
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
69
app/src/Extensions/LostPasswordHandlerExtension.php
Normal file
69
app/src/Extensions/LostPasswordHandlerExtension.php
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: tony
|
||||||
|
* Date: 6/30/18
|
||||||
|
* Time: 11:37 PM
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Site\Extensions;
|
||||||
|
|
||||||
|
use Sheadawson\Linkable\Forms\LinkField;
|
||||||
|
use Sheadawson\Linkable\Models\Link;
|
||||||
|
use SilverStripe\Control\HTTPResponse;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\ORM\DataExtension;
|
||||||
|
use SilverStripe\ORM\FieldType\DBField;
|
||||||
|
use SilverStripe\Security\MemberAuthenticator\LostPasswordHandler;
|
||||||
|
|
||||||
|
class LostPasswordHandlerExtension extends LostPasswordHandler
|
||||||
|
{
|
||||||
|
private static $url_handlers = [
|
||||||
|
'passwordsent' => 'passwordsent',
|
||||||
|
];
|
||||||
|
|
||||||
|
private static $allowed_actions = [
|
||||||
|
'passwordsent',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the "password sent" page, after a user has requested
|
||||||
|
* to reset their password.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function passwordsent()
|
||||||
|
{
|
||||||
|
$message = _t(
|
||||||
|
'SilverStripe\\Security\\Security.PASSWORDRESETSENTTEXT',
|
||||||
|
"Thank you. A reset link has been sent, provided an account exists for this email address."
|
||||||
|
);
|
||||||
|
|
||||||
|
$email = $this->getRequest()->getVar('email');
|
||||||
|
$message = $email
|
||||||
|
? 'Thank you! A reset link has been sent to \''.$email.'\', provided an account exists for this email address.'
|
||||||
|
: $message;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'Title' => _t(
|
||||||
|
'SilverStripe\\Security\\Security.PASSWORDRESETSENTHEADER',
|
||||||
|
"Password reset link sent".($email ? ' to \''.$email.'\'' : '')
|
||||||
|
),
|
||||||
|
'ElementalArea' => DBField::create_field('HTMLFragment', "<p>$message</p>"),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avoid information disclosure by displaying the same status, regardless wether the email address actually exists
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return HTTPResponse
|
||||||
|
*/
|
||||||
|
protected function redirectToSuccess(array $data)
|
||||||
|
{
|
||||||
|
$link = $this->link('passwordsent').'?email='.$data['Email'];
|
||||||
|
|
||||||
|
return $this->redirect($this->addBackURLParam($link));
|
||||||
|
}
|
||||||
|
}
|
37
app/src/Extensions/PlaceholderFormExtension.php
Normal file
37
app/src/Extensions/PlaceholderFormExtension.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Site\Extensions;
|
||||||
|
|
||||||
|
use SilverStripe\Core\Extension;
|
||||||
|
use SilverStripe\Forms\CompositeField;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
|
||||||
|
class UserFormExtension extends Extension
|
||||||
|
{
|
||||||
|
public function updateFormFields(FieldList $fields)
|
||||||
|
{
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
$this->setPlaceholder($field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setPlaceholder($field)
|
||||||
|
{
|
||||||
|
if(is_a($field, TextField::class)) {
|
||||||
|
$field->setAttribute(
|
||||||
|
'placeholder',
|
||||||
|
$field->Title()
|
||||||
|
.($field->hasClass('requiredField') ? '*' : '')
|
||||||
|
);
|
||||||
|
$field->setTitle('');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_a($field, CompositeField::class)) {
|
||||||
|
$children = $field->getChildren();
|
||||||
|
foreach ($children as $child) {
|
||||||
|
$this->setPlaceholder($child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ use SilverStripe\ORM\DataExtension;
|
|||||||
use SilverStripe\CMS\Model\SiteTree;
|
use SilverStripe\CMS\Model\SiteTree;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
use SilverStripe\Forms\TreeMultiselectField;
|
use SilverStripe\Forms\TreeMultiselectField;
|
||||||
|
use SilverStripe\Forms\DropdownField;
|
||||||
use BetterBrief\GoogleMapField;
|
use BetterBrief\GoogleMapField;
|
||||||
|
|
||||||
class SiteConfigExtension extends DataExtension
|
class SiteConfigExtension extends DataExtension
|
||||||
|
79
app/src/Extensions/UserDefinedFormExtension.php
Normal file
79
app/src/Extensions/UserDefinedFormExtension.php
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Site\Extensions;
|
||||||
|
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldDataColumns;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldPaginator;
|
||||||
|
use SilverStripe\Forms\ListboxField;
|
||||||
|
use SilverStripe\Forms\TextareaField;
|
||||||
|
use SilverStripe\ORM\DataExtension;
|
||||||
|
use SilverStripe\UserForms\Model\EditableFormField;
|
||||||
|
|
||||||
|
class UserDefinedFormExtension extends DataExtension
|
||||||
|
{
|
||||||
|
private static $db = [
|
||||||
|
'CustomThankYouCode' => 'HTMLText',
|
||||||
|
'RedirectOnComplete' => 'Boolean(0)',
|
||||||
|
'RedirectOnCompleteURL' => 'Varchar(255)',
|
||||||
|
];
|
||||||
|
|
||||||
|
private static $many_many = [
|
||||||
|
'SubmissionColumns' => EditableFormField::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
public function updateCMSFields(FieldList $fields)
|
||||||
|
{
|
||||||
|
parent::updateCMSFields($fields);
|
||||||
|
|
||||||
|
$fields->removeByName('RedirectOnComplete');
|
||||||
|
$fields->removeByName('RedirectOnCompleteURL');
|
||||||
|
|
||||||
|
$fields->removeByName('SubmissionColumns');
|
||||||
|
|
||||||
|
$fields->addFieldToTab(
|
||||||
|
'Root.Main',
|
||||||
|
ListboxField::create(
|
||||||
|
'SubmissionColumns',
|
||||||
|
'Display following columns at submissions list',
|
||||||
|
$this->owner->Fields()->map('ID', 'Title')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$tab = $fields->findOrMakeTab('Root.FormOptions');
|
||||||
|
|
||||||
|
/*$tab->push(CheckboxField::create('RedirectOnComplete'));
|
||||||
|
$tab->push(TextField::create('RedirectOnCompleteURL'));*/
|
||||||
|
$tab->push(TextareaField::create('CustomThankYouCode'));
|
||||||
|
|
||||||
|
$grid = $fields->dataFieldByName('Submissions');
|
||||||
|
|
||||||
|
$config = $grid->getConfig();
|
||||||
|
$config->getComponentByType(GridFieldPaginator::class)->setItemsPerPage(100);
|
||||||
|
|
||||||
|
$cols = $this->owner->SubmissionColumns();
|
||||||
|
if ($grid && $cols->count()) {
|
||||||
|
$dataCols = $config->getComponentByType(GridFieldDataColumns::class);
|
||||||
|
|
||||||
|
$columns = [
|
||||||
|
'ID' => 'ID',
|
||||||
|
'Created' => 'Created',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($cols as $col) {
|
||||||
|
$title = $col->getField('Title');
|
||||||
|
$name = $col->getField('Name');
|
||||||
|
$columns[$name] = [
|
||||||
|
'title' => $title,
|
||||||
|
'callback' => function($item) use ($name) {
|
||||||
|
return $item->relField($name);
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$columns['Actions'] = 'Actions';
|
||||||
|
|
||||||
|
$dataCols->setDisplayFields($columns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,8 @@ use SilverStripe\Forms\RequiredFields;
|
|||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
use SilverStripe\ORM\ArrayList;
|
use SilverStripe\ORM\ArrayList;
|
||||||
use DNADesign\Elemental\Models\ElementContent;
|
use DNADesign\Elemental\Models\ElementContent;
|
||||||
|
use DNADesign\Elemental\Models\ElementalArea;
|
||||||
|
use DNADesign\ElementalUserForms\Control\ElementFormController;
|
||||||
|
|
||||||
class PageController extends ContentController
|
class PageController extends ContentController
|
||||||
{
|
{
|
||||||
@ -38,6 +40,26 @@ class PageController extends ContentController
|
|||||||
return $this->render();
|
return $this->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function ElementalArea()
|
||||||
|
{
|
||||||
|
if($this->CurrentElement()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ElementalArea::get()->byID($this->getField('ElementalAreaID'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function CurrentElement()
|
||||||
|
{
|
||||||
|
$contoller_curr = Controller::curr();
|
||||||
|
|
||||||
|
if(is_a($contoller_curr, ElementFormController::class)) {
|
||||||
|
return $contoller_curr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function SearchForm()
|
public function SearchForm()
|
||||||
{
|
{
|
||||||
return Form::create(
|
return Form::create(
|
||||||
@ -98,7 +120,7 @@ class PageController extends ContentController
|
|||||||
$results->removeDuplicates();
|
$results->removeDuplicates();
|
||||||
|
|
||||||
return ArrayData::create([
|
return ArrayData::create([
|
||||||
'Title' => 'Search query "'.$term.'"',
|
'Title' => 'You searched for: "'.$term.'"',
|
||||||
'Results' => PaginatedList::create($results),
|
'Results' => PaginatedList::create($results),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -124,8 +146,10 @@ class PageController extends ContentController
|
|||||||
|
|
||||||
public function getSiteWideMessage()
|
public function getSiteWideMessage()
|
||||||
{
|
{
|
||||||
if (!$this->site_message) {
|
$request = $this->getRequest();
|
||||||
$session = $this->getRequest()->getSession();
|
|
||||||
|
if ($request->isGET() && !$this->site_message) {
|
||||||
|
$session = $request->getSession();
|
||||||
$this->site_message = $session->get('SiteWideMessage');
|
$this->site_message = $session->get('SiteWideMessage');
|
||||||
$session->clear('SiteWideMessage');
|
$session->clear('SiteWideMessage');
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ class DeferedRequirements implements TemplateGlobalProvider
|
|||||||
public static function Auto($class = false)
|
public static function Auto($class = false)
|
||||||
{
|
{
|
||||||
$config = Config::inst()->get(self::class);
|
$config = Config::inst()->get(self::class);
|
||||||
|
$themeName = WebpackTemplateProvider::themeName();
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
Requirements::block(THIRDPARTY_DIR.'/jquery/jquery.js');
|
Requirements::block(THIRDPARTY_DIR.'/jquery/jquery.js');
|
||||||
@ -50,10 +51,10 @@ class DeferedRequirements implements TemplateGlobalProvider
|
|||||||
}
|
}
|
||||||
// App libs
|
// App libs
|
||||||
if (!$config['nofontawesome']) {
|
if (!$config['nofontawesome']) {
|
||||||
DeferedRequirements::loadCSS('//use.fontawesome.com/releases/v5.3.1/css/all.css');
|
DeferedRequirements::loadCSS('//use.fontawesome.com/releases/v5.4.0/css/all.css');
|
||||||
}
|
}
|
||||||
DeferedRequirements::loadCSS('app.css');
|
DeferedRequirements::loadCSS($themeName.'.css');
|
||||||
DeferedRequirements::loadJS('app.js');
|
DeferedRequirements::loadJS($themeName.'.js');
|
||||||
|
|
||||||
// Class libs
|
// Class libs
|
||||||
$class = get_class(Controller::curr());
|
$class = get_class(Controller::curr());
|
||||||
@ -72,17 +73,17 @@ class DeferedRequirements implements TemplateGlobalProvider
|
|||||||
$dir = Path::join(
|
$dir = Path::join(
|
||||||
Director::publicFolder(),
|
Director::publicFolder(),
|
||||||
ManifestFileFinder::RESOURCES_DIR,
|
ManifestFileFinder::RESOURCES_DIR,
|
||||||
'app',
|
$themeName,
|
||||||
'client',
|
'client',
|
||||||
'dist'
|
'dist'
|
||||||
);
|
);
|
||||||
|
|
||||||
if (file_exists(Path::join($dir, 'css', $class . '.css'))) {
|
if (file_exists(Path::join($dir, 'css', $themeName.'_'.$class . '.css'))) {
|
||||||
DeferedRequirements::loadCSS($class . '.css');
|
DeferedRequirements::loadCSS($themeName.'_'.$class . '.css');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(Path::join($dir, 'js', $class . '.js'))) {
|
if (file_exists(Path::join($dir, 'js', $themeName.'_'.$class . '.js'))) {
|
||||||
DeferedRequirements::loadJS($class . '.js');
|
DeferedRequirements::loadJS($themeName.'_'.$class . '.js');
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::forTemplate();
|
return self::forTemplate();
|
||||||
@ -90,7 +91,8 @@ class DeferedRequirements implements TemplateGlobalProvider
|
|||||||
|
|
||||||
public static function loadCSS($css)
|
public static function loadCSS($css)
|
||||||
{
|
{
|
||||||
if (self::$defered && !self::_webpackActive()) {
|
$external = (mb_substr($css, 0, 2) === '//' || mb_substr($css, 0, 4) === 'http');
|
||||||
|
if ($external || (self::$defered && !self::_webpackActive())) {
|
||||||
self::$css[] = $css;
|
self::$css[] = $css;
|
||||||
} else {
|
} else {
|
||||||
WebpackTemplateProvider::loadCSS($css);
|
WebpackTemplateProvider::loadCSS($css);
|
||||||
@ -99,6 +101,9 @@ class DeferedRequirements implements TemplateGlobalProvider
|
|||||||
|
|
||||||
public static function loadJS($js)
|
public static function loadJS($js)
|
||||||
{
|
{
|
||||||
|
/*$external = (mb_substr($js, 0, 2) === '//' || mb_substr($js, 0, 4) === 'http');
|
||||||
|
if ($external || (self::$defered && !self::_webpackActive())) {*/
|
||||||
|
// webpack supposed to load external JS
|
||||||
if (self::$defered && !self::_webpackActive()) {
|
if (self::$defered && !self::_webpackActive()) {
|
||||||
self::$js[] = $js;
|
self::$js[] = $js;
|
||||||
} else {
|
} else {
|
||||||
@ -118,10 +123,6 @@ class DeferedRequirements implements TemplateGlobalProvider
|
|||||||
|
|
||||||
public static function forTemplate()
|
public static function forTemplate()
|
||||||
{
|
{
|
||||||
if (!self::$defered || self::_webpackActive()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = '';
|
$result = '';
|
||||||
foreach (self::$css as $css) {
|
foreach (self::$css as $css) {
|
||||||
$result .= '<i class="defer-cs" data-load="' . self::get_url($css) . '"></i>';
|
$result .= '<i class="defer-cs" data-load="' . self::get_url($css) . '"></i>';
|
||||||
@ -137,7 +138,7 @@ class DeferedRequirements implements TemplateGlobalProvider
|
|||||||
.'function lscd(a){a<s.length-1&&(a++,lsc(s.item(a).getAttribute("data-load"),function(){lscd(a)}))}'
|
.'function lscd(a){a<s.length-1&&(a++,lsc(s.item(a).getAttribute("data-load"),function(){lscd(a)}))}'
|
||||||
.'for(var s=document.getElementsByClassName("defer-cs"),i=0;i<s.length;i++){var b=document.createElement("link");b.rel="stylesheet",'
|
.'for(var s=document.getElementsByClassName("defer-cs"),i=0;i<s.length;i++){var b=document.createElement("link");b.rel="stylesheet",'
|
||||||
.'b.type="text/css",b.href=s.item(i).getAttribute("data-load"),b.media="all";var c=document.getElementsByTagName("body")[0];'
|
.'b.type="text/css",b.href=s.item(i).getAttribute("data-load"),b.media="all";var c=document.getElementsByTagName("body")[0];'
|
||||||
.'c.appendChild(b)}var s=document.getElementsByClassName("defer-sc"),i=0;lsc(s.item(i).getAttribute("data-load"),function(){lscd(i)});'
|
.'c.appendChild(b)}var s=document.getElementsByClassName("defer-sc"),i=0;if(s.item(i)!==null)lsc(s.item(i).getAttribute("data-load"),function(){lscd(i)});'
|
||||||
.'</script>';
|
.'</script>';
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Directs assets requests to Webpack server or to static files
|
* Directs assets requests to Webpack server or to static files
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Site\Templates;
|
namespace Site\Templates;
|
||||||
|
|
||||||
|
use SilverStripe\Core\Manifest\ModuleManifest;
|
||||||
use SilverStripe\View\TemplateGlobalProvider;
|
use SilverStripe\View\TemplateGlobalProvider;
|
||||||
use SilverStripe\View\Requirements;
|
use SilverStripe\View\Requirements;
|
||||||
use SilverStripe\Control\Director;
|
use SilverStripe\Control\Director;
|
||||||
@ -27,7 +28,7 @@ class WebpackTemplateProvider implements TemplateGlobalProvider
|
|||||||
/**
|
/**
|
||||||
* @var string assets static files directory
|
* @var string assets static files directory
|
||||||
*/
|
*/
|
||||||
private static $dist = 'app/client/dist';
|
private static $dist = 'client/dist';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
@ -38,7 +39,8 @@ class WebpackTemplateProvider implements TemplateGlobalProvider
|
|||||||
'WebpackDevServer' => 'isActive',
|
'WebpackDevServer' => 'isActive',
|
||||||
'WebpackCSS' => 'loadCSS',
|
'WebpackCSS' => 'loadCSS',
|
||||||
'WebpackJS' => 'loadJS',
|
'WebpackJS' => 'loadJS',
|
||||||
'ResoursesURL' => 'resoursesURL',
|
'ResourcesURL' => 'resourcesURL',
|
||||||
|
'ProjectName' => 'themeName',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +50,10 @@ class WebpackTemplateProvider implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function loadCSS($path)
|
public static function loadCSS($path)
|
||||||
{
|
{
|
||||||
|
if (self::isActive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Requirements::css(self::_getPath($path));
|
Requirements::css(self::_getPath($path));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,9 +66,14 @@ class WebpackTemplateProvider implements TemplateGlobalProvider
|
|||||||
Requirements::javascript(self::_getPath($path));
|
Requirements::javascript(self::_getPath($path));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function resoursesURL($link = null)
|
public static function themeName()
|
||||||
{
|
{
|
||||||
return Controller::join_links(Director::baseURL(), '/resources/app/client/dist/img/', $link);
|
return Config::inst()->get(ModuleManifest::class, 'project');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function resourcesURL($link = null)
|
||||||
|
{
|
||||||
|
return Controller::join_links(Director::baseURL(), '/resources/'.self::themeName().'/client/dist/img/', $link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -100,6 +111,7 @@ class WebpackTemplateProvider implements TemplateGlobalProvider
|
|||||||
{
|
{
|
||||||
return strpos($path, '//') === false ?
|
return strpos($path, '//') === false ?
|
||||||
Controller::join_links(
|
Controller::join_links(
|
||||||
|
self::themeName(),
|
||||||
Config::inst()->get(__CLASS__, 'DIST'),
|
Config::inst()->get(__CLASS__, 'DIST'),
|
||||||
(strpos($path, '.css') ? 'css' : 'js'),
|
(strpos($path, '.css') ? 'css' : 'js'),
|
||||||
$path
|
$path
|
||||||
|
89
app/src/Tests/TestServer.php
Normal file
89
app/src/Tests/TestServer.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: tony
|
||||||
|
* Date: 10/31/18
|
||||||
|
* Time: 5:31 AM
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Site\Tests;
|
||||||
|
|
||||||
|
use SilverStripe\Assets\Upload_Validator;
|
||||||
|
use SilverStripe\Core\Cache\FilesystemCacheFactory;
|
||||||
|
use SilverStripe\Core\Config\Config;
|
||||||
|
use SilverStripe\Core\Convert;
|
||||||
|
use SilverStripe\Dev\BuildTask;
|
||||||
|
use SilverStripe\Assets\File;
|
||||||
|
|
||||||
|
class TestServer extends BuildTask
|
||||||
|
{
|
||||||
|
protected $title = 'Test server';
|
||||||
|
protected $description = 'Test server';
|
||||||
|
|
||||||
|
public function run($request)
|
||||||
|
{
|
||||||
|
echo '<style>table{width:100%}table td,table th{border:1px solid #dedede}</style>';
|
||||||
|
|
||||||
|
echo '<h2>Testing Uploads</h2>';
|
||||||
|
$maxUpload = ini_get('upload_max_filesize');
|
||||||
|
$maxPost = ini_get('post_max_size');
|
||||||
|
|
||||||
|
echo self::success('PHP max upload size: '.$maxUpload);
|
||||||
|
echo self::success('PHP max post size: '.$maxPost);
|
||||||
|
echo self::success('So calculated max upload size: '.self::formatBytes(min(
|
||||||
|
Convert::memstring2bytes($maxUpload),
|
||||||
|
Convert::memstring2bytes($maxPost)
|
||||||
|
)));
|
||||||
|
|
||||||
|
$defaultSizes = Config::inst()->get(Upload_Validator::class, 'default_max_file_size');
|
||||||
|
if($defaultSizes) {
|
||||||
|
if(!is_array($defaultSizes)){
|
||||||
|
echo self::error('default_max_file_size miss-configuration, plz fix');
|
||||||
|
var_dump($defaultSizes);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '<h3>Configured limits:</h3><table style="text-align:center">'
|
||||||
|
.'<thead><tr><th>File</th><th>Size limit</th></tr></thead><tbody>';
|
||||||
|
foreach ($defaultSizes as $k => $size) {
|
||||||
|
echo '<tr><td>'.$k.'</td><td>'.$size.'</td></tr>';
|
||||||
|
}
|
||||||
|
echo '</tbody></table>';
|
||||||
|
}
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static function formatBytes($size, $precision = 2)
|
||||||
|
{
|
||||||
|
$base = log($size, 1024);
|
||||||
|
$suffixes = array('', 'K', 'M', 'G', 'T');
|
||||||
|
|
||||||
|
return round(pow(1024, $base - floor($base)), $precision) . $suffixes[(string)floor($base)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function error($text)
|
||||||
|
{
|
||||||
|
return '<span style="color:red">ERROR: '.$text.'</span><br/>';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function success($text)
|
||||||
|
{
|
||||||
|
return '<span style="color:green">SUCCESS: '.$text.'</span><br/>';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function warning($text)
|
||||||
|
{
|
||||||
|
return '<span style="color:#0014ff">WARNING: '.$text.'</span><br/>';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function renderValidation($result)
|
||||||
|
{
|
||||||
|
echo '<p>';
|
||||||
|
$msgs = $result->getMessages();
|
||||||
|
foreach ($msgs as $msg) {
|
||||||
|
echo self::error($msg['fieldName'].': '.$msg['message']);
|
||||||
|
}
|
||||||
|
echo '</p>';
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,11 @@
|
|||||||
<h1 class="page-header container<% if $ElementalArea.Elements.Count < 1 %> no-elements<% end_if %>">$Title</h1>
|
<h1 class="page-header container<% if $ElementalArea.Elements.Count < 1 %> no-elements<% end_if %>">$Title</h1>
|
||||||
|
|
||||||
<div class="page-content">
|
<div class="page-content">
|
||||||
|
<% if $CurrentElement %>
|
||||||
|
$CurrentElement
|
||||||
|
<% else %>
|
||||||
$ElementalArea
|
$ElementalArea
|
||||||
|
<% end_if %>
|
||||||
|
|
||||||
<% if $Form %>
|
<% if $Form %>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@ -27,7 +27,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<% if $PrivacyPolicy %>
|
<% if $PrivacyPolicy %>
|
||||||
<a href="$PrivacyPolicy.Link" target="_blank">$PrivacyPolicy.Title</a>
|
<a href="$PrivacyPolicy.Link">$PrivacyPolicy.Title</a>
|
||||||
|
<% end_if %>
|
||||||
|
<% if $Sitemap %>
|
||||||
|
<a href="$Sitemap.Link">$Sitemap.Title</a>
|
||||||
<% end_if %>
|
<% end_if %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<a id="Logo" href="/"><img src="{$StaticPath('img/logo.png')}" alt="{$SiteConfig.Title}" /></a>
|
<a id="Logo" href="/"><img src="{$ResoursesURL('logo.png')}" alt="{$SiteConfig.Title}" /></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 text-right">
|
<div class="col-sm-6 text-right">
|
||||||
<% with $SiteConfig %>
|
<% with $SiteConfig %>
|
||||||
|
1
app/templates/Includes/SideBar.ss
Normal file
1
app/templates/Includes/SideBar.ss
Normal file
@ -0,0 +1 @@
|
|||||||
|
<div></div>
|
@ -0,0 +1,11 @@
|
|||||||
|
<div id="uff">
|
||||||
|
<div class="on-complete-message user-form">
|
||||||
|
$OnCompleteMessage
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<% if $CustomThankYouCode %>
|
||||||
|
<div class="custom-code user-form">
|
||||||
|
$CustomThankYouCode.RAW
|
||||||
|
</div>
|
||||||
|
<% end_if %>
|
||||||
|
</div>
|
@ -4,7 +4,7 @@
|
|||||||
"description": "The SilverStripe Framework Installer",
|
"description": "The SilverStripe Framework Installer",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.1.0",
|
"php": ">=7.1.0",
|
||||||
"silverstripe/recipe-cms": "1.2.x-dev",
|
"silverstripe/recipe-cms": "^4",
|
||||||
"wilr/silverstripe-googlesitemaps": "*",
|
"wilr/silverstripe-googlesitemaps": "*",
|
||||||
"silverstripe/userforms": "*",
|
"silverstripe/userforms": "*",
|
||||||
"undefinedoffset/sortablegridfield": "*",
|
"undefinedoffset/sortablegridfield": "*",
|
||||||
@ -13,37 +13,34 @@
|
|||||||
"jonom/silverstripe-betternavigator": "*",
|
"jonom/silverstripe-betternavigator": "*",
|
||||||
"silverstripe/externallinks": "*",
|
"silverstripe/externallinks": "*",
|
||||||
"symbiote/silverstripe-gridfieldextensions": "*",
|
"symbiote/silverstripe-gridfieldextensions": "*",
|
||||||
"colymba/gridfield-bulk-editing-tools": "3.0.0-beta4",
|
"colymba/gridfield-bulk-editing-tools": "^3",
|
||||||
"dnadesign/silverstripe-elemental-list": "*",
|
"dnadesign/silverstripe-elemental-list": "*",
|
||||||
"dnadesign/silverstripe-elemental-virtual": "*",
|
"dnadesign/silverstripe-elemental-virtual": "*",
|
||||||
"dnadesign/silverstripe-elemental-userforms": "*",
|
"dnadesign/silverstripe-elemental-userforms": "*",
|
||||||
"dynamic/silverstripe-elemental-blocks": "*",
|
"dynamic/silverstripe-elemental-blocks": "*",
|
||||||
"drmartingonzo/ss-tinymce-charcount": "^1.0",
|
"drmartingonzo/ss-tinymce-charcount": "*",
|
||||||
"axllent/silverstripe-version-truncator": "*",
|
"axllent/silverstripe-version-truncator": "*",
|
||||||
"firesphere/googlemapsfield": "^1.0@dev",
|
"firesphere/googlemapsfield": "*",
|
||||||
"gorriecoe/silverstripe-dataobjecthistory": "^1.2",
|
"gorriecoe/silverstripe-dataobjecthistory": "*",
|
||||||
"mak001/silverstripe-categorization": "^1.0@dev",
|
"axllent/silverstripe-bootstrap-forms": "*",
|
||||||
"axllent/silverstripe-bootstrap-forms": "^2.0",
|
"silverstripe/redirectedurls": "*",
|
||||||
"silverstripe/redirectedurls": "dev-master",
|
|
||||||
"undefinedoffset/silverstripe-nocaptcha": "*",
|
"undefinedoffset/silverstripe-nocaptcha": "*",
|
||||||
"a2nt/silverstripe-font-awesome-field": "dev-master",
|
"a2nt/silverstripe-font-awesome-field": "dev-master",
|
||||||
"stevie-mayhew/silverstripe-svg": "^2.1",
|
"stevie-mayhew/silverstripe-svg": "*",
|
||||||
"betterbrief/silverstripe-googlemapfield": "^2.1",
|
"betterbrief/silverstripe-googlemapfield": "*",
|
||||||
"innoweb/silverstripe-sitemap": "^2.0",
|
"innoweb/silverstripe-sitemap": "*",
|
||||||
"silverstripe/multiuser-editing-alert": "^2.0",
|
"silverstripe/multiuser-editing-alert": "*",
|
||||||
"gorriecoe/silverstripe-link": "^1.2",
|
"gorriecoe/silverstripe-link": "*",
|
||||||
"gorriecoe/silverstripe-linkfield": "dev-master"
|
"gorriecoe/silverstripe-linkfield": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^5.7",
|
"phpunit/phpunit": "^5.7",
|
||||||
"lekoala/silverstripe-debugbar": "dev-master"
|
"lekoala/silverstripe-debugbar": "dev-master"
|
||||||
},
|
},
|
||||||
"repositories": [
|
"repositories": [{
|
||||||
{
|
|
||||||
"type": "vcs",
|
"type": "vcs",
|
||||||
"url": "https://github.com/a2nt/silverstripe-font-awesome"
|
"url": "https://github.com/a2nt/silverstripe-font-awesome"
|
||||||
}
|
}],
|
||||||
],
|
|
||||||
"extra": {
|
"extra": {
|
||||||
"expose": [
|
"expose": [
|
||||||
"app/client/dist"
|
"app/client/dist"
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
"bootstrap-offcanvas": "^1.0.0",
|
"bootstrap-offcanvas": "^1.0.0",
|
||||||
"bootstrap-select": "^1.13.2",
|
"bootstrap-select": "^1.13.2",
|
||||||
"bootstrap-timepicker": "^0.5.2",
|
"bootstrap-timepicker": "^0.5.2",
|
||||||
|
"bootstrap-confirmation2": "^4.0.4",
|
||||||
|
"bootstrap-table": "^1.14.2",
|
||||||
"core-util-is": "^1.0.2",
|
"core-util-is": "^1.0.2",
|
||||||
"font-awesome": "^4.7.0",
|
"font-awesome": "^4.7.0",
|
||||||
"foundation-emails": "^2.2.1",
|
"foundation-emails": "^2.2.1",
|
||||||
|
0
themes/sample/client/src/js/_layout.js
Normal file
0
themes/sample/client/src/js/_layout.js
Normal file
4
themes/sample/client/src/js/app.js
Normal file
4
themes/sample/client/src/js/app.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import '../scss/app.scss';
|
||||||
|
|
||||||
|
import 'js/app';
|
||||||
|
import './_layout';
|
0
themes/sample/client/src/scss/_layout.scss
Normal file
0
themes/sample/client/src/scss/_layout.scss
Normal file
2
themes/sample/client/src/scss/app.scss
Normal file
2
themes/sample/client/src/scss/app.scss
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@import "~scss/app.scss";
|
||||||
|
@import "_layout";
|
51
themes/sample/templates/Page.ss
Normal file
51
themes/sample/templates/Page.ss
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="$ContentLocale.ATT" dir="$i18nScriptDirection.ATT">
|
||||||
|
<%-- manifest="/cache.appcache" --%>
|
||||||
|
<head>
|
||||||
|
<% include MetaHead %>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body oncontextmenu="return false;"<% with $SiteConfig %> data-default-lng="$Longitude" data-default-lat="$Latitude"<% end_with %>>
|
||||||
|
<%-- Upgrade your Browser notice --%>
|
||||||
|
<!--[if lt IE 10]><div class="main-bn"><a href="https://www.google.com/chrome/browser/desktop/" title="<%t Page.UPGRADEBROWSER 'Upgrade your browser' %>"><%t Page.OUTDATEDBROWSER 'You are using an outdated browser. For a faster, safer browsing experience, upgrade for free today.' %></a></div><![endif]-->
|
||||||
|
|
||||||
|
<%-- No JS enabled notice --%>
|
||||||
|
<noscript><div class="main-bn"><%t Page.JAVASCRIPTREQUIRED 'Please, enable javascript.' %></div></noscript>
|
||||||
|
|
||||||
|
<%-- Loading Spinner --%>
|
||||||
|
<div id="PageLoading"><div class="loading-spinner"><div class="bubblingG"><i id="bubblingG_1"></i><i id="bubblingG_2"></i><i id="bubblingG_3"></i></div><br/><%t Page.LOADINGTEXT 'LOADING ..' %></div></div>
|
||||||
|
|
||||||
|
<%-- Site Wide Alert Message --%>
|
||||||
|
<% include SiteWideMessage %>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<header id="Header" class="container">
|
||||||
|
<% include Header %>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main id="MainContent" data-ajax-region="LayoutAjax">
|
||||||
|
$Layout
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer id="Footer" class="site-footer">
|
||||||
|
<% include Footer %>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<div class="hidden-print">
|
||||||
|
$BetterNavigator
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%-- Require CSS+JS from /public/resourses/[js,css]/[ClassName].[js,css] --%>
|
||||||
|
$AutoRequirements($ClassName).RAW
|
||||||
|
|
||||||
|
<%-- Mapbox --%>
|
||||||
|
<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" />
|
||||||
|
|
||||||
|
<%-- place extra requirements after this line --%>
|
||||||
|
<div class="extra-code extra-code-site">
|
||||||
|
$SiteConfig.ExtraCode
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -6,46 +6,79 @@ const webpack = require('webpack');
|
|||||||
const conf = require('./webpack.configuration');
|
const conf = require('./webpack.configuration');
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const filesystem = require('fs');
|
||||||
|
|
||||||
const includes = {
|
const includes = {};
|
||||||
app: path.join(__dirname, conf.SRC, 'js/app.js'),
|
|
||||||
};
|
|
||||||
|
|
||||||
const _getAllFilesFromFolder = function(dir) {
|
const _addAppFiles = (theme) => {
|
||||||
dir = path.resolve(__dirname, dir);
|
|
||||||
|
|
||||||
const filesystem = require('fs');
|
const dirPath = path.resolve(__dirname, theme);
|
||||||
|
const themeName = path.basename(theme);
|
||||||
|
|
||||||
|
if (filesystem.existsSync(path.join(dirPath, conf.SRC, 'js', 'app.js'))) {
|
||||||
|
includes[`${themeName}`] = path.join(dirPath, conf.SRC, 'js', 'app.js');
|
||||||
|
} else if (filesystem.existsSync(path.join(dirPath, conf.SRC, 'scss', 'app.scss'))) {
|
||||||
|
includes[`${themeName}`] = path.join(dirPath, conf.SRC, 'scss', 'app.scss');
|
||||||
|
}
|
||||||
|
|
||||||
|
const _getAllFilesFromFolder = function(dir, includeSubFolders = true) {
|
||||||
|
const dirPath = path.resolve(__dirname, dir);
|
||||||
let results = [];
|
let results = [];
|
||||||
|
|
||||||
filesystem.readdirSync(dir).forEach((file) => {
|
filesystem.readdirSync(dirPath).forEach((file) => {
|
||||||
if (file === '_notes') {
|
if (file.charAt(0) === '_') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = `${dir}/${file}`;
|
const filePath = `${dirPath}/${file}`;
|
||||||
const stat = filesystem.statSync(file);
|
const stat = filesystem.statSync(filePath);
|
||||||
|
|
||||||
if (stat && stat.isDirectory()) {
|
if (stat && stat.isDirectory() && includeSubFolders) {
|
||||||
results = results.concat(_getAllFilesFromFolder(file));
|
results = results.concat(_getAllFilesFromFolder(filePath, includeSubFolders));
|
||||||
} else {
|
} else {
|
||||||
results.push(file);
|
results.push(filePath);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
// add page specific scripts
|
||||||
|
const typesJSPath = path.join(theme, conf.TYPESJS);
|
||||||
|
if (filesystem.existsSync(typesJSPath)) {
|
||||||
|
const pageScripts = _getAllFilesFromFolder(typesJSPath, true);
|
||||||
|
pageScripts.forEach((file) => {
|
||||||
|
includes[`${themeName}_${path.basename(file, '.js')}`] = file;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// add page specific scss
|
||||||
|
const typesSCSSPath = path.join(theme, conf.TYPESSCSS);
|
||||||
|
if (filesystem.existsSync(typesSCSSPath)) {
|
||||||
|
const scssIncludes = _getAllFilesFromFolder(typesSCSSPath, true);
|
||||||
|
scssIncludes.forEach((file) => {
|
||||||
|
includes[`${themeName}_${path.basename(file, '.scss')}`] = file;
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// add page specific scripts
|
_addAppFiles(conf.APPDIR);
|
||||||
const pageScripts = _getAllFilesFromFolder(conf.TYPESJS);
|
|
||||||
pageScripts.forEach((file) => {
|
|
||||||
includes[path.basename(file, '.js')] = file;
|
|
||||||
});
|
|
||||||
|
|
||||||
// add page specific scss
|
// add themes
|
||||||
const scssIncludes = _getAllFilesFromFolder(conf.TYPESSCSS);
|
if (conf.THEMESDIR) {
|
||||||
scssIncludes.forEach((file) => {
|
const dir = path.resolve(__dirname, conf.THEMESDIR);
|
||||||
includes[path.basename(file, '.scss')] = file;
|
|
||||||
});
|
if (filesystem.existsSync(dir)) {
|
||||||
|
filesystem.readdirSync(dir).forEach((file) => {
|
||||||
|
filePath = `${dir}/${file}`;
|
||||||
|
const stat = filesystem.statSync(filePath);
|
||||||
|
|
||||||
|
if (stat && stat.isDirectory()) {
|
||||||
|
_addAppFiles(path.join(conf.THEMESDIR, file));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: includes,
|
entry: includes,
|
||||||
@ -79,14 +112,6 @@ module.exports = {
|
|||||||
}, {
|
}, {
|
||||||
test: /\.coffee?$/,
|
test: /\.coffee?$/,
|
||||||
use: 'coffee-loader',
|
use: 'coffee-loader',
|
||||||
}, {
|
|
||||||
test: /\.(png|jpg|jpeg|gif|svg)$/,
|
|
||||||
loader: 'file-loader',
|
|
||||||
options: {
|
|
||||||
name: '[name].[ext]',
|
|
||||||
outputPath: 'img/',
|
|
||||||
publicPath: '../img/',
|
|
||||||
},
|
|
||||||
}, {
|
}, {
|
||||||
test: /\.worker\.js$/,
|
test: /\.worker\.js$/,
|
||||||
use: {
|
use: {
|
||||||
@ -97,7 +122,12 @@ module.exports = {
|
|||||||
resolve: {
|
resolve: {
|
||||||
modules: [
|
modules: [
|
||||||
path.resolve(__dirname, 'public'),
|
path.resolve(__dirname, 'public'),
|
||||||
'node_modules'
|
path.resolve(__dirname, conf.APPDIR, 'client', 'src'),
|
||||||
|
path.resolve(__dirname, conf.APPDIR, 'client', 'src', 'js'),
|
||||||
|
path.resolve(__dirname, conf.APPDIR, 'client', 'src', 'scss'),
|
||||||
|
path.resolve(__dirname, conf.APPDIR, 'client', 'src', 'img'),
|
||||||
|
path.resolve(__dirname, conf.APPDIR, 'client', 'src', 'thirdparty'),
|
||||||
|
path.resolve(__dirname, 'node_modules')
|
||||||
],
|
],
|
||||||
alias: {
|
alias: {
|
||||||
'jquery': require.resolve('jquery'),
|
'jquery': require.resolve('jquery'),
|
||||||
|
@ -25,7 +25,7 @@ const config = merge.strategy({
|
|||||||
},
|
},
|
||||||
|
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, conf.DIST),
|
path: path.join(__dirname),
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
// necessary for HMR to know where to load the hot update chunks
|
// necessary for HMR to know where to load the hot update chunks
|
||||||
publicPath: 'https://' + conf.HOSTNAME + ':' + conf.PORT + '/'
|
publicPath: 'https://' + conf.HOSTNAME + ':' + conf.PORT + '/'
|
||||||
@ -80,7 +80,12 @@ const config = merge.strategy({
|
|||||||
}, {
|
}, {
|
||||||
test: /\.(gif|png|jpg|jpeg|ttf|otf|eot|svg|woff(2)?)$/,
|
test: /\.(gif|png|jpg|jpeg|ttf|otf|eot|svg|woff(2)?)$/,
|
||||||
use: [{
|
use: [{
|
||||||
loader: 'url-loader'
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name(file) {
|
||||||
|
return 'public/[path][name].[ext]';
|
||||||
|
},
|
||||||
|
},
|
||||||
}]
|
}]
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
@ -98,7 +103,9 @@ const config = merge.strategy({
|
|||||||
clientLogLevel: 'info',
|
clientLogLevel: 'info',
|
||||||
contentBase: [
|
contentBase: [
|
||||||
path.resolve(__dirname, 'public'),
|
path.resolve(__dirname, 'public'),
|
||||||
'node_modules'
|
path.resolve(__dirname, 'public', 'resources'),
|
||||||
|
path.resolve(__dirname, 'public', 'resources', conf.APPDIR, conf.DIST),
|
||||||
|
'node_modules',
|
||||||
],
|
],
|
||||||
//watchContentBase: true,
|
//watchContentBase: true,
|
||||||
overlay: {
|
overlay: {
|
||||||
@ -106,7 +113,7 @@ const config = merge.strategy({
|
|||||||
errors: true
|
errors: true
|
||||||
},
|
},
|
||||||
headers: {
|
headers: {
|
||||||
'Access-Control-Allow-Origin': '*'
|
'Access-Control-Allow-Origin': '*',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -17,9 +17,9 @@ module.exports = merge(common, {
|
|||||||
devtool: '',
|
devtool: '',
|
||||||
|
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, conf.DIST),
|
path: path.join(__dirname, conf.APPDIR, conf.DIST),
|
||||||
filename: 'js/[name].js',
|
filename: path.join('js', '[name].js'),
|
||||||
publicPath: conf.DIST + '/',
|
publicPath: path.join(conf.APPDIR, conf.DIST),
|
||||||
},
|
},
|
||||||
|
|
||||||
module: {
|
module: {
|
||||||
@ -82,7 +82,20 @@ module.exports = merge(common, {
|
|||||||
publicPath: '../fonts/'
|
publicPath: '../fonts/'
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
}]
|
}, {
|
||||||
|
test: /\.(png|jpg|jpeg|gif|svg)$/,
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[ext]',
|
||||||
|
outputPath: 'img/',
|
||||||
|
publicPath: '../img/'
|
||||||
|
/*,
|
||||||
|
name(file) {
|
||||||
|
//return 'public/[path][name].[ext]';
|
||||||
|
return '[hash].[ext]';
|
||||||
|
},*/
|
||||||
|
},
|
||||||
|
}, ]
|
||||||
},
|
},
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
@ -106,9 +119,9 @@ module.exports = merge(common, {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
new FaviconsWebpackPlugin({
|
new FaviconsWebpackPlugin({
|
||||||
logo: path.join(__dirname, conf.SRC) + '/favicon.png',
|
logo: path.join(__dirname, conf.APPDIR, conf.SRC, 'favicon.png'),
|
||||||
prefix: '/icons/',
|
prefix: '/icons/',
|
||||||
statsFilename: conf.DIST + '/icons/iconstats.json',
|
statsFilename: path.join(conf.APPDIR, conf.DIST, 'icons', 'iconstats.json'),
|
||||||
icons: {
|
icons: {
|
||||||
android: true,
|
android: true,
|
||||||
appleIcon: true,
|
appleIcon: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user