JS, code and templates updates. Noticable feature: MapBox CMS fields and MapBox frontend map

This commit is contained in:
Tony Air 2019-09-07 08:39:49 +07:00
parent b34f9c58cc
commit 3c4ce987b3
48 changed files with 662 additions and 385 deletions

View File

@ -1,3 +1,7 @@
---
Name: 'app-captcha'
---
SilverStripe\SpamProtection\Extension\FormSpamProtectionExtension:
default_spam_protector: UndefinedOffset\NoCaptcha\Forms\NocaptchaProtector
@ -10,4 +14,4 @@ UndefinedOffset\NoCaptcha\Forms\NocaptchaField:
default_size: "normal" #Default size (optional, normal, compact or invisible, defaults to normal)
default_badge: "bottomright" #Default badge position (bottomright, bottomleft or inline, defaults to bottomright)
proxy_server: "" #Your proxy server address (optional)
proxy_auth: "" #Your proxy server authentication information (optional)
proxy_auth: "" #Your proxy server authentication information (optional)

View File

@ -1,3 +1,7 @@
---
Name: 'webapp-columns'
---
Site\Extensions\ElementRows:
container_max_width: 1140
column_class: 'col-block col-md-'

View File

@ -1,5 +1,5 @@
---
Name: debugbarext
Name: 'webapp-debugbar'
After:
- 'framework'
- 'debugbar'
@ -9,4 +9,4 @@ Only:
LeKoala\DebugBar\DebugBar:
enabled_in_admin: false
query_limit: 500
max_header_length: 2048
max_header_length: 2048

View File

@ -29,6 +29,7 @@ SilverStripe\CMS\Model\SiteTree:
- DNADesign\ElementalVirtual\Model\ElementVirtual
DNADesign\ElementalList\Model\ElementList:
inline_editable: false
default_global_elements: false
allowed_elements:
- DNADesign\ElementalList\Model\ElementList
@ -46,9 +47,12 @@ DNADesign\ElementalList\Model\ElementList:
noframe: 'No Frame'
DNADesign\Elemental\Models\ElementContent:
default_global_elements: false
inline_editable: false
extensions:
- Site\Extensions\ElementContentWidget
Dynamic\Elements\Image\Elements\ElementImage:
inline_editable: false
extensions:
- Site\Extensions\ElementImageWidget

View File

@ -1,16 +1,20 @@
---
Name: webapp-extensions
---
# Basic extensions
SilverStripe\Admin\LeftAndMain:
extensions:
- Site\Extensions\LeftAndMainExtension
SilverStripe\SiteConfig\SiteConfig:
extensions:
- Site\Extensions\SiteConfigExtension
- Site\Extensions\SocialExtension
SilverStripe\SiteTree\SiteTree:
SilverStripe\CMS\Model\SiteTree:
extensions:
- Site\Extensions\SiteTreeExtension
SilverStripe\Blog\Model\BlogPost:
extensions:
- Site\Extensions\BlogPostExtension
Sheadawson\Linkable\Models\EmbeddedObject:
extensions:
- Site\Extensions\EmbeddedObjectExtension
@ -27,7 +31,7 @@ SilverStripe\Core\Injector\Injector:
Sheadawson\Linkable\Forms\EmbeddedObjectField:
class: Site\Extensions\EmbedObjectField
# User Forms
# User Forms module
SilverStripe\UserForms\Form\UserForm:
extensions:
- Site\Extensions\PlaceholderFormExtension
@ -39,3 +43,12 @@ SilverStripe\UserForms\Model\UserDefinedForm:
DNADesign\ElementalUserForms\Model\ElementForm:
extensions:
- Site\Extensions\UserDefinedFormExtension
# Blog + Widgets module extensions
Page:
extensions:
- SilverStripe\Widgets\Extensions\WidgetPageExtension
SilverStripe\Blog\Model\BlogPost:
extensions:
- Site\Extensions\BlogPostExtension

View File

@ -1,4 +0,0 @@
BetterBrief\GoogleMapField:
default_options:
api_key: 'YOUR_API_KEY'
show_search_box: true

17
app/_config/map.yml Normal file
View File

@ -0,0 +1,17 @@
---
Name: 'webapp-map'
After:
- 'silverstripe-mapboxfield'
- 'addressable'
---
SilverStripe\Core\Injector\Injector:
A2nt\SilverStripeMapboxField\MarkerExtension:
properties:
geocoder: %$Symbiote\Addressable\MapboxGeocodeService
Symbiote\Addressable\GeocodeServiceInterface:
class: Symbiote\Addressable\MapboxGeocodeService
Symbiote\Addressable\MapboxGeocodeService:
mapbox_api_key: ''
A2nt\SilverStripeMapboxField\MapboxField:
map_style: 'mapbox://styles/mapbox/streets-v9' #'mapbox://styles/mapbox/light-v10'

View File

@ -1,5 +1,5 @@
---
Name: payment
Name: 'webapp-payment'
---
SilverStripe\Omnipay\Model\Payment:
allowed_gateways:

View File

@ -1,3 +1,6 @@
---
Name: 'webapp-requirements'
---
Site\Templates\DeferedRequirements:
nojquery: false
nofontawesome: false

View File

@ -1,5 +1,5 @@
---
Name: shop
Name: 'webapp-shop'
---
SilverStripe\Core\Injector\Injector:
SilverShop\Checkout\SinglePageCheckoutComponentConfig:

View File

@ -1,5 +1,5 @@
---
Name: webapp-themes
Name: 'webapp-themes'
---
SilverStripe\View\SSViewer:

View File

@ -1,6 +1,8 @@
---
Name: 'webapp-version-truncator'
---
Axllent\VersionTruncator\VersionTruncator:
keep_versions: 4 # how many (published) versions of each page to keep
keep_drafts: 2 # how many drafts of each page to keep
keep_redirects: true # keep page versions that have a different URLSegment (for redirects)
keep_old_page_types: false # keep page versions where page type (ClassName) has changed

View File

@ -1,11 +1,11 @@
'use strict';
import $ from 'jquery';
import Events from "../_events";
import mapBoxGL from "mapbox-gl";
import Events from '../_events';
import mapBoxGL from 'mapbox-gl';
//import "./mapStorage";
import "../../scss/_components/_ui.map.scss";
import '../../scss/_components/_ui.map.scss';
const W = window;
@ -21,41 +21,45 @@ const MapAPI = (($) => {
class MapAPI {
// Constructor
constructor(element) {
this._element = element;
const $element = $(this._element);
const geojson = $element.data('geojson');
constructor(el) {
this._el = el;
const $el = $(this._el);
const config = $el.data();
const center = [
($element.data('lng') ? $element.data('lng') : $BODY.data('default-lng')),
($element.data('lat') ? $element.data('lat') : $BODY.data('default-lat')),
(config['lng'] ? config['lng'] : $BODY.data('default-lng')),
(config['lat'] ? config['lat'] : $BODY.data('default-lat')),
];
const popup = new mapboxgl.Popup({
const popup = new mapBoxGL.Popup({
closeOnClick: false,
className: 'popup',
});
currentStyle = this.getStyle();
mapBoxGL.accessToken = $element.data('key');
currentStyle = this.getStyle();
mapBoxGL.accessToken = $el.data('key');
Map = new mapBoxGL.Map({
'container': $element.find('.mapAPI-map')[0],
center,
//hash: true,
'style': currentStyle,
//localIdeographFontFamily: $BODY.css('font-family'),
'zoom': ($element.data('map-zoom') ? $element.data('map-zoom') : 10),
'attributionControl': false,
/*transformRequest: (url, resourceType)=> {
if(resourceType === 'Source' && url.startsWith('http://myHost')) {
return {
url: url.replace('http', 'https'),
headers: { 'my-custom-header': true},
credentials: 'include' // Include cookies for cross-origin requests
}
}
}*/
})
'container': $el.find('.mapAPI-map')[0],
'center': center,
//hash: true,
'style': currentStyle,
'localIdeographFontFamily': $BODY.css('font-family'),
'zoom': (config['mapZoom'] ? config['mapZoom'] : 10),
'attributionControl': false,
'antialias': true,
/*'pitch': 45,
'bearing': -17.6*/
/*transformRequest: (url, resourceType)=> {
if(resourceType === 'Source' && url.startsWith('http://myHost')) {
return {
url: url.replace('http', 'https'),
headers: { 'my-custom-header': true},
credentials: 'include' // Include cookies for cross-origin requests
}
}
}*/
})
.addControl(new mapBoxGL.AttributionControl({
compact: true,
}))
@ -66,34 +70,107 @@ const MapAPI = (($) => {
},
trackUserLocation: true,
}), 'bottom-right')
.addControl(new mapboxgl.ScaleControl({
.addControl(new mapBoxGL.ScaleControl({
maxWidth: 80,
unit: 'metric',
}), 'top-left');
}), 'top-left')
.addControl(new mapboxgl.FullscreenControl());
$el.data('Map', Map);
$el.data('Popup', popup);
// event.target
Map.on('load', (e) => {
// Insert the layer beneath any symbol layer.
if (config['3d']) {
const layers = Map.getStyle().layers;
let labelLayerId;
for (let i = 0; i < layers.length; i++) {
if (layers[i].type === 'symbol' && layers[i].layout['text-field']) {
labelLayerId = layers[i].id;
break;
}
}
Map.addLayer({
'id': '3d-buildings',
'source': 'composite',
'source-layer': 'building',
'filter': ['==', 'extrude', 'true'],
'type': 'fill-extrusion',
'minzoom': 15,
'paint': {
'fill-extrusion-color': '#aaa',
// use an 'interpolate' expression to add a smooth transition effect to the
// buildings as the user zooms in
'fill-extrusion-height': [
"interpolate", ["linear"],
["zoom"],
15, 0,
15.05, ["get", "height"]
],
'fill-extrusion-base': [
"interpolate", ["linear"],
["zoom"],
15, 0,
15.05, ["get", "min_height"]
],
'fill-extrusion-opacity': .6
}
}, labelLayerId);
}
const firstMarker = config['geojson'].features[0].geometry.coordinates;
//Map.setCenter(firstMarker);
const bounds = new mapBoxGL.LngLatBounds(firstMarker, firstMarker);
// add markers to map
geojson.features.forEach((marker) => {
// create a DOM element for the marker
const $el = $(`<div class="marker">${ marker.icon }</div>`);
config['geojson'].features.forEach((marker) => {
const id = marker.id;
const crds = marker.geometry.coordinates;
const content = marker.properties.content;
// create a DOM el for the marker
const $el = $(`<div id="Marker${ id }" data-id="${ id }" class="marker">${ marker.icon }</div>`);
$el.on('click', () => {
console.log('Marker click');
const coordinates = marker.geometry.coordinates;
const content = marker.properties.content;
console.log(popup);
popup.setLngLat(coordinates)
popup.setLngLat(crds)
.setHTML(content)
.addTo(Map);
if (config['flyToMarker']) {
Map.flyTo({
center: crds,
zoom: 17,
});
}
$el.trigger(Events.MAPMARKERCLICK);
});
// add marker to map
new mapboxgl.Marker($el[0])
.setLngLat(marker.geometry.coordinates)
new mapBoxGL.Marker($el[0])
.setLngLat(crds)
.addTo(Map);
bounds.extend(crds);
});
Map.fitBounds(bounds, {
padding: 30,
});
popup.on('close', (e) => {
if (config['flyToBounds']) {
Map.fitBounds(bounds, {
padding: 30,
});
}
$el.trigger(Events.MAPPOPUPCLOSE);
});
$el.trigger(Events.MAPLOADED);
$(W).trigger(Events.MAPLOADED);
console.log('Map is loaded');
});
@ -124,7 +201,7 @@ const MapAPI = (($) => {
}, 36000);
$element.addClass(`${NAME}-active`);
$el.addClass(`${NAME}-active`);
}
// Public methods
@ -133,36 +210,37 @@ const MapAPI = (($) => {
}
getStyle() {
const $el = $(this._el);
return $el.data('map-style');
return 'mapbox://styles/mapbox/streets-v9';
const hour = new Date().getHours();
if (hour < 6 || hour > 18) {
// night
//return 'mapbox://styles/mapbox/streets-v7';
return 'mapbox://styles/tony-air/cjeacwih92iu42rpd8tcmuyb2';
} else {
// day
return 'mapbox://styles/mapbox/streets-v9';
}
// day
return 'mapbox://styles/mapbox/streets-v9';
}
dispose() {
const $element = $(this._element);
const $el = $(this._el);
$element.removeClass(`${NAME}-active`);
$.removeData(this._element, DATA_KEY);
this._element = null;
$el.removeClass(`${NAME}-active`);
$.removeData(this._el, DATA_KEY);
this._el = null;
}
static _jQueryInterface() {
if (typeof W.localStorage !== 'undefined') {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
// attach functionality to el
const $el = $(this);
let data = $el.data(DATA_KEY);
if (!data) {
data = new MapAPI(this);
$element.data(DATA_KEY, data);
$el.data(DATA_KEY, data);
}
});
}

View File

@ -7,37 +7,37 @@ const SlidingMenu = (($) => {
class SlidingMenu {
// Constructor
constructor(element) {
this._element = element;
const $element = $(this._element);
$element.addClass(`${NAME}-active`);
constructor(el) {
const $el = $(this._el);
this.$el = $el;
$el.addClass(`${NAME}-active`);
// esc button
$(window).on('keyup',((e) => {
$(window).on('keyup', ((e) => {
if (e.which === 27) {
$element.find('.is-open[data-toggle="offcanvas"]').click();
$el.find('.is-open[data-toggle="offcanvas"]').click();
}
}));
}
// Public methods
dispose() {
console.log(`Disposing: ${NAME} elements`);
console.log(`Disposing: ${NAME} els`);
$(this._element).removeClass(`${NAME}-active`);
$.removeData(this._element, DATA_KEY);
this._element = null;
this.$el.removeClass(`${NAME}-active`);
$.removeData(this.$el, DATA_KEY);
this.$el = null;
}
static _jQueryInterface() {
return this.each(function () {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
return this.each(function() {
// attach functionality to el
const $el = $(this);
let data = $el.data(DATA_KEY);
if (!data) {
data = new SlidingMenu(this);
$element.data(DATA_KEY, data);
$el.data(DATA_KEY, data);
}
});
}
@ -46,7 +46,7 @@ const SlidingMenu = (($) => {
// jQuery interface
$.fn[NAME] = SlidingMenu._jQueryInterface;
$.fn[NAME].Constructor = SlidingMenu;
$.fn[NAME].noConflict = function () {
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return SlidingMenu._jQueryInterface;
};

View File

@ -5,6 +5,9 @@
module.exports = {
AJAX: 'ajax-load',
LOADED: 'load',
MAPLOADED: 'map-loaded',
MAPMARKERCLICK: 'map-marker-click',
MAPPOPUPCLOSE: 'map-popup-close',
SET_TARGET_UPDATE: 'set-target-update',
RESTORE_FIELD: 'restore-field',
FORM_INIT_BASICS: 'form-basics',

View File

@ -15,20 +15,40 @@ import './_components/routes/index';
import Events from './_events';
import Spinner from './_components/_ui.spinner';
// youtube video preview image
import './_components/_ui.video.preview';
import './_components/_ui.carousel';
import './_components/_ui.menu';
// Bootstrap hover menu
import './_components/_ui.hover';
import FormBasics from './_components/_ui.form.basics';
// Toggle bootstrap form fields
//import FormToggleUI from './_components/_ui.form.fields.toggle';
// Bootstrap Date & Time fields
//import FormDatetime from './_components/_ui.form.datetime';
import FormStepped from './_components/_ui.form.stepped';
// Stepped forms functionality
//import FormStepped from './_components/_ui.form.stepped';
// Forms validation functionality
import FormValidate from './_components/_ui.form.validate';
// Store forms data into localStorage
import FormStorage from './_components/_ui.form.storage';
// client-side images cropping
//import FormCroppie from './_components/_ui.form.croppie';
// AJAX functionality
import AjaxUI from './_components/_ui.ajax';
// Google NoCaptcha fields
import NoCaptcha from './_components/_ui.nocaptcha';
import SmoothScroll from 'smooth-scroll';

View File

@ -1,92 +0,0 @@
import $ from 'jquery';
const TypePage = (($) => {
// Constants
const NAME = 'TypePage';
// const DATA_KEY = "pageUI." + NAME;
const Events = require('./_events');
class TypePage {
// Static methods
static init() {
console.log(`Initializing: ${NAME}`);
}
static destroy() {
console.log(`Destroying: ${NAME}`);
}
/**
* jQuery extension functions
// Constructor
constructor(element) {
console.log("Constructing: " + NAME + " elements");
this._element = element;
}
// Public methods
dispose() {
console.log("Disposing: " + NAME + " elements");
$.removeData(this._element, DATA_KEY);
this._element = null;
}
static _jQueryInterface() {
return this.each(function () {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) {
data = new TypePage(this);
$element.data(DATA_KEY, data);
}
})
}
*/
}
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
TypePage.init();
});
// JQuery extension functions
/*
$.fn[NAME] = TypePage._jQueryInterface;
$.fn[NAME].Constructor = TypePage;
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return TypePage._jQueryInterface;
};
// auto-apply
$(".ui." + NAME).ready(function(){
$(".ui." + NAME).TypePage();
}); */
return TypePage;
})($);
export default TypePage;
/*
import $ from 'jquery';
(function (G) {
G.initPulsePage = function () {
G.destroyPulsePage();
};
G.destroyPulsePage = function () {};
$(window).on("ajax-content-loaded", function () {
G.initPulsePage();
});
$(document).ready(function () {
G.initPulsePage();
});
}(this)); */

View File

@ -7,10 +7,7 @@ import 'bootstrap/js/dist/alert';
import 'bootstrap/js/dist/button';
import 'bootstrap/js/dist/carousel';
import 'bootstrap/js/dist/collapse';
// conflicting with bootstrap-select/dist/js/bootstrap-select
import 'bootstrap/js/dist/dropdown';
import 'bootstrap/js/dist/modal';
import 'bootstrap/js/dist/tooltip';
import 'bootstrap/js/dist/popover';
@ -18,14 +15,12 @@ import 'bootstrap/js/dist/scrollspy';
import 'bootstrap/js/dist/tab';
//
//import Vue from 'vue/dist/vue.esm.js';
// import Bootstrap-Vue
/*import { Carousel } from 'bootstrap-vue/es/components';
Vue.use(Carousel);*/
// Offcanvas menu
import 'offcanvas-bootstrap/dist/js/bootstrap.offcanvas';
import 'jquery-zoom/jquery.zoom';
// Uncomment it to enable meta-lightbox zooming on hover
//import 'jquery-zoom/jquery.zoom';
import 'meta-lightbox/meta-lightbox';
import './_main';

View File

@ -146,22 +146,36 @@ button, input, optgroup, select, textarea,
}
// dropdown hover
/*
.dropdown.show {
.dropdown {
&:hover,
&:focus {
.dropdown-menu {
display: block;
}
}
}
}
@media only screen and (min-width: map-get($grid-breakpoints, "md")) {
.dropdown-hover .collapse ul li {
.dropdown-hover ul li {
position: relative;
}
.dropdown-hover .collapse ul li:hover {
> .dropdown-toggle::after {
transform: rotate(-90deg);
}
.dropdown-hover ul li {
&:hover,
&:focus {
> .dropdown-toggle::after {
transform: rotate(-90deg);
}
> ul {
display: block;
> ul {
display: block;
}
}
}
.dropdown-hover .collapse ul ul {
.dropdown-hover ul ul {
position: absolute;
top: 100%;
left: 0;
@ -169,16 +183,20 @@ button, input, optgroup, select, textarea,
display: none;
}
/*******/
.dropdown-hover .collapse ul ul li {
.dropdown-hover ul ul li {
position: relative;
}
.dropdown-hover .collapse ul ul li:hover > ul {
display: block;
.dropdown-hover ul ul li {
&:hover,
&:focus {
> ul {
display: block;
}
}
}
.dropdown-hover .collapse ul ul ul {
.dropdown-hover ul ul ul {
position: absolute;
top: 0;
left: 100%;
@ -186,16 +204,20 @@ button, input, optgroup, select, textarea,
display: none;
}
/*******/
.dropdown-hover .collapse ul ul ul li {
.dropdown-hover ul ul ul li {
position: relative;
}
.dropdown-hover .collapse ul ul ul li:hover ul {
display: block;
.dropdown-hover ul ul ul li {
&:hover,
&:focus {
ul {
display: block;
}
}
}
.dropdown-hover .collapse ul ul ul ul {
.dropdown-hover ul ul ul ul {
position: absolute;
top: 0;
left: -100%;
@ -203,9 +225,28 @@ button, input, optgroup, select, textarea,
display: none;
z-index: 1;
}
}
}*/
// dark dropdowns
.navbar-dark {
.nav-link {
@include hover-focus {
background: $navbar-dark-hover-background;
}
}
.active > .nav-link,
.nav-link.active {
background: $navbar-dark-active-background;
}
.nav-link.show,
.navbar-nav .show > .nav-link {
background: $navbar-dark-show-background;
color: $navbar-dark-show-color;
}
}
.dropdown-menu.bg-dark {
border-color: $dark;
@ -231,8 +272,37 @@ button, input, optgroup, select, textarea,
.dropdown-item {
@include hover-focus {
color: $navbar-dark-brand-hover-color;
background: $dark;
color: $navbar-dark-hover-color;
background: $navbar-dark-hover-background;
}
&.active,
&:active {
background: $navbar-dark-active-background;
}
.nav-link {
background: none;
}
}
}
// pulse
.pulse {
animation: pulse 0.8s linear infinite;
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(0.8);
}
100% {
transform: scale(1);
}
}

View File

@ -6,10 +6,30 @@
margin-bottom: 1rem;
}
.mapboxgl-popup-content {
box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.4);
.mapboxgl-popup-close-button {
font-size: 2rem;
padding: .5rem;
&:hover,
&:focus {
background: $primary;
color: $white;
}
}
}
.mapboxgl-marker {
width: 30px;
height: 30px;
font-size: 30px;
cursor: pointer;
text-align: center;
color: $primary;
.fas {
animation: pulse 0.8s linear infinite;
}
}

View File

@ -55,6 +55,10 @@ body.shrink {}
}
}
&.dynamic__elements__image__elements__elementimage {
text-align: center;
}
&.site__elements__accordion {
.card {
padding-left: 0;

View File

@ -4,14 +4,16 @@ h1, h2, h3, h4, h5, h6,
}
.bg-dark {
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6,
.typography,
a {
color: $white;
}
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6,
.typography,
a {
color: $white;
}
}
.typography {
@include clearfix;
@import "./types/editor";
}

View File

@ -8,7 +8,6 @@
namespace Site\Extensions;
use Sheadawson\Linkable\Forms\LinkField;
use Sheadawson\Linkable\Models\Link;
use SilverStripe\FontAwesome\FontAwesomeField;
@ -29,13 +28,9 @@ class ElementContentWidget extends DataExtension
{
parent::updateCMSFields($fields);
$tab = $fields->findOrMakeTab('Root.Main');
$tab->push(
FontAwesomeField::create('BlockIcon')
);
$tab->push(
LinkField::create('BlockLinkID', 'Link')
);
$fields->addFieldsToTab('Root.Main', [
FontAwesomeField::create('BlockIcon'),
LinkField::create('BlockLinkID', 'Link'),
]);
}
}
}

View File

@ -12,6 +12,7 @@ use Dynamic\Elements\Image\Elements\ElementImage;
use Sheadawson\Linkable\Forms\LinkField;
use Sheadawson\Linkable\Models\Link;
use SilverStripe\Core\Config\Config;
use SilverStripe\Forms\CheckboxField;
use SilverStripe\Forms\DropdownField;
use SilverStripe\Forms\FieldList;
use SilverStripe\ORM\DataExtension;
@ -25,6 +26,7 @@ class ElementImageWidget extends DataExtension
];
private static $db = [
'Resize' => 'Boolean(1)',
'ImageHeight' => 'Float',
'Content' => 'HTMLText',
];
@ -45,6 +47,12 @@ class ElementImageWidget extends DataExtension
$this->owner->ImageHeight = $this->getHeight();
$heights = Config::inst()->get(__CLASS__, 'available_heights');
$fields->replaceField('Resize', CheckboxField::create(
'Resize',
'Would you like to scale image?'
));
if (count($heights)) {
$fields->replaceField(
'ImageHeight',
@ -53,7 +61,9 @@ class ElementImageWidget extends DataExtension
'Image Height',
$heights,
$this->getHeight()
)->setEmptyString('(unspecified)')
)
->setEmptyString('(unspecified)')
->displayIf('Resize')->isChecked()->end()
);
} else {
$fields->dataFieldByName('ImageHeight')
@ -64,6 +74,11 @@ class ElementImageWidget extends DataExtension
public function ImageResized()
{
$image = $this->owner->Image();
if (!$this->owner->Resize) {
return $image;
}
$width = $this->getWidth();
$height = $this->getHeight();

View File

@ -0,0 +1,13 @@
<?php
namespace Site\Extensions;
use SilverStripe\Core\Extension;
class LeftAndMainExtension extends Extension
{
public function init()
{
}
}

View File

@ -13,16 +13,17 @@ use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TreeMultiselectField;
use SilverStripe\Forms\DropdownField;
use BetterBrief\GoogleMapField;
//use BetterBrief\GoogleMapField;
use Bigfork\SilverStripeMapboxField\MapboxField;
class SiteConfigExtension extends DataExtension
{
private static $db = [
'ExtraCode' => 'Text',
'Longitude' => 'Varchar(255)',
'Latitude' => 'Varchar(255)',
'Longitude' => 'Decimal(10, 8)',
'Latitude' => 'Decimal(11, 8)',
'MapZoom' => 'Int',
'MapAPIKey' => 'Varchar(255)',
//'MapAPIKey' => 'Varchar(255)',
'Description' => 'Varchar(255)',
];
@ -37,40 +38,49 @@ class SiteConfigExtension extends DataExtension
public function updateCMSFields(FieldList $fields)
{
$tab = $fields->findOrMakeTab('Root.Main');
$fields->addFieldsToTab('Root.Main', [
TreeMultiselectField::create(
'Navigation',
'Navigation',
SiteTree::class
),
TextareaField::create('Description', 'Website Description'),
TextareaField::create('ExtraCode', 'Extra site-wide HTML code'),
DropdownField::create(
'PrivacyPolicyID',
'Privacy Policy Page',
SiteTree::get()->map()->toArray()
),
DropdownField::create(
'SitemapID',
'Sitemap Page',
SitemapPage::get()->map()->toArray()
),
]);
$tab->push(TreeMultiselectField::create(
'Navigation',
'Navigation',
SiteTree::class
));
$tab->push(TextareaField::create('ExtraCode', 'Extra site-wide HTML code'));
$tab->push(DropdownField::create(
'PrivacyPolicyID',
'Privacy Policy Page',
SiteTree::get()->map()->toArray()
));
$tab->push(DropdownField::create(
'SitemapID',
'Sitemap Page',
SitemapPage::get()->map()->toArray()
));
$tab->push(TextareaField::create('Description', 'Website Description'));
$mapTab = $fields->findOrMakeTab('Root.GoogleMaps');
$mapTab->push(TextField::create('MapAPIKey'));
$mapTab->push(TextField::create('MapZoom'));
$mapTab->push(GoogleMapField::create(
$mapTab = $fields->findOrMakeTab('Root.Maps');
$fields->addFieldsToTab('Root.Maps', [
//TextField::create('MapAPIKey'),
TextField::create('MapZoom'),
MapboxField::create('Map', 'Choose a location', 'Latitude', 'Longitude'),
]);
/*GoogleMapField::create(
$this->owner,
'Location',
[
'show_search_box' => true,
]
));
)*/
}
public function MapAPIKey()
{
return MapboxField::config()->get('access_token');
}
public function MapStyle()
{
return MapboxField::config()->get('map_style');
}
public function getGeoJSON()

View File

@ -18,11 +18,11 @@ class SiteTreeExtension extends DataExtension
public function updateCMSFields(FieldList $fields)
{
$tab = $fields->findOrMakeTab('Root.Settings');
$tab->push(Textarea::create(
'ExtraCode',
'Extra page specific HTML code'
));
$fields->addFieldsToTab('Root.Settings', [
TextareaField::create(
'ExtraCode',
'Extra page specific HTML code'
),
]);
}
}

View File

@ -38,4 +38,9 @@ class Page extends SiteTree
return false;
}
public function CSSClass()
{
return str_replace(['\\'], '-', $this->getField('ClassName'));
}
}

View File

@ -1,16 +1,21 @@
<% if $Pages %>
<nav class="breadcrumbs"><ul>
<li>
<a href="/">Home</a>
$Delimiter.RAW
</li>
<% loop $Pages %>
<li<% if $Last %> class="current"<% end_if %>>
<% if not Up.Unlinked %><a href="$Link" class="breadcrumb-$Pos"><% end_if %>
$MenuTitle.XML
<% if not Up.Unlinked %></a><% end_if %>
$Up.Delimiter.RAW
<nav class="breadcrumbs $DefaultContainer" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/">Home</a>
<%-- $Delimiter.RAW --%>
</li>
<% end_loop %>
</ul></nav>
<% loop $Pages %>
<li
class="breadcrumb-item<% if $Last %> current active<% end_if %>"
<% if $Last %> aria-current="page"<% end_if %>
>
<% if not Up.Unlinked %><a href="$Link" class="breadcrumb-$Pos"><% end_if %>
$MenuTitle.XML
<% if not Up.Unlinked %></a><% end_if %>
<%-- if not $Last %>$Up.Delimiter.RAW<% end_if --%>
</li>
<% end_loop %>
</ol>
</nav>
<% end_if %>

View File

@ -1,11 +1,12 @@
<% if $ImageResized %>
<div class="image-element__image<% if $Height %> height{$Height}<% end_if %><% if $Width %> width{$Width}<% 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 %>
<img src="$ImageResized.URL" class="img-responsive" alt="$Title.ATT">
<img src="$ImageResized.URL" class="img-responsive" alt="$Title.ATT" />
<% if $ImageLink %></a><% end_if %>
</div>
<% end_if %>
<% if $ShowTitle || $Content || $ImageLink %>
<div class="image-element__caption img-content">
<div class="container">
<% if $ShowTitle %><h3 class="image-element__title title">$Title</h3><% end_if %>
@ -21,4 +22,5 @@
</a>
<% end_if %>
</div>
</div>
</div>
<% end_if %>

View File

@ -1,5 +1,5 @@
<div class="page-content">
<h1 class="page-header container<% if $ElementalArea.Elements.Count < 1 %> no-elements<% end_if %>">$Title</h1>
<h1 class="page-header $DefaultContainer<% if $ElementalArea.Elements.Count < 1 %> no-elements<% end_if %>">$Title</h1>
<div class="page-content">
<% if $CurrentElement %>

View File

@ -1,5 +1,5 @@
<% if $Children %>
<li class="nav-item dropdown<% if $isCurrent || $isSection %> active <% end_if %>{$ExtraClass}">
<li class="nav-item dropdown<% if $isCurrent || $isSection %> active <% end_if %> {$CSSClass} {$ExtraClass}">
<a
class="nav-link dropdown-toggle"
id="NavItem{$ID}"
@ -21,7 +21,7 @@
</ul>
</li>
<% else %>
<li class="nav-item $ExtraClass <% if $isCurrent || $isSection %> active<% end_if %>">
<li class="nav-item {$CSSClass} $ExtraClass <% if $isCurrent || $isSection %> active<% end_if %>">
<a class="nav-link" href="{$Link}" title="$Title.XML">
$MenuTitle.XML
<% if $isCurrent || $isSection %><i class="sr-only">(current)</i><% end_if %>

View File

@ -1,4 +1,4 @@
<style>
body,html{font-size:14px;margin:0;padding:0;background:#fff;color:#333}#PageLoading{position:fixed;left:0;top:0;margin:0;width:100%!important;height:100%!important;background:rgba(255,255,255,.9);display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;z-index:9999}.main-bn{position:fixed;top:0;left:0;width:100%;z-index:99999999;padding:0.5rem 1rem;text-align:center;color:#fff;background:#FF0000}.loading-spinner{text-align:center}
body,html{font-size:14px;margin:0;padding:0;background:#fff;color:#333}#PageLoading{position:fixed;left:0;top:0;margin:0;width:100%!important;height:100%!important;background:rgba(255,255,255,.9);display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;z-index:9999}.main-bn{position:fixed;top:0;left:0;width:100%;z-index:99999999;padding:0.5rem 1rem;text-align:center;color:#fff;background:#FF0000}img,iframe{max-width:100%}.loading-spinner{text-align:center}
.lds-ellipsis{display:inline-block;position:relative;width:64px;height:64px}.lds-ellipsis div{position:absolute;top:27px;width:11px;height:11px;border-radius:50%;background:#888;animation-timing-function:cubic-bezier(0, 1, 1, 0)}.lds-ellipsis div:nth-child(1){left:6px;animation:lds-ellipsis1 0.6s infinite}.lds-ellipsis div:nth-child(2){left:6px;animation:lds-ellipsis2 0.6s infinite}.lds-ellipsis div:nth-child(3){left:26px;animation:lds-ellipsis2 0.6s infinite}.lds-ellipsis div:nth-child(4){left:45px;animation:lds-ellipsis3 0.6s infinite}@keyframes lds-ellipsis1{0%{transform:scale(0)}100%{transform:scale(1)}}@keyframes lds-ellipsis3{0%{transform:scale(1)}100%{transform:scale(0)}}@keyframes lds-ellipsis2{0%{transform:translate(0, 0)}100%{transform:translate(19px, 0)}}
</style>

View File

@ -1,3 +1,3 @@
<div id="PageContainer" class="page{$ClassName} action{$Action}">
<div id="PageContainer" class="page{$CSSClass} action{$Action}">
<% include Content %>
</div>
</div>

View File

@ -1,5 +1,5 @@
<% with $SearchResults %>
<div id="PageContainer" class="page action{$Action}">
<div id="PageContainer" class="page{$CSSClass} pageSearch action{$Action}">
<div class="page-content">
<h1 class="page-header container no-elements">$Title</h1>

View File

@ -1,7 +1,11 @@
<div class="mapAPI-map-container" data-map-zoom="$MapZoom" data-key="$MapAPIKey" data-geojson="$GeoJSON.XML">
<div
class="mapAPI-map-container"
data-map-zoom="$MapZoom"
data-key="<% if $MapAPIKey %>$MapAPIKey<% else %>$SiteConfig.MapAPIKey<% end_if %>"
data-map-style="<% if $MapStyle %>$MapStyle<% else %>$SiteConfig.MapStyle<% end_if %>"
data-geojson="$GeoJSON.XML"
data-fly-to-marker="true"
data-fly-to-bounds="false"
>
<div class="mapAPI-map"></div>
<div class="text-right">
$DirectionsLink.RAW
</div>
</div>
</div>

View File

@ -14,7 +14,30 @@
</header>
<main id="MainContent" data-ajax-region="LayoutAjax">
$Layout
<% if $ParentID %>
$Breadcrumbs
<% end_if %>
<% if $SideBarView || $Parent.SideBarView %>
<div class="$DefaultContainer">
<div class="row">
<div class="col-md-8">
$Layout
</div>
<div class="col-md-4">
<div class="page-content">
<% if $SideBarView %>
$SideBarView
<% else %>
$Parent.SideBarView
<% end_if %>
</div>
</div>
</div>
</div>
<% else %>
$Layout
<% end_if %>
</main>
</div>

View File

@ -1,4 +1,4 @@
<div id="PageContainer" class="page{$ClassName} action{$Action}">
<div id="PageContainer" class="page{$CSSClass} action{$Action}">
<% include Content %>
<div class="page-content">
@ -23,7 +23,7 @@
<% if $PaginatedList.Exists %>
<div class="row">
<% loop $PaginatedList %>
<div class="col-sm-4">
<div class="col-sm-3 col-md-3">
<% include BlogPostInfo %>
</div>
<% end_loop %>
@ -42,4 +42,4 @@
</div>
</div>
<% include SilverStripe\\Blog\\BlogSideBar %>
<%-- include SilverStripe\\Blog\\BlogSideBar --%>

View File

@ -1,4 +1,4 @@
<div id="PageContainer" class="page{$ClassName} action{$Action}">
<div id="PageContainer" class="page{$CSSClass} action{$Action}">
<article class="blog-entry">
<% if $FeaturedImage %>
@ -31,4 +31,4 @@
<% end_if %>
</div>
<% include SilverStripe\\Blog\\BlogSideBar %>
<%-- include SilverStripe\\Blog\\BlogSideBar --%>

View File

@ -0,0 +1,11 @@
<% if $Categories %>
<ul class="list-unstyled list-inline">
<% loop $Categories %>
<li class="list-inline-item">
<a href="$Link" title="$Title" class="btn btn-secondary">
<span class="text">$Title</span>
</a>
</li>
<% end_loop %>
</ul>
<% end_if %>

View File

@ -0,0 +1,11 @@
<% if $Posts %>
<ul class="list-unstyled">
<% loop $Posts %>
<li>
<a href="$Link" title="$Title">
<span class="text">$Title</span>
</a>
</li>
<% end_loop %>
</ul>
<% end_if %>

View File

@ -0,0 +1,11 @@
<% if $Tags %>
<ul class="list-unstyled list-inline">
<% loop $Tags %>
<li class="list-inline-item">
<a href="$Link" title="$Title" class="btn btn-secondary">
<span class="text">$Title</span>
</a>
</li>
<% end_loop %>
</ul>
<% end_if %>

View File

@ -1,5 +1,12 @@
<% if $ShowTitle %>
<h2 class="slider-element__title text-center">$Title</h2>
<% if $ShowTitle || $Content %>
<div class="slider-caption">
<% if $ShowTitle %>
<h2 class="slider-element__title text-center">$Title</h2>
<% end_if %>
<% if $Content %>
<div class="slider-element__content typography text-center">$Content</div>
<% end_if %>
</div>
<% end_if %>
<% if $SlideShow %>

View File

@ -0,0 +1,4 @@
<nav class="secondary element">
<% if $Title %><h2 class="widget-title">$Title</h2><% end_if %>
$Content
</nav>

View File

@ -1,71 +1,74 @@
{
"name": "silverstripe/installer",
"type": "silverstripe-recipe",
"description": "The SilverStripe Framework Installer",
"require": {
"php": ">=7.1.0",
"silverstripe/recipe-cms": "^4",
"wilr/silverstripe-googlesitemaps": "*",
"silverstripe/userforms": "*",
"undefinedoffset/sortablegridfield": "*",
"silverstripe/spamprotection": "*",
"silverstripe/recaptcha": "*",
"jonom/silverstripe-betternavigator": "*",
"silverstripe/externallinks": "*",
"symbiote/silverstripe-gridfieldextensions": "*",
"colymba/gridfield-bulk-editing-tools": "^3",
"dnadesign/silverstripe-elemental-list": "*",
"dnadesign/silverstripe-elemental-virtual": "*",
"dnadesign/silverstripe-elemental-userforms": "*",
"dynamic/silverstripe-elemental-blocks": "*",
"drmartingonzo/ss-tinymce-charcount": "*",
"axllent/silverstripe-version-truncator": "*",
"firesphere/googlemapsfield": "*",
"gorriecoe/silverstripe-dataobjecthistory": "*",
"axllent/silverstripe-bootstrap-forms": "*",
"silverstripe/redirectedurls": "*",
"undefinedoffset/silverstripe-nocaptcha": "*",
"a2nt/silverstripe-font-awesome-field": "dev-master",
"stevie-mayhew/silverstripe-svg": "*",
"betterbrief/silverstripe-googlemapfield": "*",
"innoweb/silverstripe-sitemap": "*",
"silverstripe/multiuser-editing-alert": "*",
"gorriecoe/silverstripe-link": "*",
"gorriecoe/silverstripe-linkfield": "*",
"silverstripe/environmentcheck": "*"
},
"require-dev": {
"phpunit/phpunit": "^5.7",
"lekoala/silverstripe-debugbar": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/a2nt/silverstripe-font-awesome"
}
"name": "silverstripe/installer",
"type": "silverstripe-recipe",
"description": "The SilverStripe Framework Installer",
"require": {
"php": ">=7.1.0",
"ext-json": "*",
"silverstripe/recipe-cms": "^4",
"wilr/silverstripe-googlesitemaps": "*",
"silverstripe/userforms": "*",
"undefinedoffset/sortablegridfield": "*",
"silverstripe/spamprotection": "*",
"silverstripe/recaptcha": "*",
"jonom/silverstripe-betternavigator": "*",
"silverstripe/externallinks": "*",
"symbiote/silverstripe-gridfieldextensions": "*",
"colymba/gridfield-bulk-editing-tools": "^3",
"dnadesign/silverstripe-elemental-list": "*",
"dnadesign/silverstripe-elemental-virtual": "*",
"dnadesign/silverstripe-elemental-userforms": "*",
"dynamic/silverstripe-elemental-blocks": "*",
"drmartingonzo/ss-tinymce-charcount": "*",
"axllent/silverstripe-version-truncator": "*",
"gorriecoe/silverstripe-dataobjecthistory": "*",
"axllent/silverstripe-bootstrap-forms": "*",
"silverstripe/redirectedurls": "*",
"undefinedoffset/silverstripe-nocaptcha": "*",
"stevie-mayhew/silverstripe-svg": "*",
"betterbrief/silverstripe-googlemapfield": "*",
"innoweb/silverstripe-sitemap": "*",
"silverstripe/multiuser-editing-alert": "*",
"gorriecoe/silverstripe-link": "*",
"gorriecoe/silverstripe-linkfield": "*",
"silverstripe/environmentcheck": "*",
"silverstripe/widgets": "^2.0",
"a2nt/silverstripe-font-awesome-field": "dev-master",
"a2nt/silverstripe-mapboxfield": "dev-master"
},
"require-dev": {
"phpunit/phpunit": "^5.7",
"lekoala/silverstripe-debugbar": "dev-master"
},
"repositories": [{
"type": "vcs",
"url": "https://github.com/a2nt/silverstripe-font-awesome"
}, {
"type": "vcs",
"url": "https://github.com/a2nt/silverstripe-mapboxfield"
}],
"extra": {
"expose": [
"app/client/dist"
],
"extra": {
"expose": [
"app/client/dist"
],
"project-files-installed": [
"app/.htaccess",
"app/_config.php",
"app/_config/mysite.yml",
"app/src/Page.php",
"app/src/PageController.php"
],
"public-files-installed": [
".htaccess",
"index.php",
"install-frameworkmissing.html",
"install.php",
"web.config"
]
},
"config": {
"process-timeout": 600
},
"prefer-stable": true,
"minimum-stability": "dev"
"project-files-installed": [
"app/.htaccess",
"app/_config.php",
"app/_config/mysite.yml",
"app/src/Page.php",
"app/src/PageController.php"
],
"public-files-installed": [
".htaccess",
"index.php",
"install-frameworkmissing.html",
"install.php",
"web.config"
]
},
"config": {
"process-timeout": 600
},
"prefer-stable": true,
"minimum-stability": "dev"
}

View File

@ -42,6 +42,7 @@
"jquery-zoom": "^1.7.21",
"jquery.appear": "^1.0.1",
"jquery.inputmask": "^3.3.4",
"jquery-hoverintent": "*",
"mapbox-gl": "^1.2.1",
"meta-lightbox": "^1.0.0",
"offcanvas-bootstrap": "^2.5.2",

View File

@ -0,0 +1 @@
DELETE themes folder in case u don't have any themes

View File

@ -6,17 +6,7 @@
</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 %>
<% include First %>
<div class="wrapper">
<header id="Header" class="container">
@ -24,11 +14,34 @@
</header>
<main id="MainContent" data-ajax-region="LayoutAjax">
$Layout
<% if $ParentID %>
$Breadcrumbs
<% end_if %>
<% if $SideBarView || $Parent.SideBarView %>
<div class="$DefaultContainer">
<div class="row">
<div class="col-md-8">
$Layout
</div>
<div class="col-md-4">
<div class="page-content">
<% if $SideBarView %>
$SideBarView
<% else %>
$Parent.SideBarView
<% end_if %>
</div>
</div>
</div>
</div>
<% else %>
$Layout
<% end_if %>
</main>
</div>
<footer id="Footer" class="site-footer">
<footer id="Footer" class="site-footer footer">
<% include Footer %>
</footer>
@ -37,13 +50,13 @@
</div>
<%-- Require CSS+JS from /public/resourses/[js,css]/[ClassName].[js,css] --%>
$AutoRequirements($ClassName).RAW
$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 --%>
<%-- place extra requirements after this line --%>
<div class="extra-code extra-code-site">
$SiteConfig.ExtraCode
</div>