Big commit i'm sorry ...
This commit is contained in:
12
app/forms.py
12
app/forms.py
@@ -7,14 +7,15 @@ from wtforms import validators
|
||||
from wtforms.validators import DataRequired, Length
|
||||
|
||||
class FormBloc(FlaskForm):
|
||||
title = StringField('Titre', validators=[DataRequired()])
|
||||
name = StringField('Nom du bloc', validators=[DataRequired()])
|
||||
title = StringField('Titre', validators=[])
|
||||
subtitle = StringField('Sous-titre', validators=[])
|
||||
property = StringField('Classes CSS', validators=[])
|
||||
bg_color = ColorField('Couleur de fond', validators=[])
|
||||
fg_color = ColorField('Couleur du texte', validators=[])
|
||||
text = TextAreaField('Présentation', validators=[Length(min=0, max=1000)])
|
||||
text = TextAreaField('Présentation', validators=[Length(min=0, max=30000)])
|
||||
text_button = StringField('Texte du bouton', validators=[])
|
||||
link = StringField('Lien', validators=[])
|
||||
image = FileField('image', validators=[FileAllowed(['jpg', 'png', 'gif'], 'Images only!')])
|
||||
image = FileField('image', validators=[FileAllowed(['jpg','jpeg','png'])])
|
||||
email = StringField('Email', validators=[])
|
||||
phone = StringField('Téléphone', validators=[])
|
||||
address = StringField('Addresse', validators=[])
|
||||
@@ -35,8 +36,7 @@ class ImageUpload(FlaskForm):
|
||||
subtitle = StringField('Sous-titre',validators=[])
|
||||
text = StringField('Une description de votre image', validators=[])
|
||||
category = StringField('Categories',validators=[])
|
||||
image = FileField('image', validators=[FileRequired(),
|
||||
FileAllowed(['jpg', 'png', 'gif'], 'Images only!')])
|
||||
image = FileField('image', validators=[FileAllowed(['jpg', 'png', 'gif'], 'Images only!')])
|
||||
|
||||
class Login(FlaskForm):
|
||||
login = StringField('Votre identifiant', validators=[DataRequired()])
|
||||
|
||||
@@ -4,13 +4,15 @@ from werkzeug.utils import secure_filename
|
||||
from app.forms import *
|
||||
from PIL import Image
|
||||
from os import remove, path
|
||||
from pathlib import Path, PurePath, PurePosixPath
|
||||
|
||||
|
||||
|
||||
class MyBlocs:
|
||||
|
||||
def new(blocName, blocType):
|
||||
def new(blocName, blocType, theme):
|
||||
mybloc = None
|
||||
if blocType in MyBlocs.listTypeBlocs():
|
||||
if blocType in MyBlocs.listTypeBlocs(theme):
|
||||
mybloc=dict()
|
||||
mybloc['name'] = str(blocName)
|
||||
mybloc['type'] = str(blocType)
|
||||
@@ -26,4 +28,13 @@ class MyBlocs:
|
||||
def newImgForm():
|
||||
return ImageUpload()
|
||||
|
||||
def listTypeBlocs(theme):
|
||||
typeBlocs = list()
|
||||
folders = Path(PurePosixPath('./app').joinpath('templates', theme, 'blocs'))
|
||||
for folder in folders.iterdir():
|
||||
if not(folder.is_dir()):
|
||||
typeBloc=folder.name.split('.')[0]
|
||||
typeBlocs.append(typeBloc[1:])
|
||||
|
||||
return typeBlocs
|
||||
|
||||
|
||||
@@ -3,105 +3,179 @@ import os
|
||||
from werkzeug.utils import secure_filename
|
||||
from app.forms import *
|
||||
from PIL import Image
|
||||
from os import remove, path
|
||||
|
||||
from pathlib import Path, PurePath, PurePosixPath
|
||||
|
||||
class DataSite:
|
||||
|
||||
datas = ""
|
||||
static_path = ""
|
||||
user_folder = None
|
||||
username = str()
|
||||
datas = str()
|
||||
static_path = None
|
||||
trash = list()
|
||||
filej= ""
|
||||
filej= None
|
||||
|
||||
def __init__(self, username, users_folder ):
|
||||
self.filej = os.path.join(users_folder, username,'ident.json')
|
||||
def __init__(self, username :str , users_folder :str ):
|
||||
self.username = username
|
||||
self.user_folder = PurePosixPath(users_folder).joinpath(username)
|
||||
self.filej = Path(PurePosixPath(self.user_folder).joinpath('ident.json'))
|
||||
|
||||
with open(self.filej, 'r') as f:
|
||||
|
||||
with self.filej.open(newline='', mode='r', encoding='utf-8') as f:
|
||||
self.datas = json.load(f)
|
||||
self.static_path = os.path.join(users_folder, username, 'public')
|
||||
self.static_path = Path(PurePosixPath(self.user_folder.joinpath('public')))
|
||||
self.static_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def loadFile(self):
|
||||
with open(self.filej, 'r') as f:
|
||||
self.datas = json.load(f)
|
||||
if not self.filej.isfile():
|
||||
raise FileNotFoundError(f"Le fichier ident.json n'existe pas : {self.filej}")
|
||||
|
||||
def loadFile_tmp(self):
|
||||
with open(self.filej_tmp, 'r') as f:
|
||||
with self.filej.open(newline='', mode='r', encoding='utf-8') as f:
|
||||
self.datas = json.load(f)
|
||||
|
||||
|
||||
def updateBloc(bloc, form):
|
||||
bloc['name'] = form.name.data
|
||||
bloc['bg_color'] = form.bg_color.data
|
||||
bloc['fg_color']=form.fg_color.data
|
||||
bloc['title'] = form.title.data
|
||||
bloc['text'] = form.text.data
|
||||
bloc['text_button']=form.text_button.data
|
||||
bloc['link'] = form.link.data
|
||||
if form.image.data :
|
||||
f=form.image.data
|
||||
filename = secure_filename(f.filename)
|
||||
extension = filename.rsplit('.', 1)[1].lower()
|
||||
f.save(os.path.join(
|
||||
self.static_path, 'img','bg_custom.'+ extension))
|
||||
|
||||
bloc['bg_img']='bg_custom.'+extension
|
||||
bloc['email'] = form.email.data
|
||||
bloc['address']=form.address.data
|
||||
bloc['phone'] = form.phone.data
|
||||
bloc['postal_code'] = form.postal_code.data
|
||||
bloc['city'] = form.city.data
|
||||
|
||||
def getBlocs(self, page: str):
|
||||
|
||||
if page != '':
|
||||
page = Path(self.user_folder.joinpath(page, 'page.json'))
|
||||
datas = ""
|
||||
if not page.exists():
|
||||
raise FileNotFoundError(f"Le fichier page.json n'existe pas : {page}")
|
||||
|
||||
datas = json.loads(page.read_text())
|
||||
else:
|
||||
datas = self.datas
|
||||
|
||||
return datas
|
||||
|
||||
|
||||
def updateBloc(self, bloc, form, files=None):
|
||||
print (form)
|
||||
for field in form():
|
||||
print(field)
|
||||
|
||||
if files != None:
|
||||
f = files['image']
|
||||
filename = secure_filename(f.filename)
|
||||
extension = filename.rsplit('.', 1)[1].lower()
|
||||
bg_custom = 'bg_custom_'+bloc['name']+'.'+extension
|
||||
f.save(PurePath.joinpath(
|
||||
self.static_path, 'img', bg_custom))
|
||||
|
||||
bloc['bg_img'] = bg_custom
|
||||
|
||||
return bloc
|
||||
|
||||
def updateImg(self, bloc, img, form):
|
||||
filename = img['file']
|
||||
def updateImg(self, image, form):
|
||||
img = dict()
|
||||
img['title'] = form.title.data
|
||||
img['subtitle'] = form.subtitle.data
|
||||
img['description'] = form.description.data
|
||||
img['category'] = form.category.data
|
||||
self.datas['blocs'][bloc][filename]=img
|
||||
img['file'] = image
|
||||
return img
|
||||
|
||||
def updateImg_tmp(self, bloc, img, form):
|
||||
filename = img['file']
|
||||
img['title'] = form.title.data
|
||||
img['subtitle'] = form.subtitle.data
|
||||
img['description'] = form.description.data
|
||||
img['category'] = form.category.data
|
||||
self.datas['blocs'][bloc][filename]=img
|
||||
|
||||
|
||||
def addImg(self, bloc, image_uploaded):
|
||||
def addImg(self, image_uploaded):
|
||||
img = dict()
|
||||
|
||||
img['title'] = ""
|
||||
img['subtitle']=""
|
||||
img['text'] = ""
|
||||
img['category'] = ""
|
||||
img['file']=image_uploaded
|
||||
self.datas['blocs'][bloc][image_uploaded]=img
|
||||
img['file'] = image_uploaded
|
||||
|
||||
return img
|
||||
|
||||
|
||||
def addImg_tmp(self, bloc, image_uploaded):
|
||||
img = dict()
|
||||
img['title'] = ""
|
||||
img['subtitle']=""
|
||||
img['text'] = ""
|
||||
img['category'] = ""
|
||||
img['file']=image_uploaded
|
||||
self.datas_tmp['blocs'][bloc][image_uploaded]=img
|
||||
def delImg(self, bloc, img):
|
||||
|
||||
def saveJson(self):
|
||||
remove(self.filej)
|
||||
with open (self.filej, 'w') as f:
|
||||
f.write(json.dumps(self.datas, indent=5))
|
||||
if bloc['type'] == 'gallery':
|
||||
img_file = Path(PurePosixPath(self.user_folder).joinpath('public', 'img', bloc[img]['file'] ))
|
||||
img_thumb_file = Path(PurePosixPath(self.user_folder).joinpath('public','img', 'thumbnails', bloc[img]['file']))
|
||||
if img_file.exists():
|
||||
img_file.unlink()
|
||||
|
||||
def delImg(self, img):
|
||||
try:
|
||||
images = self.datas['images']
|
||||
images.pop(img)
|
||||
except KeyError:
|
||||
print("Le fichier n'est pas dans la liste")
|
||||
if img_thumb_file.exists():
|
||||
img_thumb_file.unlink()
|
||||
|
||||
bloc.pop(img)
|
||||
else:
|
||||
self.trash.append(img)
|
||||
img_file = Path(PurePosixPath(self.user_folder).joinpath('public', 'img', img ))
|
||||
|
||||
return bloc
|
||||
|
||||
|
||||
def saveMenu(self, menu:dict):
|
||||
self.datas['menu'] = menu
|
||||
self.filej.write_text(json.dumps(self.datas, indent=5))
|
||||
|
||||
|
||||
def saveBlocs(self, page='', blocs=dict()):
|
||||
if page != '':
|
||||
datas = dict()
|
||||
datas['blocs'] = blocs
|
||||
|
||||
page_info = Path(PurePosixPath(self.user_folder).joinpath(page, 'page.json'))
|
||||
|
||||
if not page_info.exists():
|
||||
raise FileNotFoundError(f"Le fichier page.json n'existe pas : {page}")
|
||||
|
||||
page_info.write_text(json.dumps(datas, indent=3))
|
||||
else:
|
||||
self.datas['blocs']= blocs
|
||||
self.filej.write_text(json.dumps(self.datas, indent=5))
|
||||
|
||||
|
||||
def getPages(self):
|
||||
mypages = list()
|
||||
folders = Path(self.user_folder)
|
||||
for folder in folders.iterdir():
|
||||
if folder.name != 'public' and folder.is_dir():
|
||||
mypages.append(folder.name)
|
||||
|
||||
return mypages
|
||||
|
||||
def new_page(self, pageName:str, pageType:str):
|
||||
page_folder = Path(PurePosixPath(self.user_folder).joinpath(pageName))
|
||||
page = Path(PurePosixPath(self.user_folder).joinpath(pageName, 'page.json'))
|
||||
page_type = Path('./app/templates/themes/'+self.datas['config']['theme']+'/pages/'+pageType+'.json')
|
||||
|
||||
if not page_type.exists():
|
||||
raise FileNotFoundError(f"Le type de page n'existe pas : {page_type}")
|
||||
else:
|
||||
page_folder.mkdir()
|
||||
page.write_text(page_type.read_text())
|
||||
|
||||
if not page.exists():
|
||||
raise FileNotFoundError(f"La page n'a pas pu etre créé : {page}")
|
||||
|
||||
return True
|
||||
|
||||
def rm_page(self, pageName :str):
|
||||
page_folder = Path(PurePosixPath(self.user_folder).joinpath(pageName))
|
||||
page = Path(PurePosixPath(self.user_folder).joinpath(pageName, 'page.json'))
|
||||
|
||||
#First delete the json page
|
||||
try:
|
||||
page.unlink()
|
||||
print(f"Successfully deleted: {page}")
|
||||
except FileNotFoundError:
|
||||
print(f"File not found: {page}. Nothing to delete.")
|
||||
# Delete the empty directory
|
||||
if page_folder.is_dir():
|
||||
try:
|
||||
page_folder.rmdir()
|
||||
print(f"Successfully removed empty directory: {page_folder}")
|
||||
except OSError as e:
|
||||
print(f"Error removing directory (might not be empty): {e}")
|
||||
|
||||
|
||||
def writeHTML(self, pageName :str, htmlExport :str):
|
||||
public_folder = Path(PurePosixPath(self.user_folder).joinpath('public'))
|
||||
pageName = pageName+'.html'
|
||||
page = Path(PurePosixPath(self.user_folder).joinpath('public', pageName))
|
||||
page.write_text(htmlExport)
|
||||
|
||||
|
||||
def emptyTrash(self):
|
||||
for file in self.trash:
|
||||
|
||||
@@ -12,7 +12,7 @@ class Users:
|
||||
if auth_file != None:
|
||||
self.__auth_file = auth_file
|
||||
self.__auth_method = "file"
|
||||
|
||||
x
|
||||
def getPasswd(self, username):
|
||||
with open(self.auth_file, 'r') as f:
|
||||
users_info = f.readlines()
|
||||
|
||||
354
app/routes.py
354
app/routes.py
@@ -1,9 +1,10 @@
|
||||
from app import app
|
||||
from flask import render_template, url_for, request, flash, redirect, session, make_response
|
||||
from flask import render_template, url_for, request, flash, redirect, session, make_response, send_from_directory
|
||||
import json
|
||||
from markupsafe import escape
|
||||
from werkzeug.utils import secure_filename
|
||||
import os
|
||||
import re
|
||||
from app.forms import ImageForm, ImageUpload
|
||||
from app.models.sites import DataSite
|
||||
from app.models.blocs import MyBlocs
|
||||
@@ -17,20 +18,15 @@ from flask_wtf.csrf import CSRFProtect
|
||||
|
||||
csrf = CSRFProtect(app)
|
||||
|
||||
|
||||
app.secret_key = 'your_secret_key'
|
||||
|
||||
|
||||
app.config.from_pyfile('config.py')
|
||||
|
||||
|
||||
THEMES_FOLDER = './themes/'
|
||||
USERS_FOLDER = app.config['USERS_FOLDER']
|
||||
bcrypt = Bcrypt(app)
|
||||
|
||||
EXT_IMG = {'.jpg', '.JPG', '.png', '.PNG', '.gif', '.GIF', '.bmp', '.BMP', '.jpeg', '.JPEG' }
|
||||
|
||||
@app.route('/', methods=['GET', 'POST'])
|
||||
@app.route('/index.html', methods=['GET', 'POST'])
|
||||
@app.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
form = Login()
|
||||
@@ -65,91 +61,79 @@ def logout():
|
||||
return redirect(url_for('login'))
|
||||
|
||||
|
||||
@app.route('/edit/save')
|
||||
@login_required
|
||||
def savefile():
|
||||
user = '%s'% escape(session['username'])
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
db.saveJson(TMP.datas)
|
||||
db.emptyTrash()
|
||||
return redirect(url_for('edit'))
|
||||
|
||||
@app.route('/edit')
|
||||
@login_required
|
||||
def edit():
|
||||
user = '%s'% escape(session['username'])
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
theme = db.datas['config']['theme']
|
||||
menu = db.datas['menu']
|
||||
myblocs = db.datas['blocs']
|
||||
return render_template('/edit.html.tpl',
|
||||
blocEdit="",
|
||||
config=db.datas['config'],
|
||||
menu=menu,
|
||||
theme=theme,
|
||||
myblocs=myblocs
|
||||
)
|
||||
@app.route('/edit/<page>')
|
||||
@app.route('/', methods=['GET'], defaults={'page': ''})
|
||||
@app.route('/<page>/', methods=['GET'])
|
||||
@login_required
|
||||
def edit(page):
|
||||
user = '%s'% escape(session['username'])
|
||||
page = '%s' % escape(page)
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
blocs_page = db.getpage()
|
||||
mypages = db.getPages()
|
||||
theme = db.datas['config']['theme']
|
||||
menu = db.datas['menu']
|
||||
myblocs = db.datas['blocs']
|
||||
myblocs = db.getBlocs(page)['blocs']
|
||||
|
||||
return render_template('/edit.html.tpl',
|
||||
blocEdit="",
|
||||
config=db.datas['config'],
|
||||
menu=menu,
|
||||
theme=theme,
|
||||
pagesList=mypages,
|
||||
page=page,
|
||||
myblocs=myblocs
|
||||
)
|
||||
|
||||
|
||||
@app.route('/edit/images/<bloc>/<image>', methods=['GET', 'POST'])
|
||||
@app.route('/edit/images/<bloc>/<image>', methods=['GET', 'POST'], defaults={'page': ''})
|
||||
@app.route('/<page>/edit/images/<bloc>/<image>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def editPhoto(image, bloc):
|
||||
def editPhoto(page, image, bloc):
|
||||
user = '%s'% escape(session['username'])
|
||||
page = '%s' % escape(page)
|
||||
image = '%s' % escape(image)
|
||||
bloc = '%s' % escape(bloc)
|
||||
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
theme = db.datas['config']['theme']
|
||||
form = ImageForm()
|
||||
mesimages = db.datas['blocs'][bloc]
|
||||
myblocs = db.getBlocs(page)['blocs']
|
||||
|
||||
if form.validate_on_submit():
|
||||
if request.method == 'POST':
|
||||
db.updateImg(bloc, mesimages[image], form)
|
||||
db.saveJson()
|
||||
myblocs[bloc][image] = db.updateImg(image, form)
|
||||
db.saveBlocs(page, myblocs)
|
||||
form = MyBlocs.makeForm(db.datas['blocs'][bloc])
|
||||
if "hx-request" in request.headers:
|
||||
return render_template(theme+'/blocs/edit/images_list.html',
|
||||
theme=theme,
|
||||
bloc=mesimages,
|
||||
form=form)
|
||||
if "hx-request" in request.headers:
|
||||
return make_response(('Image modified', 200))
|
||||
else:
|
||||
return redirect ('/edit#'+bloc)
|
||||
return redirect ('/#'+bloc)
|
||||
else:
|
||||
return render_template(theme+'/blocs/edit/_image-edit'+'.html', form=form, image=mesimages[image], bloc=mesimages)
|
||||
return render_template(THEMES_FOLDER+theme+'/blocs/edit/_image-edit'+'.html', form=form, image=myblocs[bloc][image], bloc=myblocs[bloc])
|
||||
|
||||
@app.route('/upload-gallery/<bloc>', methods=['POST'])
|
||||
|
||||
@app.route('/upload-gallery/<bloc>', methods=['POST'], defaults={'page': ''})
|
||||
@app.route('/<page>/upload-gallery/<bloc>', methods=['POST'])
|
||||
@login_required
|
||||
def drop_upload(bloc):
|
||||
def drop_upload(page, bloc):
|
||||
user = '%s'% escape(session['username'])
|
||||
page = '%s' % escape(page)
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
datas = dict()
|
||||
file = request.files['file']
|
||||
filename = secure_filename(file.filename)
|
||||
myblocs = db.getBlocs(page)['blocs']
|
||||
ext = os.path.splitext(filename)[-1]
|
||||
save_path = "./app/static/img/portfolio"
|
||||
save_path = os.path.join(USERS_FOLDER, user, 'public', 'img' )
|
||||
if ext not in EXT_IMG :
|
||||
return make_response(('Le fichier n\'est pas une image', 400))
|
||||
|
||||
current_chunk = int(request.form['dzchunkindex'])
|
||||
print (current_chunk)
|
||||
|
||||
if (os.path.isfile(os.path.join(save_path, 'fullsize', filename ))) and current_chunk == 0:
|
||||
if (os.path.isfile(os.path.join(save_path, filename ))) and current_chunk == 0:
|
||||
return make_response(('Un fichier avec le même nom existe déjà', 400))
|
||||
|
||||
try:
|
||||
with open(os.path.join(save_path, 'fullsize', filename ), 'ab') as f:
|
||||
with open(os.path.join(save_path, filename ), 'ab') as f:
|
||||
f.seek(int(request.form['dzchunkbyteoffset']))
|
||||
f.write(file.stream.read())
|
||||
except OSError:
|
||||
@@ -159,117 +143,231 @@ def drop_upload(bloc):
|
||||
|
||||
if current_chunk + 1 == total_chunks:
|
||||
# This was the last chunk, the file should be complete and the size we expect
|
||||
if os.path.getsize(os.path.join(save_path, 'fullsize', filename )) != int(request.form['dztotalfilesize']):
|
||||
if os.path.getsize(os.path.join(save_path, filename )) != int(request.form['dztotalfilesize']):
|
||||
return make_response(('La taille du fichier source est différentes', 500))
|
||||
else:
|
||||
with Image.open(os.path.join(save_path, 'fullsize', filename )) as img :
|
||||
img.thumbnail((300,300))
|
||||
with Image.open(os.path.join(save_path, filename )) as img :
|
||||
img.thumbnail((640,480))
|
||||
img.save(os.path.join(save_path, 'thumbnails', filename ) )
|
||||
db.addImg(bloc, filename)
|
||||
db.saveJson()
|
||||
|
||||
myblocs[bloc][filename] = db.addImg(filename)
|
||||
db.saveBlocs(page, myblocs)
|
||||
return make_response(('Chunk upload succesfull', 200))
|
||||
|
||||
@app.route('/edit/images/<bloc>/del/<image>', methods=['GET'])
|
||||
@login_required
|
||||
def delImage(bloc, image):
|
||||
user = '%s'% escape(session['username'])
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
db.delImg(image)
|
||||
db.saveJson()
|
||||
return redirect ('/edit#'+bloc)
|
||||
|
||||
@app.route('/edit/<blocname>', methods=['GET', 'POST'])
|
||||
@app.route('/edit/images/<bloc>/del/<image>', methods=['GET'], defaults={'page': ''})
|
||||
@app.route('/<page>/edit/images/<bloc>/del/<image>', methods=['GET'])
|
||||
@login_required
|
||||
def editBloc(blocname):
|
||||
def delImage(page, bloc, image):
|
||||
user = '%s'% escape(session['username'])
|
||||
page = '%s' % escape(page)
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
myblocs = db.getBlocs(page)['blocs']
|
||||
|
||||
myblocs[bloc] = db.delImg(myblocs[bloc], image)
|
||||
db.saveBlocs(page, myblocs)
|
||||
|
||||
return make_response(('Image removed', 200))
|
||||
|
||||
|
||||
@app.route('/imgs_list/<blocname>', methods=['GET'], defaults={'page': ''})
|
||||
@app.route('/<page>/imgs_list/<blocname>', methods=['GET'])
|
||||
@login_required
|
||||
def imagesList(page, blocname):
|
||||
user = '%s'% escape(session['username'])
|
||||
page = '%s' % escape(page)
|
||||
blocname = '%s' % escape(blocname)
|
||||
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
theme = db.datas['config']['theme']
|
||||
bloc = db.datas['blocs'][blocname]
|
||||
myblocs = db.getBlocs(page)['blocs']
|
||||
bloc = myblocs[blocname]
|
||||
|
||||
return render_template(THEMES_FOLDER+theme+'/blocs/edit/images_list.html',page=page,
|
||||
bloc=bloc)
|
||||
|
||||
|
||||
@app.route('/edit/<blocname>', methods=['GET', 'POST'], defaults={'page': ''})
|
||||
@app.route('/<page>/edit/<blocname>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def editBloc(page, blocname):
|
||||
user = '%s'% escape(session['username'])
|
||||
page = '%s' % escape(page)
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
theme = db.datas['config']['theme']
|
||||
myblocs = db.getBlocs(page)['blocs']
|
||||
bloc = myblocs[blocname]
|
||||
form = MyBlocs.makeForm(bloc)
|
||||
|
||||
if request.method == 'POST':
|
||||
datas=dict()
|
||||
if form.validate_on_submit():
|
||||
print(form.name.data)
|
||||
db.datas['blocs'][form.name.data]=DataSite.updateBloc(bloc, form)
|
||||
db.saveJson()
|
||||
|
||||
for field, value in request.form.items():
|
||||
print (field)
|
||||
if field != 'csrf_token' and field != 'image':
|
||||
myblocs[blocname][field] = value
|
||||
if 'image' in request.files.keys():
|
||||
file = request.files['image']
|
||||
print ('filename: '+ file.filename)
|
||||
filename = secure_filename(file.filename)
|
||||
bg_custom = 'bg_custom_'+bloc['name']+filename
|
||||
print('bg_custom : '+ bg_custom)
|
||||
file.save(os.path.join(USERS_FOLDER, user, 'public', 'img', bg_custom ))
|
||||
if 'bg_img' in bloc.keys():
|
||||
db.delImg(bloc, bloc['bg_img'])
|
||||
|
||||
|
||||
myblocs[blocname]['bg_img'] = bg_custom
|
||||
|
||||
db.saveBlocs(page, myblocs)
|
||||
flash(u'Vos changements on été pris en compte et enregistré', 'success')
|
||||
else:
|
||||
print(form.errors)
|
||||
|
||||
if "hx-request" in request.headers:
|
||||
return render_template(theme+'/blocs/_'+bloc['type']+'.html',
|
||||
return render_template(THEMES_FOLDER+theme+'/blocs/_'+bloc['type']+'.html',
|
||||
theme=theme,
|
||||
bloc=db.datas['blocs'][blocname])
|
||||
page=page,
|
||||
bloc=myblocs[blocname])
|
||||
else:
|
||||
return redirect(url_for('edit'))
|
||||
|
||||
|
||||
else:
|
||||
if "hx-request" in request.headers:
|
||||
return render_template(theme+'/blocs/edit/_'+bloc['type']+'.html',
|
||||
return render_template(THEMES_FOLDER+theme+'/blocs/edit/_'+bloc['type']+'.html',
|
||||
theme=theme,
|
||||
bloc=bloc,
|
||||
page=page,
|
||||
form=form)
|
||||
else:
|
||||
return render_template('/edit.html.tpl',
|
||||
config=db.datas['config'],
|
||||
menu=db.datas['menu'],
|
||||
myblocs=db.datas['blocs'],
|
||||
myblocs=myblocs,
|
||||
page=page,
|
||||
theme=theme,
|
||||
blocEdit=bloc['name'],
|
||||
form=form)
|
||||
|
||||
@app.route('/view/<bloc>', methods=['GET'])
|
||||
@app.route('/view/<bloc>', methods=['GET'], defaults={'page': ''})
|
||||
@app.route('/<page>/view/<bloc>', methods=['GET'])
|
||||
@login_required
|
||||
def viewBloc(bloc):
|
||||
def viewBloc(page, bloc):
|
||||
user = '%s'% escape(session['username'])
|
||||
page = '%s' % escape(page)
|
||||
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
theme = db.datas['config']['theme']
|
||||
myblocs = db.datas['blocs']
|
||||
form = MyBlocs.makeForm(db.datas['blocs'][bloc])
|
||||
bloc = db.datas['blocs'][bloc]
|
||||
myblocs = db.getBlocs(page)['blocs']
|
||||
bloc = myblocs[bloc]
|
||||
|
||||
return render_template(theme+'/blocs/_'+bloc['type']+'.html',
|
||||
return render_template(THEMES_FOLDER+theme+'/blocs/_'+bloc['type']+'.html',
|
||||
bloc=bloc)
|
||||
|
||||
@app.route('/addBloc', methods=['POST'])
|
||||
@app.route('/addBloc', methods=['POST'], defaults={'page': ''})
|
||||
@app.route('/<page>/addBloc', methods=['POST'])
|
||||
@login_required
|
||||
def addBloc():
|
||||
def addBloc(page):
|
||||
user = '%s'% escape(session['username'])
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
for key in request.form:
|
||||
print (key +':'+ request.form[key])
|
||||
blocName = request.form['blocName']
|
||||
blocType = request.form['blocType']
|
||||
bloc = MyBlocs.new(blocName, blocType)
|
||||
if bloc != None:
|
||||
db.datas['blocs'][blocName] = { 'name': blocName, 'type': blocType}
|
||||
flash (u'Bloc ajouté avec succès', 'succes');
|
||||
else:
|
||||
return make_response(('Invalid type of bloc ', 500))
|
||||
page = '%s' % escape(page)
|
||||
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
datas = dict()
|
||||
myblocs = db.getBlocs(page)['blocs']
|
||||
|
||||
blocName = '%s' % escape(request.form['blocName'])
|
||||
blocType = request.form['blocType']
|
||||
bloc = MyBlocs.new(blocName, blocType, db.datas['config']['theme'])
|
||||
test_name = "^[A-Za-z0-9_-]*$"
|
||||
|
||||
if bloc != None:
|
||||
if bool(re.match(test_name, blocName)) :
|
||||
|
||||
myblocs[blocName] = { 'name': blocName, 'type': blocType}
|
||||
flash (u'Bloc ajouté avec succès', 'succes');
|
||||
else:
|
||||
return make_response(('Invalid bloc Name', 500))
|
||||
|
||||
db.saveBlocs(page, myblocs)
|
||||
|
||||
db.saveJson()
|
||||
if "hx-request" in request.headers:
|
||||
return render_template('/admin/_blocs-list.html',
|
||||
myblocs=db.datas['blocs'])
|
||||
else:
|
||||
return redirect(url_for('edit'))
|
||||
|
||||
@app.route('/sortblocs', methods=['POST'])
|
||||
|
||||
@app.route('/addPage', methods=['POST'])
|
||||
@login_required
|
||||
def sortblocs():
|
||||
def addPage():
|
||||
user = '%s'% escape(session['username'])
|
||||
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
datas = dict()
|
||||
|
||||
pageName = '%s' % escape(request.form['pageName'])
|
||||
pageType = request.form['pageType']
|
||||
test_name = "^[A-Za-z0-9_-]*$"
|
||||
if bool(re.match(test_name, pageName)) :
|
||||
try :
|
||||
page = db.new_page(pageName, pageType)
|
||||
except FileExistsError:
|
||||
return make_response(('Page already exist', 500))
|
||||
else:
|
||||
flash (u'Page créé avec succès', 'success');
|
||||
else:
|
||||
return make_response(('Invalid type ', 500))
|
||||
|
||||
|
||||
mypages = db.getPages()
|
||||
return redirect(url_for('edit', page=pageName))
|
||||
|
||||
@app.route('/rmPage/<pageName>')
|
||||
@login_required
|
||||
def rmPage(pageName):
|
||||
pageName = '%s' % escape(pageName)
|
||||
user = '%s'% escape(session['username'])
|
||||
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
|
||||
try:
|
||||
db.rm_page(pageName)
|
||||
flash (u'Page supprimé avec succès', 'success');
|
||||
except OSError as e:
|
||||
flash (u"La page n'a pa pu être supprimer", 'error');
|
||||
|
||||
|
||||
return redirect(url_for('edit'))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@app.route('/sortblocs', methods=['POST'], defaults={'page': ''})
|
||||
@app.route('/<page>/sortblocs', methods=['POST'])
|
||||
@login_required
|
||||
def sortblocs(page):
|
||||
user = '%s'% escape(session['username'])
|
||||
page = '%s' % escape(page)
|
||||
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
config = db.datas['config']
|
||||
menu = db.datas['menu']
|
||||
myblocs = deepcopy(TMP.datas['blocs'])
|
||||
db.datas['blocs']=dict()
|
||||
datas = dict()
|
||||
myblocs = dict()
|
||||
|
||||
myblocs_orig = db.getBlocs(page)['blocs']
|
||||
|
||||
for bloc in request.form:
|
||||
if bloc != 'csrf_token':
|
||||
bloc_name = bloc.replace("bloc-", "", 2)
|
||||
db.datas['blocs'][bloc_name] = myblocs[bloc_name]
|
||||
myblocs[bloc_name] = myblocs_orig[bloc_name]
|
||||
flash (u'Les blocs ont été réagencés', 'succes');
|
||||
db.saveJson()
|
||||
|
||||
db.saveBlocs(page, myblocs)
|
||||
|
||||
return redirect(url_for('edit'))
|
||||
|
||||
@app.route('/editmenu', methods=['POST'])
|
||||
@@ -291,7 +389,59 @@ def editMenu():
|
||||
else:
|
||||
db.datas['menu'][menu] = str(request.form[menu])
|
||||
|
||||
db.saveJson()
|
||||
db.saveMenu(db.datas['menu'])
|
||||
flash (u'Le menu a bien été modifier', 'success');
|
||||
return redirect(url_for('edit'))
|
||||
|
||||
@app.route('/public/img/<filename>')
|
||||
@login_required
|
||||
def myimgs(filename):
|
||||
user = '%s' % escape(session['username'])
|
||||
return send_from_directory(
|
||||
os.path.join(USERS_FOLDER, user, 'public', 'img'), filename )
|
||||
|
||||
@app.route('/public/img/thumbnails/<filename>')
|
||||
@login_required
|
||||
def mythumbnails(filename):
|
||||
user = '%s' % escape(session['username'])
|
||||
return send_from_directory(
|
||||
os.path.join(USERS_FOLDER, user, 'public', 'img', 'thumbnails'), filename )
|
||||
|
||||
@app.route('/favicon.ico', methods=['GET'])
|
||||
@app.route('/favicon.ico/', methods=['GET'])
|
||||
def favicon():
|
||||
return make_response(('Ok! ', 200))
|
||||
|
||||
|
||||
|
||||
@app.route('/publish', methods=['GET'])
|
||||
@login_required
|
||||
def publish():
|
||||
user = '%s' % escape(session['username'])
|
||||
db = DataSite(user, USERS_FOLDER)
|
||||
listPages = db.getPages()
|
||||
theme = db.datas['config']['theme']
|
||||
menu = db.datas['menu']
|
||||
|
||||
for page in listPages:
|
||||
myblocs = db.getBlocs(page)['blocs']
|
||||
htmlExport = render_template('/index.html.tpl',
|
||||
config=db.datas['config'],
|
||||
menu=menu,
|
||||
theme=theme,
|
||||
page=page,
|
||||
myblocs=myblocs)
|
||||
db.writeHTML(theme, page, htmlExport)
|
||||
|
||||
# Export index.html landing page
|
||||
myblocs = db.getBlocs('')['blocs']
|
||||
htmlExport = render_template('/index.html.tpl',
|
||||
config=db.datas['config'],
|
||||
menu=menu,
|
||||
theme=theme,
|
||||
page='/',
|
||||
myblocs=myblocs)
|
||||
|
||||
db.writeHTML(theme, 'index', htmlExport)
|
||||
return redirect(url_for('edit'))
|
||||
|
||||
|
||||
@@ -63,6 +63,92 @@ h6 {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.ql-align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ql-align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.ql-align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding: 60px 80px 40px;
|
||||
position: relative;
|
||||
}
|
||||
blockquote p {
|
||||
font-size: 35px;
|
||||
font-weight: 700px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/*blockquote p::before {
|
||||
content: "\f095";
|
||||
font-family: FontAwesome;
|
||||
display: inline-block;
|
||||
padding-right: 6px;
|
||||
vertical-align: middle;
|
||||
font-size: 180px;
|
||||
}*/
|
||||
|
||||
blockquote:before {
|
||||
position: absolute;
|
||||
font-family: 'FontAwesome';
|
||||
top: 0;
|
||||
content:"\f10d";
|
||||
font-size: 200px;
|
||||
color: rgba(0,0,0,0.1);
|
||||
|
||||
}
|
||||
|
||||
blockquote::after {
|
||||
content: "";
|
||||
top: 20px;
|
||||
left: 50%;
|
||||
margin-left: -100px;
|
||||
position: absolute;
|
||||
height: 3px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
blockquote{
|
||||
font-size: 1.4em;
|
||||
width:60%;
|
||||
margin:50px auto;
|
||||
font-style:italic;
|
||||
color: #555555;
|
||||
padding:1.2em 30px 1.2em 75px;
|
||||
border-left:8px solid #f05f40;
|
||||
line-height:1.6;
|
||||
position: relative;
|
||||
background:#EDEDED;
|
||||
}
|
||||
|
||||
blockquote::before{
|
||||
font-family:Arial;
|
||||
content: "\201C";
|
||||
color:#f05f40;
|
||||
font-size:4em;
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top:-10px;
|
||||
}
|
||||
|
||||
blockquote::after{
|
||||
content: '';
|
||||
}
|
||||
|
||||
blockquote span{
|
||||
display:block;
|
||||
color:#333333;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
margin-top:1em;
|
||||
}
|
||||
|
||||
section {
|
||||
padding: 8rem 0;
|
||||
z-index: -1;
|
||||
@@ -141,7 +227,7 @@ img::-moz-selection {
|
||||
@media (min-width: 992px) {
|
||||
#mainNav {
|
||||
border-color: transparent;
|
||||
background-color: transparent;
|
||||
background-color: rgba(0,0,0,0.7);
|
||||
}
|
||||
#mainNav .navbar-brand {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
@@ -190,16 +276,27 @@ header.masthead {
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
header.masthead hr {
|
||||
header.article-img {
|
||||
padding-top: 10rem;
|
||||
padding-bottom: calc(10rem - 56px);
|
||||
background-position: center center;
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
|
||||
header.article-img header.masthead hr {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
header.masthead h1 {
|
||||
header.article-img header.masthead h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
header.masthead p {
|
||||
header.article-img header.masthead p {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
@@ -210,19 +307,27 @@ header.masthead p {
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
header.article-img {
|
||||
height: 50vh;
|
||||
min-height: 300px;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
header.masthead {
|
||||
height: 100vh;
|
||||
min-height: 650px;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
header.masthead h1 {
|
||||
|
||||
header.article-img header.masthead h1 {
|
||||
font-size: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
header.masthead h1 {
|
||||
header.article-img header.masthead h1 {
|
||||
font-size: 4rem;
|
||||
}
|
||||
.btn-success {
|
||||
|
||||
@@ -4,3 +4,37 @@
|
||||
border-top-color: currentcolor;
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
.visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.msginfo
|
||||
{
|
||||
color: white;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
.msginfo .success
|
||||
{
|
||||
background-color: green;
|
||||
|
||||
}
|
||||
|
||||
.msginfo .error{
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.ql-toolbar {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.ql-editor {
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
|
||||
}
|
||||
|
||||
3
app/static/css/prism.min.css
vendored
Normal file
3
app/static/css/prism.min.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/* PrismJS 1.30.0
|
||||
https://prismjs.com/download#themes=prism-okaidia&languages=markup+css+clike+javascript+bash+c+cpp+markdown+markup-templating+nginx+php+python */
|
||||
code[class*=language-],pre[data-language*=language-]{color:#f8f8f2;background:0 0;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8292a2}.token.punctuation{color:#f8f8f2}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 180 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 106 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB |
15
app/static/js/prism.js
Normal file
15
app/static/js/prism.js
Normal file
File diff suppressed because one or more lines are too long
@@ -12,7 +12,7 @@
|
||||
dictDefaultMessage: 'Déposez vos fichiers ici!',
|
||||
paramName: "file",
|
||||
maxFilesize: 1024, // MB
|
||||
url: "/upload-dropzone",
|
||||
url: "{% if page %}/{{ page }}{% endif %}/upload-gallery/{{bloc.name}}",
|
||||
chunking: true,
|
||||
forceChunking: true,
|
||||
chunkSize: 1000000,
|
||||
|
||||
4
app/templates/_print_colors.css
Normal file
4
app/templates/_print_colors.css
Normal file
@@ -0,0 +1,4 @@
|
||||
{% if bloc.fg_color != bloc.bg_color %}
|
||||
color: {{ bloc.fg_color }}; background-color: {{ bloc.bg_color }};
|
||||
{% endif %}
|
||||
|
||||
@@ -9,28 +9,40 @@
|
||||
<button class="btn btn-outline-success" onclick="printForm()">+</button>
|
||||
|
||||
<div class="formAddBloc" id="addBloc">
|
||||
<form action="/addBloc" method="POST" class="" >
|
||||
<form action="/addBloc" id="addBloc" method="POST" class="" >
|
||||
<input id="csrf_token" name="csrf_token" type="hidden" value="{{ csrf_token() }}">
|
||||
<h3>Créé un nouveau bloc</H3>
|
||||
<br>
|
||||
|
||||
<label for="nom"><b>Nom du bloc </b></label><br/>
|
||||
<input type="text" name="blocName" placeholder="Nom" id="blocName" required="">
|
||||
<label for="blocName">Nom du bloc (caractères sans accents uniquement) </label>
|
||||
<div class="input-group">
|
||||
<input type="text"
|
||||
name="blocName"
|
||||
class="form-control"
|
||||
id="blocName"
|
||||
placeholder="Bloc1"
|
||||
required>
|
||||
<div class="invalid-feedback">
|
||||
Entrez le nom du bloc sans espaces ni caractères spéciaux
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<label for="link"><b>Type de bloc</b></label>
|
||||
<br/>
|
||||
<select id="blocType" name="blocType" size="8">
|
||||
<option value="presentation">Présentation</option>
|
||||
<select id="blocType" name="blocType" size="8" required>
|
||||
<option value="presentation"> Ecran d'Accueil </option>
|
||||
<option value="presentation"> Image En-tête d'article </option>
|
||||
<option value="text">Texte libre</option>
|
||||
<option value="simple_article">Article Simple</option>
|
||||
<option value="gallery">Galerie</option>
|
||||
<option value="external_link">Lien externe</option>
|
||||
<option value="contact">Contact</option>
|
||||
</select>
|
||||
<br/>
|
||||
<button type="submit" class="btn btn-success"
|
||||
hx-post="/addBloc"
|
||||
hx-swap="outerHTML"
|
||||
hx-target="#myblocs"> Créer le bloc </button>
|
||||
onclick="valid_nameBloc()"
|
||||
hx-post="/addBloc"
|
||||
hx-swap="outerHTML"
|
||||
hx-target="#myblocs"> Créer le bloc </button>
|
||||
</form>
|
||||
</div>
|
||||
<hr/>
|
||||
@@ -39,9 +51,20 @@
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function valid_nameBloc()
|
||||
{
|
||||
var blocName = document.getElementById("blocName");
|
||||
let name_field = blocName.value.trim();
|
||||
let Valid = /^[a-z0-9]+$/i.test(name_field);
|
||||
console.log(Valid);
|
||||
if (!Valid) {
|
||||
document.getElementById("blocName").setAttribute("class", "form-control is-invalid");
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
<form class="sortblocs" action="/sortblocs" method="POST" id="myblocs">
|
||||
<div id="myblocs" class="myblocs">
|
||||
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||
{% for item in myblocs.keys() %}
|
||||
|
||||
<div class="bloc" id="bloc-{{ item }}" style="margin-top: 10px;">
|
||||
<div class="bloc" id="bloc-{{ item }}" style="margin-top: 10px;">
|
||||
<button class="btn"> {{ item }} - {{ myblocs[item]['type'] }} </button>
|
||||
<input class="input-menu" id="bloc-{{ item }}" name="{{ item }}" value="" style="display:none;">
|
||||
<button class="btn btn-danger" onclick="deleteItem(this)"> x </button>
|
||||
@@ -30,4 +30,4 @@
|
||||
swapThreshold: 0.65,
|
||||
})};
|
||||
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
{% for item in myblocs.keys() %}
|
||||
|
||||
<div class="bloc" id="bloc-{{ item }}" style="margin-top: 10px;">
|
||||
<button class="btn"> {{ item }} - {{ myblocs[item]['type'] }} </button>
|
||||
<input class="input-menu" id="bloc-{{ item }}" name="{{ item }}" value="" style="display:none;">
|
||||
<button class="btn btn-danger" onclick="deleteItem(this)"> x </button>
|
||||
</div>
|
||||
|
||||
{% endfor %}
|
||||
@@ -6,14 +6,14 @@
|
||||
type="button"
|
||||
data-toggle="modal"
|
||||
data-target="#addBloc">
|
||||
Agencer es blocs
|
||||
Blocs de cette page
|
||||
</button>
|
||||
|
||||
<button class="btn btn-info nav-brand js-scroll-trigger"
|
||||
type="button"
|
||||
data-toggle="modal"
|
||||
data-target="#mymenu">
|
||||
Editer le menu
|
||||
Mon menu
|
||||
</button>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
type="button"
|
||||
data-toggle="modal"
|
||||
data-target="#mypages">
|
||||
Gérer mes pages
|
||||
Mes pages
|
||||
</button>
|
||||
|
||||
<button class="btn btn-secondary"
|
||||
@@ -46,39 +46,19 @@
|
||||
<div class="modal-content">
|
||||
<!-- Modal Header -->
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title"> Agencer mes blocs </h4>
|
||||
<h4 class="modal-title"> Mes blocs </h4>
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
</div>
|
||||
<div class="modal-body text-center">
|
||||
{% include 'admin/_bloc-edit.html' %}
|
||||
</div>
|
||||
<div class="modal-footer mx-auto">
|
||||
<a class="btn btn-danger" href="/edit" > Annuler </a>
|
||||
<a class="btn btn-danger" href="/" > Annuler </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="modal" id="mypages">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<!-- Modal Header -->
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title"> Mes pages </h4>
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
</div>
|
||||
<div class="modal-body text-center">
|
||||
{% include 'admin/_pages-edit.html' %}
|
||||
</div>
|
||||
<div class="modal-footer mx-auto">
|
||||
<a class="btn btn-danger" href="/edit" > Annuler </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="modal" id="mymenu">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
@@ -91,12 +71,32 @@
|
||||
{% include 'admin/_menu-edit.html' %}
|
||||
</div>
|
||||
<div class="modal-footer mx-auto">
|
||||
<a class="btn btn-danger" href="/edit" > Annuler </a>
|
||||
<a class="btn btn-danger" href="/" > Annuler </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="mypages">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<!-- Modal Header -->
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title"> Mes pages </h4>
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
</div>
|
||||
<div class="modal-body text-center">
|
||||
{% include 'admin/_pages-edit.html' %}
|
||||
</div>
|
||||
<div class="modal-footer mx-auto">
|
||||
<a class="btn btn-danger" href="/" > Annuler </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="modal" id="parameters">
|
||||
<div class="modal-dialog modal-lg">
|
||||
@@ -134,8 +134,9 @@
|
||||
|
||||
<!-- Modal footer -->
|
||||
<div class="modal-footer mx-auto">
|
||||
<a class="btn btn-danger" href="/edit" > Annuler </a>
|
||||
<a class="btn btn-danger" href="/" > Annuler </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -52,7 +52,6 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="/static/vendors/Sortable/Sortable.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
|
||||
<!--
|
||||
<form class="sortblocs" action="/createpage" method="POST" id="mypages">
|
||||
<div id="myblocs" class="myblocs">
|
||||
|
||||
{% for item in mypages %}
|
||||
|
||||
<div class="page" id="page" style="margin-top: 10px;">
|
||||
<button class="btn"> {{ }} - {{ myblocs[item]['type'] }} </button>
|
||||
<input class="input-menu" id="bloc-{{ item }}" name="{{ item }}" value="" style="display:none;">
|
||||
<button class="btn btn-danger" onclick="deleteItem(this)"> x </button>
|
||||
</div>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
-->
|
||||
<script src="/static/vendors/Sortable/Sortable.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var elements = document.getElementsByClassName('page');
|
||||
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
|
||||
new Sortable(elements[i], {
|
||||
group: 'shared',
|
||||
animation: 150,
|
||||
invertSwap: true,
|
||||
fallbackOnBody: true,
|
||||
swapThreshold: 0.65,
|
||||
})};
|
||||
|
||||
</script>
|
||||
@@ -1,24 +1,47 @@
|
||||
<div id="mypages">
|
||||
<ul style="list-style:none;" id="mypages" class="mypages">
|
||||
<li><a href="/"> <button class="btn"> Page d'accueil </button> </a> </li>
|
||||
|
||||
<!--
|
||||
<form class="sortblocs" action="/createpage" method="POST" id="mypages">
|
||||
<div id="myblocs" class="myblocs">
|
||||
</div>
|
||||
</form>
|
||||
{% for item in pagesList %}
|
||||
|
||||
-->
|
||||
<script src="/static/vendors/Sortable/Sortable.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
<li style="padding-top: 10px;">
|
||||
<a href="/{{ item }}/">
|
||||
<button class="btn"> {{ item }} </button>
|
||||
</a>
|
||||
<a href="/rmPage/{{ item }}"><button class="btn btn-danger"> X </button></a>
|
||||
|
||||
var elements = document.getElementsByClassName('page');
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
</ul>
|
||||
|
||||
new Sortable(elements[i], {
|
||||
group: 'shared',
|
||||
animation: 150,
|
||||
invertSwap: true,
|
||||
fallbackOnBody: true,
|
||||
swapThreshold: 0.65,
|
||||
})};
|
||||
|
||||
</script>
|
||||
<div class="formAddPage" id="addPage">
|
||||
<form action="/addPage" id="addPage" method="POST" class="" >
|
||||
<input id="csrf_token" name="csrf_token" type="hidden" value="{{ csrf_token() }}">
|
||||
<h3>Créé un nouveau bloc</H3>
|
||||
<br>
|
||||
<label for="blocName">Nom du bloc (caractères sans accents uniquement) </label>
|
||||
<div class="input-group">
|
||||
<input type="text"
|
||||
name="pageName"
|
||||
class="form-control"
|
||||
id="pageName"
|
||||
placeholder="Ma_Page"
|
||||
required>
|
||||
<div class="invalid-feedback">
|
||||
Entrez le nom de la page sans espaces ni caractères spéciaux
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<label for="link"><b>Type de bloc</b></label>
|
||||
<br/>
|
||||
<select id="pageType" name="pageType" size="8" required>
|
||||
<option value="article_image"> Article avec une image d'en tête </option>
|
||||
<option value="simple_article"> Page blanche Texte libre </option>
|
||||
</select>
|
||||
<br/>
|
||||
<button type="submit" class="btn btn-success"
|
||||
onclick="valid_nameBloc()"> Créer la page </button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
<header class="masthead text-center text-white d-flex" style="background-image: url('/static/img/{{ bloc.bg_img }}');">
|
||||
<div class="container my-auto">
|
||||
<form method='POST' action='/edit/accueil' enctype="multipart/form-data">
|
||||
{{ form.csrf_token }}
|
||||
<div class="row">
|
||||
<div class="col-lg-10 form-group mx-auto">
|
||||
{{ form.titre(value=bloc.title,
|
||||
class="form-control form-control-lg text-center text-uppercase")
|
||||
}}
|
||||
{% for error in form.titre.errors %}
|
||||
<span style="color: red;">{{ error }}</span>
|
||||
{% endfor %}
|
||||
<hr>
|
||||
</div>
|
||||
<div class="col-lg-8 form-group mx-auto">
|
||||
{% set f = form.presentation.process_data(bloc.text) %}
|
||||
{{ form.presentation(
|
||||
class="form-control text-center",
|
||||
rows="7")
|
||||
}}
|
||||
{% for error in form.presentation.errors %}
|
||||
<span style="color: red;">{{ error }}</span>
|
||||
{% endfor %}
|
||||
<br/>
|
||||
<div class="col-lg-4 form-group mx-auto">
|
||||
{{ form.texte_boutton(value=bloc.text_button,
|
||||
class="form-control text-center") }}
|
||||
{% for error in form.texte_boutton.errors %}
|
||||
<span style="color: red;">
|
||||
{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="col-lg-3 form-group mx-auto">
|
||||
{{ form.image(class="form-control" ) }}
|
||||
</div>
|
||||
{{ form.submit() }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</header>
|
||||
@@ -1,16 +0,0 @@
|
||||
<header class="masthead text-center text-white d-flex" style="background-image: url('/static/img/{{ mesinfos.presentation.bg_img }}');" >
|
||||
<div class="container my-auto">
|
||||
<div class="row">
|
||||
<div class="col-lg-10 mx-auto">
|
||||
<h1 class="text-uppercase">
|
||||
<strong> {{ mesinfos.presentation.title }} </strong>
|
||||
</h1>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="col-lg-8 mx-auto">
|
||||
<p class="text-faded mb-5"> {{ mesinfos.presentation.text }} </p>
|
||||
<a class="btn btn-primary btn-xl js-scroll-trigger" href="#about">{{ mesinfos.presentation.text_button }} </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
@@ -1,34 +0,0 @@
|
||||
|
||||
<div class="container-fluid p-0">
|
||||
<form method='POST' action='/edit/images/{{ bloc.name }}/{{ image.file }}' hx-swap="outerHTML" hx-target="#{{ bloc.name }}">
|
||||
{{ form.csrf_token }}
|
||||
<div class="row">
|
||||
<div class="col-lg-2 mx-auto my-4 text-center">
|
||||
<img class="img-fluid" src="/static/img/portfolio/thumbnails/{{ image.file }}" alt="{{ image.description }}">
|
||||
</div>
|
||||
<div class="col-lg-4 mx-auto my-4 text-center">
|
||||
<h3> Titre </h3>
|
||||
{{ form.title(value=image.title,
|
||||
class="form-control form-control-lg text-center") }}
|
||||
<hr class="light my-4">
|
||||
<h3>Sous-titre</h3>
|
||||
{{ form.subtitle(value=image.subtitle, class="form-control text-center") }}
|
||||
<br/>
|
||||
<h3> Catégorie </h3>
|
||||
{{ form.category(value=image.category, class="form-control text-center") }}
|
||||
<hr class="light my-4">
|
||||
<h3> Description de votre image </h3>
|
||||
<p> Une description de l'image est utile pour les personnes mal-voyantes et au référecement de votre site </p>
|
||||
{{ form.description(value=image.description, class="form-control text-center") }}
|
||||
<br/>
|
||||
<button class="btn btn-success" type="submit" data-dismiss="modal"
|
||||
hx-post="/edit/images/{{ bloc.name }}/{{ image.file }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-target="#{{ bloc.name }}"> Valider </button>
|
||||
<a class="btn btn-danger mx-auto" href="/edit/images/del/{{ image.nom_fichier }}">Supprimer l'image</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<section class="bg-primary" id="about">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-8 mx-auto text-center">
|
||||
<h2 class="section-heading text-white">{{ mesinfos.text.title }}</h2>
|
||||
<hr class="light my-4">
|
||||
<p class="text-faded mb-4"> {{ mesinfos.text.text }} </p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,20 +0,0 @@
|
||||
<header class="masthead text-center text-white d-flex" style="background-image: url('/static/img/{{ bloc.bg_img }}');" id="{{ bloc.name }}" >
|
||||
<div class="container my-auto">
|
||||
<div class="row">
|
||||
<div class="col-lg-10 mx-auto">
|
||||
<h1 class="text-uppercase">
|
||||
<strong> {{ bloc.title }} </strong>
|
||||
</h1>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="col-lg-8 mx-auto">
|
||||
<p class="text-faded mb-5"> {{ bloc.text }} </p>
|
||||
<a class="btn btn-primary btn-xl js-scroll-trigger" href="#">{{ bloc.text_button }}
|
||||
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
<form id="uploader" methods="POST" class="dropzone dz-clickable"></form>
|
||||
|
||||
{% include theme+'/blocs/edit/images_list.html' %}
|
||||
|
||||
{% include '_js_dropzone.html' %}
|
||||
@@ -1,30 +0,0 @@
|
||||
{% extends 'creative/_layout.html' %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
{% include theme+'/_nav.html' %}
|
||||
{% include theme+'/_navtool.html' %}
|
||||
|
||||
|
||||
{% for bloc in myblocs.values() %}
|
||||
|
||||
{% if blocEdit == bloc.name %}
|
||||
{% include theme+'/_'+bloc.type+'-edit.html' %}
|
||||
{% else %}
|
||||
|
||||
{% include theme+'/_'+bloc.type+'.html' %}
|
||||
|
||||
<button class="btn btn-success btn-xl pull-right"
|
||||
style="margin-top:-7rem; margin-right:1rem;"
|
||||
hx-get="/edit/{{ bloc.name }}"
|
||||
hx-target="#{{bloc.name}}"
|
||||
hw-swap="none"
|
||||
> Éditer </button>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -1,15 +0,0 @@
|
||||
{% extends "creative/layout.html" %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<!-- Navigation -->
|
||||
{% include 'creative/_nav.html' %}
|
||||
|
||||
{% for bloc in myblocs.values() %}
|
||||
|
||||
{% include 'creative/_'+bloc.type+'.html' %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -1,15 +0,0 @@
|
||||
{% extends "creative/layout.html" %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<!-- Navigation -->
|
||||
{% include 'creative/_nav.html' %}
|
||||
|
||||
{% for bloc in myblocs.values() %}
|
||||
|
||||
{% include 'creative/_'+bloc.type+'.html' %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -1,19 +0,0 @@
|
||||
{# creative/layout.html #}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
|
||||
<head>
|
||||
<!-- Style CSS -->
|
||||
{% include 'creative/_head.html' %}
|
||||
</head>
|
||||
|
||||
<body id="page-top">
|
||||
{% block body %}
|
||||
|
||||
{% endblock %}
|
||||
</body>
|
||||
|
||||
{% include 'creative/javascript.html' %}
|
||||
|
||||
</html>
|
||||
@@ -1,10 +1,31 @@
|
||||
<div class="text-center mx-auto">
|
||||
<button class="btn btn-success"
|
||||
hx-post='/edit/{{ bloc.name }}'
|
||||
hx-swap="outerHTML"
|
||||
onclick="saveText()"
|
||||
hx-post='{% if page %}/{{ page }}{% endif %}/edit/{{ bloc.name }}'
|
||||
hx-swap="outerHTML swap:100ms"
|
||||
hx-target="#{{ bloc.name }}" > Enregistrer </button>
|
||||
|
||||
|
||||
<button class="btn btn-danger"
|
||||
hx-get="/view/{{ bloc.name }}"
|
||||
onclick="enableModBtn()"
|
||||
hx-get="{% if page %}/{{ page }}{% endif %}/view/{{ bloc.name }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-target="#{{ bloc.name }}" > Annuler </button>
|
||||
</div>
|
||||
<script>
|
||||
function enableModBtn(){
|
||||
document.getElementById("modify-{{ bloc.name }}").disabled = false;
|
||||
}
|
||||
|
||||
function saveText(){
|
||||
|
||||
editor_content = document.getElementById("editor");
|
||||
if (editor_content != null)
|
||||
{
|
||||
document.getElementById("text").innerHTML = quill.getSemanticHTML(0);
|
||||
delete quill;
|
||||
}
|
||||
enableModBtn();
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
4
app/templates/edit-tools/_disable-modify-button.html
Normal file
4
app/templates/edit-tools/_disable-modify-button.html
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
<script>
|
||||
document.getElementById("modify-{{ bloc.name }}").disabled = true;
|
||||
</script>
|
||||
52
app/templates/edit-tools/_editor-wysiwyg.html
Normal file
52
app/templates/edit-tools/_editor-wysiwyg.html
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
<div id="editor">
|
||||
{{ bloc.text|safe }}
|
||||
</div>
|
||||
<br/>
|
||||
<textarea style="display :none;" id="text" name="text"> </textarea>
|
||||
|
||||
<!-- Initialize Quill editor -->
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var toolbarOptions = [
|
||||
['bold', 'italic', 'underline', 'strike'], // toggled buttons
|
||||
['blockquote', 'code-block'],
|
||||
['link', 'image'],
|
||||
|
||||
[{ 'header': 2 }, { 'header': 3 }, { 'header': 4},], // custom button values
|
||||
[{ 'list': 'ordered'}, { 'list': 'bullet' }, { 'list': 'check' }],
|
||||
[{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
|
||||
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
|
||||
[{ 'direction': 'rtl' }], // text direction
|
||||
|
||||
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
|
||||
[{ 'header': [ 2, 3, 4, 5, 6, false] }],
|
||||
|
||||
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
|
||||
[{ 'font': [] }],
|
||||
[{ 'align': [] }],
|
||||
|
||||
['clean'] // remove formatting button
|
||||
];
|
||||
var quill = new Quill('#editor', {
|
||||
modules: {
|
||||
syntax: true, // Include syntax module
|
||||
toolbar: toolbarOptions // Include button in toolbar
|
||||
},
|
||||
theme: 'snow'
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.ql-container {
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
.ql-editor {
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
|
||||
<h3> Nom du bloc : {{ bloc.name }} </h3>
|
||||
<div class="row mx-md-5">
|
||||
<div class="col-auto">
|
||||
<label> Nom du bloc </label>
|
||||
{{ form.name(col=4,value=bloc.name,
|
||||
<label> Classes CSS </label>
|
||||
{{ form.property(col=4,value=bloc.property,
|
||||
class="form-control text-center") }}
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label> Couleur de l'arrière plan </label>
|
||||
{{ form.bg_color(col=4,
|
||||
class="form-control form-control-color text-center") }}
|
||||
class="form-control form-control-color text-center",
|
||||
value=bloc.bg_color) }}
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label> Couleur du texte</label>
|
||||
{{ form.fg_color(col=4,
|
||||
class="form-control form-control-color text-center") }}
|
||||
class="form-control form-control-color text-center",
|
||||
value=bloc.fg_color) }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
@@ -15,4 +15,9 @@
|
||||
.msginfo .error{
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.ql-toolbar {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
<style>
|
||||
|
||||
.msginfo
|
||||
{
|
||||
color: white;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
.msginfo .success
|
||||
{
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.msginfo .error{
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
||||
@@ -2,27 +2,38 @@
|
||||
|
||||
{% block css %}
|
||||
{% include 'edit-tools/css/dropzone' %}
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css" rel="stylesheet">
|
||||
<link href="/static/css/edit-toolbar.css" rel="stylesheet">
|
||||
|
||||
<link href="/static/css/prism.min.css" rel="stylesheet">
|
||||
<!-- Include the highlight.js library -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.snow.css" rel="stylesheet" />
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
{% include config.theme+'/_nav.html' %}
|
||||
{% include config.theme+'/_navtool.html' %}
|
||||
{% include 'themes/'+config.theme+'/_nav.html' %}
|
||||
{% include 'admin/_menu-admin.html' %}
|
||||
|
||||
{% macro print_colors() %}
|
||||
{% endmacro %}
|
||||
|
||||
{% for bloc in myblocs.values() %}
|
||||
|
||||
{% if blocEdit == bloc.name %}
|
||||
{% include config.theme+'/blocs/edit/_'+bloc.type+'.html' %}
|
||||
{% else %}
|
||||
{% include config.theme+'/blocs/_'+bloc.type+'.html' %}
|
||||
|
||||
<button class="btn btn-success btn-xl pull-right"
|
||||
style="margin-top:-7rem; margin-right:1rem;"
|
||||
hx-get="/edit/{{ bloc.name }}"
|
||||
hx-target="#{{bloc.name}}"
|
||||
hx-swap="oob"> Modifier </button>
|
||||
{% include 'themes/'+config.theme+'/blocs/edit/_'+bloc.type+'.html' %}
|
||||
|
||||
{% else %}
|
||||
|
||||
{% include 'themes/'+config.theme+'/blocs/_'+bloc.type+'.html' %}
|
||||
|
||||
<button class="btn btn-success btn-xl pull-right"
|
||||
id="modify-{{ bloc.name }}"
|
||||
style="margin-top:-7rem; margin-right:1rem;"
|
||||
hx-get="{% if page %}/{{ page }}{% endif %}/edit/{{ bloc.name }}"
|
||||
hx-target="#{{bloc.name}}"
|
||||
hx-swap="oob"> Modifier </button>
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
@@ -31,5 +42,13 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
<!-- Include the Quill library -->
|
||||
|
||||
<script src="/static/vendors/htmx/htmx.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/cpp.min.js"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.js"></script>
|
||||
|
||||
<script src="/static/js/prism.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<head>
|
||||
<!-- Style CSS -->
|
||||
{% include config.theme+'/_head.html' %}
|
||||
{% include 'themes/'+config.theme+'/_head.html' %}
|
||||
{% block css %}
|
||||
{% endblock %}
|
||||
</head>
|
||||
@@ -11,17 +11,17 @@
|
||||
<body id="page-top">
|
||||
{% block body %}
|
||||
|
||||
{% include config.theme+'/_nav.html' %}
|
||||
{% include 'themes/'+config.theme+'/_nav.html' %}
|
||||
|
||||
{% for bloc in myblocs.values() %}
|
||||
{% include config.theme+'/blocs/_'+bloc.type+'.html' %}
|
||||
{% include 'themes/'+config.theme+'/blocs/_'+bloc.type+'.html' %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{% endblock %}
|
||||
</body>
|
||||
|
||||
{% include config.theme+'/javascript.html' %}
|
||||
{% include 'themes/'+config.theme+'/javascript.html' %}
|
||||
{% block js %}
|
||||
{% endblock js %}
|
||||
</html>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="{{ item }}">
|
||||
{% for subitem in menu[item].keys() %}
|
||||
<a class="dropdown-item" href="{{item[subitem]}}">{{ subitem }}</a>
|
||||
<a class="dropdown-item" href="{{menu[item][subitem]}}">{{ subitem }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</li>
|
||||
@@ -1,11 +1,10 @@
|
||||
<section class="bg-primary" id="{{ bloc.name }}">
|
||||
<section class="bg-primary {{ bloc.property }}" id="about">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-8 mx-auto text-center">
|
||||
<h2 class="section-heading text-white">{{ bloc.title }}</h2>
|
||||
<hr class="light my-4">
|
||||
<p class="text-faded mb-4"> {{ bloc.text }} </p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,4 +1,4 @@
|
||||
<section id="contact" >
|
||||
<section id="contact" class="{{ bloc.property }}" style="{% include '_print_colors.css' %}">
|
||||
<div class="container" id="{{ bloc.name }}">
|
||||
<div class="row">
|
||||
<div class="col-lg-8 mx-auto text-center">
|
||||
@@ -1,7 +1,7 @@
|
||||
<section class="bg-dark text-white" id="{{ bloc.name }}" hx-swap-oob="true" >
|
||||
<section class="{{ bloc.property }}" style="{% include '_print_colors.css' %}" id="{{ bloc.name }}" >
|
||||
<div class="container text-center">
|
||||
<h2 class="mb-4">{{ bloc.title }}</h2>
|
||||
<p> {{ bloc.text }} </p>
|
||||
{{ bloc.text|safe }}
|
||||
<a class="btn btn-light btn-xl sr-button" href="{{ bloc.link }}">
|
||||
{{ bloc.text_button }}
|
||||
</a>
|
||||
@@ -1,12 +1,14 @@
|
||||
|
||||
<section class="p-0" id="{{ bloc.name }}">
|
||||
<section class="p-0 {{ bloc.property }}" id="{{ bloc.name }}">
|
||||
<div class="container-fluid p-0">
|
||||
<div class="row no-gutters popup-gallery">
|
||||
{% for image in bloc.values() %}
|
||||
{% if image.file %}
|
||||
<div class="col-lg-4 col-sm-6 text-center">
|
||||
<a class="portfolio-box" href="/static/img/portfolio/fullsize/{{ image.file }}" alt="{{ image.description }}">
|
||||
<img class="img-fluid" src="/static/img/portfolio/thumbnails/{{ image.file }}" alt="{{ image.description }}">
|
||||
<a class="portfolio-box" href="/public/img/{{ image.file }}"
|
||||
alt="{{ image.description }}">
|
||||
<img class="img-fluid" src="/public/img/thumbnails/{{ image.file }}"
|
||||
alt="{{ image.description }}">
|
||||
<div class="portfolio-box-caption">
|
||||
<div class="portfolio-box-caption-content">
|
||||
<div class="project-category text-faded">
|
||||
14
app/templates/themes/creative/blocs/_head_image.html
Normal file
14
app/templates/themes/creative/blocs/_head_image.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<header class="article-img text-center text-white d-flex" style="{% include '_print_colors.css' %} background-image: url('/public/img/{{ bloc.bg_img }}');" id="{{ bloc.name }}" >
|
||||
<div class="container my-auto">
|
||||
<div class="row" style="mix-blend-mode: hard-light;background-color: rgba(0,0,0,0.3);">
|
||||
<div class="col-lg-10 mx-auto">
|
||||
<h1 class="text-uppercase">
|
||||
<strong> {{ bloc.title }} </strong>
|
||||
</h1>
|
||||
<hr>
|
||||
<h3> {{ bloc.subtitle }} </h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
25
app/templates/themes/creative/blocs/_presentation.html
Normal file
25
app/templates/themes/creative/blocs/_presentation.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<header class="masthead text-center text-white d-flex" style="{% include '_print_colors.css' %} background-image: url('/public/img/{{ bloc.bg_img }}');" id="{{ bloc.name }}" >
|
||||
<div class="container my-auto">
|
||||
<div class="row" style="mix-blend-mode: hard-light;background-color: rgba(0,0,0,0.3);">
|
||||
<div class="col-lg-10 mx-auto">
|
||||
<h1 class="text-uppercase">
|
||||
<strong> {{ bloc.title }} </strong>
|
||||
</h1>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="col-lg-10 mx-auto">
|
||||
<p class="text-faded mb-5"> {{ bloc.text|safe }} </p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="center mx-auto mt-5">
|
||||
<a class="btn btn-primary btn-xl js-scroll-trigger" href="{{ bloc.link }}">
|
||||
{{ bloc.text_button }}
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
|
||||
11
app/templates/themes/creative/blocs/_simple_article.html
Normal file
11
app/templates/themes/creative/blocs/_simple_article.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<section class="{{ bloc.property }}" id="{{ bloc.name }}" style="{{print_colors()}}" >
|
||||
<h2 class="section-heading text-center">{{ bloc.title }}</h2>
|
||||
<hr class="my-4">
|
||||
|
||||
<div class="container">
|
||||
<div class="col-lg-8 mx-auto">
|
||||
<p class="mb-4"> {{ bloc.text|safe }} </p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
8
app/templates/themes/creative/blocs/_text.html
Normal file
8
app/templates/themes/creative/blocs/_text.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<section class="{{ bloc.property }}" id="{{ bloc.name }}" style="{% include '_print_colors.css' %}">
|
||||
<div class="container">
|
||||
<div class="px-3 mx-auto">
|
||||
{{ bloc.text|safe }}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -50,3 +50,4 @@
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
{% include 'edit-tools/_disable-modify-button.html' %}
|
||||
@@ -7,8 +7,8 @@
|
||||
{{ form.title(value=bloc.title,
|
||||
class="form-control form-control-lg text-center") }}
|
||||
<h3> Description du lien </h3>
|
||||
{{ form.text(value=bloc.text,
|
||||
class="form-control text-center") }}
|
||||
{% include 'edit-tools/_editor-wysiwyg.html' %}
|
||||
|
||||
<h3> Votre lien (https://exemple.com) </h3>
|
||||
{{ form.link(value=bloc.link, class="form-control text-center") }}
|
||||
<br />
|
||||
@@ -23,4 +23,4 @@
|
||||
{% include 'edit-tools/_btn-save-cancel.html' %}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% include 'edit-tools/_disable-modify-button.html' %}
|
||||
12
app/templates/themes/creative/blocs/edit/_gallery.html
Normal file
12
app/templates/themes/creative/blocs/edit/_gallery.html
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
<form id="uploader" methods="POST" class="dropzone dz-clickable">
|
||||
{{ form.csrf_token }}
|
||||
</form>
|
||||
<div hx-get="{{ url_for('imagesList', page=page, blocname=bloc.name) }}" hx-trigger="load, every 7s">
|
||||
|
||||
</div>
|
||||
|
||||
<div id="editImage">
|
||||
</div>
|
||||
{% include '_js_dropzone.html' %}
|
||||
{% include 'edit-tools/_disable-modify-button.html' %}
|
||||
43
app/templates/themes/creative/blocs/edit/_head_image.html
Normal file
43
app/templates/themes/creative/blocs/edit/_head_image.html
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
<div class="container my-auto pt-5" style="background-color: rgba(0,0,0,0.3);">
|
||||
<form method='POST' action='/edit/{{ bloc.name }}' enctype="multipart/form-data" hx-swap="outerHTML" hx-target="#{{ bloc.name }}" hx-encoding="multipart/form-data">
|
||||
{{ form.csrf_token }}
|
||||
|
||||
|
||||
<div class="container my-auto">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-lg-10 form-group mx-auto">
|
||||
{% include 'edit-tools/_form-base.html' %}
|
||||
{{ form.title(value=bloc.title,
|
||||
class="form-control form-control-lg text-center text-uppercase")
|
||||
}}
|
||||
{% for error in form.title.errors %}
|
||||
<span style="color: red;">{{ error }}</span>
|
||||
{% endfor %}
|
||||
<hr>
|
||||
</div>
|
||||
<div class="col-lg-10 form-group mx-auto">
|
||||
{{ form.subtitle(value=bloc.subtitle,
|
||||
class="form-control form-control-lg text-center text-uppercase")
|
||||
}}
|
||||
{% for error in form.subtitle.errors %}
|
||||
<span style="color: red;">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="col-lg-8 form-group mx-auto">
|
||||
{{ form.image(class="form-control" ) }}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
{% include 'edit-tools/_btn-save-cancel.html' %}
|
||||
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
{% include 'edit-tools/_disable-modify-button.html' %}
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
<div class="container-fluid p-0">
|
||||
<div class="container-fluid p-0" id="editImageInfo">
|
||||
<form method='POST' action='/edit/images/{{ bloc.name }}/{{ image.file }}' hx-swap="outerHTML" hx-target="#editImg">
|
||||
{{ form.csrf_token }}
|
||||
<div class="row">
|
||||
<div class="col-lg-2 mx-auto my-4 text-center">
|
||||
<img class="img-fluid" src="/static/img/portfolio/thumbnails/{{ image.file }}" alt="{{ image.description }}">
|
||||
<img class="img-fluid" src="/public/img/thumbnails/{{ image.file }}" alt="{{ image.description }}">
|
||||
</div>
|
||||
<div class="col-lg-4 mx-auto my-4 text-center">
|
||||
<h3> Titre </h3>
|
||||
@@ -22,10 +22,13 @@
|
||||
{{ form.description(value=image.description, class="form-control text-center") }}
|
||||
<br/>
|
||||
<button class="btn btn-success" type="submit" data-dismiss="modal"
|
||||
hx-post="/edit/images/{{ bloc.name }}/{{ image.file }}"
|
||||
hx-post="/edit/images/{{ bloc.name }}/{{ image.file }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-target="#editImg"> Valider </button>
|
||||
<a class="btn btn-danger mx-auto" href="/edit/images/del/{{ image.nom_fichier }}">Supprimer l'image</a>
|
||||
hx-target="#editImageInfo"
|
||||
hx-swap="delete"> Valider </button>
|
||||
<button class="btn btn-danger mx-auto" hx-get="{{ url_for('delImage', page=page, bloc=bloc.name, image=image.file) }}"
|
||||
hx-swap="delete"
|
||||
hx-target="#editImageInfo"> Supprimer l'image</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="container my-auto">
|
||||
<form method='POST' action='/edit/{{ bloc.name }}' hx-swap="outerHTML" hx-target="#{{ bloc.name }}" enctype="multipart/form-data">
|
||||
<div class="container mt-5 py-5 pb-5" style="width:100%;">
|
||||
<form method='POST' action='/edit/{{ bloc.name }}' enctype="multipart/form-data" hx-swap="outerHTML" hx-target="#{{ bloc.name }}" hx-encoding="multipart/form-data">
|
||||
{{ form.csrf_token }}
|
||||
<div class="row">
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
</div>
|
||||
<div class="col-lg-8 form-group mx-auto">
|
||||
{% set f = form.text.process_data(bloc.text) %}
|
||||
<textarea class="form-control text-center" id="text" name="text"> {{ bloc.text }} </textarea>
|
||||
{% for error in form.text.errors %}
|
||||
{% include 'edit-tools/_editor-wysiwyg.html' %}
|
||||
|
||||
{% for error in form.text.errors %}
|
||||
<span style="color: red;">{{ error }}</span>
|
||||
{% endfor %}
|
||||
<br/>
|
||||
@@ -27,11 +28,11 @@
|
||||
<span style="color: red;">
|
||||
{{ error }}</span>
|
||||
{% endfor %}
|
||||
<h4> cible du bouton </h4>
|
||||
<h4> cible du bouton #bloc ou un lien (https://exemple.com) </h4>
|
||||
{{ form.link(value=bloc.link, class="form-control text-center") }}
|
||||
<br />
|
||||
</div>
|
||||
<div class="col-lg-3 form-group mx-auto">
|
||||
|
||||
<div class="col-lg-8 form-group mx-auto">
|
||||
{{ form.image(class="form-control" ) }}
|
||||
</div>
|
||||
{% include 'edit-tools/_btn-save-cancel.html' %}
|
||||
@@ -39,4 +40,4 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% include 'edit-tools/_disable-modify-button.html' %}
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
<section>
|
||||
<div class="container">
|
||||
<form method='POST' action='/edit/{{ bloc.name }}' >
|
||||
{{ form.csrf_token }}
|
||||
@@ -9,12 +9,12 @@
|
||||
{{ form.title(col=5,value=bloc.title,
|
||||
class="form-control form-control-lg text-center") }}
|
||||
<hr class="light my-4">
|
||||
<textarea class="form-control text-center" id="text" name="text"> {{ bloc.text }} </textarea>
|
||||
<br/>
|
||||
{% include 'edit-tools/_btn-save-cancel.html' %}
|
||||
{% include 'edit-tools/_editor-wysiwyg.html' %}
|
||||
|
||||
{% include 'edit-tools/_btn-save-cancel.html' %}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% include 'edit-tools/_disable-modify-button.html' %}
|
||||
16
app/templates/themes/creative/blocs/edit/_text.html
Normal file
16
app/templates/themes/creative/blocs/edit/_text.html
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
<div class="container">
|
||||
<form method='POST' action='/edit/{{ bloc.name }}' >
|
||||
{{ form.csrf_token }}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8 mx-auto text-center">
|
||||
{% include 'edit-tools/_form-base.html' %}
|
||||
{% include 'edit-tools/_editor-wysiwyg.html' %}
|
||||
</div>
|
||||
</div>
|
||||
{% include 'edit-tools/_btn-save-cancel.html' %}
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
{% include 'edit-tools/_disable-modify-button.html' %}
|
||||
@@ -1,11 +1,11 @@
|
||||
<section class="p-0">
|
||||
<section class="p-0" id="{{bloc.name}}">
|
||||
<div class="container-fluid p-0" id="editImg">
|
||||
<div class="row no-gutters ">
|
||||
{% for image in bloc.values() %}
|
||||
{% if image.file %}
|
||||
<div class="col-lg-4 col-sm-6 text-center">
|
||||
<a class="portfolio-box">
|
||||
<img class="img-fluid" src="/static/img/portfolio/thumbnails/{{ image.file }}" alt="{{ image.description }}">
|
||||
<img class="img-fluid" src="/public/img/thumbnails/{{ image.file }}" alt="{{ image.description }}">
|
||||
<div class="portfolio-box-caption">
|
||||
<div class="portfolio-box-caption-content">
|
||||
<div class="project-category text-faded">
|
||||
@@ -20,7 +20,7 @@
|
||||
</a>
|
||||
<button type="button" class="btn btn-success m-4"
|
||||
hx-get="/edit/images/{{ bloc.name }}/{{ image.file }}"
|
||||
hx-target="#editImg"
|
||||
hx-target="#editImage"
|
||||
hw-swap="none">
|
||||
<i class="fa fa-pencil-square-o"></i>
|
||||
</button>
|
||||
@@ -1,4 +1,9 @@
|
||||
|
||||
<script>
|
||||
function rm_node(idName){
|
||||
const element = document.getElementById(idName);
|
||||
element.remove();
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Bootstrap core JavaScript -->
|
||||
<script src="/static/vendors/jquery/jquery.min.js"></script>
|
||||
22
app/templates/themes/creative/pages/article_image.json
Normal file
22
app/templates/themes/creative/pages/article_image.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"blocs": {
|
||||
"bloc0": {
|
||||
"type": "head_image",
|
||||
"name": "bloc0",
|
||||
"bg_color": "#000000",
|
||||
"fg_color": "#000000",
|
||||
"title": "PAge avec une image de presentation",
|
||||
"bg_img": "bg_custom_bloc0image_entete_exemple.jpg",
|
||||
"property": "",
|
||||
"subtitle": "Votre sous-titre"
|
||||
},
|
||||
"bloc1": {
|
||||
"name": "bloc1",
|
||||
"type": "text",
|
||||
"text": "<h3>Votre\u00a0texte\u00a0libre\u00a0!\u00a0</h3><p></p><p>Vous\u00a0pouvez\u00a0\u00e9crire\u00a0ce\u00a0que\u00a0vous\u00a0voulez\u00a0ici</p>",
|
||||
"bg_color": "#000000",
|
||||
"fg_color": "#000000",
|
||||
"property": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
20
app/templates/themes/creative/pages/simple_article.json
Normal file
20
app/templates/themes/creative/pages/simple_article.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"blocs": {
|
||||
"test_bloc": {
|
||||
"name": "test_bloc",
|
||||
"type": "text",
|
||||
"title": "Salut c'est moi et ... voila quoi !!!!",
|
||||
"text": "<h2 class=\"ql-align-center\">Votre\u00a0titre\u00a0</h2><pre data-language=\"bash\">\n#!/bin/bash\necho \"Un exemple de code\"\n</pre><p></p><h2>Titre\u00a02</h2><h3>Titre\u00a03</h3><h4>Titre\u00a04\u00a0</h4><p></p><p class=\"ql-align-right\"><span style=\"background-color: rgb(255, 153, 0);\">Youpi\u00a0!!!!!!!!!!!!!!!</span></p><p class=\"ql-align-center\"></p><blockquote>Une\u00a0citation</blockquote><p></p><p></p><p>Vous\u00a0pouvez\u00a0aussi\u00a0empiler\u00a0les\u00a0blocs\u00a0de\u00a0texte\u00a0poiur\u00a0les\u00a0mettre\u00a0de\u00a0couleur\u00a0diff\u00e9rentes\u00a0par\u00a0exemple\u00a0</p><p></p><p></p>",
|
||||
"bg_color": "#000000",
|
||||
"fg_color": "#000000",
|
||||
"text_button": null,
|
||||
"link": null,
|
||||
"email": null,
|
||||
"address": null,
|
||||
"phone": null,
|
||||
"postal_code": null,
|
||||
"city": null,
|
||||
"property": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
451
app/templates/themes/creative/static/css/creative.css
Normal file
451
app/templates/themes/creative/static/css/creative.css
Normal file
@@ -0,0 +1,451 @@
|
||||
body,
|
||||
html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Merriweather', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
hr {
|
||||
max-width: 50px;
|
||||
border-width: 3px;
|
||||
border-color: #F05F40;
|
||||
}
|
||||
|
||||
hr.light {
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #F05F40;
|
||||
-webkit-transition: all 0.2s;
|
||||
-moz-transition: all 0.2s;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.btn-success{
|
||||
z-index: 999;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.img-fluid {
|
||||
position: relative;
|
||||
z-index:-30;
|
||||
}
|
||||
a:hover {
|
||||
color: #f05f40;
|
||||
}
|
||||
|
||||
.modal-backdrop{
|
||||
z-index:auto
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
.bg-primary {
|
||||
background-color: #F05F40 !important;
|
||||
}
|
||||
|
||||
.bg-dark {
|
||||
background-color: #212529 !important;
|
||||
}
|
||||
|
||||
.text-faded {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.ql-align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ql-align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.ql-align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding: 60px 80px 40px;
|
||||
position: relative;
|
||||
}
|
||||
blockquote p {
|
||||
font-size: 35px;
|
||||
font-weight: 700px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/*blockquote p::before {
|
||||
content: "\f095";
|
||||
font-family: FontAwesome;
|
||||
display: inline-block;
|
||||
padding-right: 6px;
|
||||
vertical-align: middle;
|
||||
font-size: 180px;
|
||||
}*/
|
||||
|
||||
blockquote:before {
|
||||
position: absolute;
|
||||
font-family: 'FontAwesome';
|
||||
top: 0;
|
||||
content:"\f10d";
|
||||
font-size: 200px;
|
||||
color: rgba(0,0,0,0.1);
|
||||
|
||||
}
|
||||
|
||||
blockquote::after {
|
||||
content: "";
|
||||
top: 20px;
|
||||
left: 50%;
|
||||
margin-left: -100px;
|
||||
position: absolute;
|
||||
height: 3px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
blockquote{
|
||||
font-size: 1.4em;
|
||||
width:60%;
|
||||
margin:50px auto;
|
||||
font-style:italic;
|
||||
color: #555555;
|
||||
padding:1.2em 30px 1.2em 75px;
|
||||
border-left:8px solid #f05f40;
|
||||
line-height:1.6;
|
||||
position: relative;
|
||||
background:#EDEDED;
|
||||
}
|
||||
|
||||
blockquote::before{
|
||||
font-family:Arial;
|
||||
content: "\201C";
|
||||
color:#f05f40;
|
||||
font-size:4em;
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top:-10px;
|
||||
}
|
||||
|
||||
blockquote::after{
|
||||
content: '';
|
||||
}
|
||||
|
||||
blockquote span{
|
||||
display:block;
|
||||
color:#333333;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
margin-top:1em;
|
||||
}
|
||||
|
||||
section {
|
||||
padding: 8rem 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.section-heading {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
::-moz-selection {
|
||||
color: #fff;
|
||||
background: #212529;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
::selection {
|
||||
color: #fff;
|
||||
background: #212529;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
img::selection {
|
||||
color: #fff;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
img::-moz-selection {
|
||||
color: #fff;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
#mainNav {
|
||||
border-bottom: 1px solid rgba(33, 37, 41, 0.1);
|
||||
background-color: #fff;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
|
||||
-webkit-transition: all 0.2s;
|
||||
-moz-transition: all 0.2s;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
#mainNav .navbar-brand {
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
color: #F05F40;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
#mainNav .navbar-brand:focus, #mainNav .navbar-brand:hover {
|
||||
color: #f05f40;
|
||||
}
|
||||
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link,
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus {
|
||||
font-size: .9rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:hover,
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus:hover {
|
||||
color: #F05F40;
|
||||
}
|
||||
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link.active,
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus.active {
|
||||
color: #F05F40 !important;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link.active:hover,
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus.active:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
#mainNav {
|
||||
border-color: transparent;
|
||||
background-color: rgba(0,0,0,0.7);
|
||||
}
|
||||
#mainNav .navbar-brand {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
#mainNav .navbar-brand:focus, #mainNav .navbar-brand:hover {
|
||||
color: #fff;
|
||||
}
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link {
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link,
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:hover,
|
||||
#mainNav .navbar-nav > li.nav-item > a.nav-link:focus:hover {
|
||||
color: #fff;
|
||||
}
|
||||
#mainNav.navbar-shrink {
|
||||
border-bottom: 1px solid rgba(33, 37, 41, 0.1);
|
||||
background-color: #fff;
|
||||
}
|
||||
#mainNav.navbar-shrink .navbar-brand {
|
||||
color: #F05F40;
|
||||
}
|
||||
#mainNav.navbar-shrink .navbar-brand:focus, #mainNav.navbar-shrink .navbar-brand:hover {
|
||||
color: #f05f40;
|
||||
}
|
||||
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link,
|
||||
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:focus {
|
||||
color: #212529;
|
||||
}
|
||||
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:hover,
|
||||
#mainNav.navbar-shrink .navbar-nav > li.nav-item > a.nav-link:focus:hover {
|
||||
color: #F05F40;
|
||||
}
|
||||
}
|
||||
|
||||
header.masthead {
|
||||
padding-top: 10rem;
|
||||
padding-bottom: calc(10rem - 56px);
|
||||
background-position: center center;
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
header.article-img {
|
||||
padding-top: 10rem;
|
||||
padding-bottom: calc(10rem - 56px);
|
||||
background-position: center center;
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
|
||||
header.article-img header.masthead hr {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
header.article-img header.masthead h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
header.article-img header.masthead p {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
header.masthead p {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
header.article-img {
|
||||
height: 50vh;
|
||||
min-height: 300px;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
header.masthead {
|
||||
height: 100vh;
|
||||
min-height: 650px;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
header.article-img header.masthead h1 {
|
||||
font-size: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
header.article-img header.masthead h1 {
|
||||
font-size: 4rem;
|
||||
}
|
||||
.btn-success {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.service-box {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
|
||||
.portfolio-box {
|
||||
position: relative;
|
||||
display: block;
|
||||
max-width: 650px;
|
||||
margin: 0 auto;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.portfolio-box .portfolio-box-caption {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
opacity: 0;
|
||||
color: #fff;
|
||||
background: rgba(240, 95, 64, 0.9);
|
||||
-webkit-transition: all 0.2s;
|
||||
-moz-transition: all 0.2s;
|
||||
transition: all 0.2s;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 100%;
|
||||
transform: translateY(-50%);
|
||||
text-align: center;
|
||||
z-index:-10;
|
||||
}
|
||||
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category,
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
|
||||
padding: 0 15px;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.portfolio-box:hover .portfolio-box-caption {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.portfolio-box:focus {
|
||||
outline: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category {
|
||||
font-size: 16px;
|
||||
}
|
||||
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
color: #F05F40 !important;
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
border: none;
|
||||
border-radius: 300px;
|
||||
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.btn-xl {
|
||||
padding: 1rem 2rem;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #F05F40;
|
||||
border-color: #F05F40;
|
||||
}
|
||||
|
||||
.btn-primary:hover, .btn-primary:focus, .btn-primary:active {
|
||||
color: #fff;
|
||||
background-color: #ee4b28 !important;
|
||||
}
|
||||
|
||||
.btn-primary:active, .btn-primary:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba(240, 95, 64, 0.5) !important;
|
||||
}
|
||||
|
||||
section.bg-dark p {
|
||||
|
||||
padding-bottom: 3rem;
|
||||
|
||||
}
|
||||
|
||||
section.bg-dark {
|
||||
padding-top: 3rem;
|
||||
padding-bottom: 3rem;
|
||||
}
|
||||
73
app/templates/themes/creative/static/css/fontes-creative.css
Normal file
73
app/templates/themes/creative/static/css/fontes-creative.css
Normal file
@@ -0,0 +1,73 @@
|
||||
@font-face {
|
||||
font-family: 'Merryweather';
|
||||
src:url("../fontes/Merryweather/Merryweather-Regular.woff");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Merryweather';
|
||||
src:url("../fontes/Merryweather/Merryweather-Bold.woff");
|
||||
font-weight: bold;
|
||||
font-style: bold;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src:url("../fontes/OpenSans/open-sans-v15-latin-regular.woff2");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src:url("../fontes/OpenSans/open-sans-v15-latin-italic.woff2");
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src:url("../fontes/OpenSans/open-sans-v15-latin-300.woff2");
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src:url("../fontes/OpenSans/open-sans-v15-latin-300italic.woff2");
|
||||
font-weight: 300;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src:url("../fontes/OpenSans/open-sans-v15-latin-600.woff2");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src:url("../fontes/OpenSans/open-sans-v15-latin-600italic.woff2");
|
||||
font-weight: 600;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src:url("../fontes/OpenSans/open-sans-v15-latin-700.woff2");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src:url("../fontes/OpenSans/open-sans-v15-latin-700italic.woff2");
|
||||
font-weight: 700;
|
||||
font-style: italic;
|
||||
}
|
||||
31
app/templates/themes/creative/static/css/fontes.css
Normal file
31
app/templates/themes/creative/static/css/fontes.css
Normal file
@@ -0,0 +1,31 @@
|
||||
/*Import de fontes trouver sur font2u.com Bon site !!!! */
|
||||
|
||||
@font-face {
|
||||
font-family: 'Lora';
|
||||
src:url("../fonts/Lora-Regular.woff");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Raleway';
|
||||
src:url("../fonts/Raleway-Regular.woff");
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Raleway';
|
||||
src:url("../fonts/Raleway-Bold.woff");
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family:'Lora-Italic';
|
||||
src:url("../fonts/Lora-Italic.woff");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family:'Roboto';
|
||||
src:url("../fonts/Roboto-Regular.woff");
|
||||
}
|
||||
|
||||
3
app/templates/themes/creative/static/css/prism.min.css
vendored
Normal file
3
app/templates/themes/creative/static/css/prism.min.css
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/* PrismJS 1.30.0
|
||||
https://prismjs.com/download#themes=prism-okaidia&languages=markup+css+clike+javascript+bash+c+cpp+markdown+markup-templating+nginx+php+python */
|
||||
code[class*=language-],pre[data-language*=language-]{color:#f8f8f2;background:0 0;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8292a2}.token.punctuation{color:#f8f8f2}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
106
app/templates/themes/creative/static/js/creative.js
Normal file
106
app/templates/themes/creative/static/js/creative.js
Normal file
@@ -0,0 +1,106 @@
|
||||
(function($) {
|
||||
"use strict"; // Start of use strict
|
||||
|
||||
// Smooth scrolling using jQuery easing
|
||||
$('a.js-scroll-trigger[href*="#"]:not([href="#"])').click(function() {
|
||||
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
|
||||
var target = $(this.hash);
|
||||
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
|
||||
if (target.length) {
|
||||
$('html, body').animate({
|
||||
scrollTop: (target.offset().top - 57)
|
||||
}, 1000, "easeInOutExpo");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Closes responsive menu when a scroll trigger link is clicked
|
||||
$('.js-scroll-trigger').click(function() {
|
||||
$('.navbar-collapse').collapse('hide');
|
||||
});
|
||||
|
||||
// Activate scrollspy to add active class to navbar items on scroll
|
||||
$('body').scrollspy({
|
||||
target: '#mainNav',
|
||||
offset: 57
|
||||
});
|
||||
|
||||
// Collapse Navbar
|
||||
var navbarCollapse = function() {
|
||||
if ($("#mainNav").offset().top > 100) {
|
||||
$("#mainNav").addClass("navbar-shrink");
|
||||
} else {
|
||||
$("#mainNav").removeClass("navbar-shrink");
|
||||
}
|
||||
};
|
||||
// Collapse now if page is not at top
|
||||
navbarCollapse();
|
||||
// Collapse the navbar when page is scrolled
|
||||
$(window).scroll(navbarCollapse);
|
||||
|
||||
// Scroll reveal calls
|
||||
window.sr = ScrollReveal();
|
||||
sr.reveal('.sr-icons', {
|
||||
duration: 600,
|
||||
scale: 0.3,
|
||||
distance: '0px'
|
||||
}, 200);
|
||||
sr.reveal('.sr-button', {
|
||||
duration: 1000,
|
||||
delay: 200
|
||||
});
|
||||
sr.reveal('.sr-contact', {
|
||||
duration: 600,
|
||||
scale: 0.3,
|
||||
distance: '0px'
|
||||
}, 300);
|
||||
|
||||
// Magnific popup calls
|
||||
$('.popup-gallery').magnificPopup({
|
||||
delegate: 'a',
|
||||
type: 'image',
|
||||
tLoading: 'Loading image #%curr%...',
|
||||
mainClass: 'mfp-img-mobile',
|
||||
gallery: {
|
||||
enabled: true,
|
||||
navigateByImgClick: true,
|
||||
preload: [0, 1]
|
||||
},
|
||||
image: {
|
||||
tError: '<a href="%url%">The image #%curr%</a> could not be loaded.'
|
||||
}
|
||||
});
|
||||
|
||||
$(".obfuscate").each(function () {
|
||||
|
||||
$(this).html($(this).html()
|
||||
.replace("__chez__", "@").replace(/\.\.\./g, ".")
|
||||
.replace(/Un/g, "1")
|
||||
.replace(/Deux/g, "2")
|
||||
.replace(/Trois/g, "3")
|
||||
.replace(/Quatre/g, "4")
|
||||
.replace(/Cinq/g, "5")
|
||||
.replace(/Six/g, "6")
|
||||
.replace(/Sept/g, "7")
|
||||
.replace(/Huit/g, "8")
|
||||
.replace(/Neuf/g, "9")
|
||||
.replace(/Zero/g, "0"))
|
||||
|
||||
$(this).attr("href", $(this).attr("href")
|
||||
.replace("__chez__", "@").replace(/\.\.\./g, ".")
|
||||
.replace(/Un/g, "1")
|
||||
.replace(/Deux/g, "2")
|
||||
.replace(/Trois/g, "3")
|
||||
.replace(/Quatre/g, "4")
|
||||
.replace(/Cinq/g, "5")
|
||||
.replace(/Six/g, "6")
|
||||
.replace(/Sept/g, "7")
|
||||
.replace(/Huit/g, "8")
|
||||
.replace(/Neuf/g, "9")
|
||||
.replace(/Zero/g, "0"))
|
||||
|
||||
});
|
||||
|
||||
|
||||
})(jQuery); // End of use strict
|
||||
15
app/templates/themes/creative/static/js/prism.js
Normal file
15
app/templates/themes/creative/static/js/prism.js
Normal file
File diff suppressed because one or more lines are too long
1912
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-grid.css
vendored
Normal file
1912
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-grid.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-grid.css.map
vendored
Normal file
1
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-grid.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-grid.min.css
vendored
Normal file
7
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-grid.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-grid.min.css.map
vendored
Normal file
1
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-grid.min.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
331
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-reboot.css
vendored
Normal file
331
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-reboot.css
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v4.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2018 The Bootstrap Authors
|
||||
* Copyright 2011-2018 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
line-height: 1.15;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-ms-overflow-style: scrollbar;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
@-ms-viewport {
|
||||
width: device-width;
|
||||
}
|
||||
|
||||
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: #212529;
|
||||
text-align: left;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
[tabindex="-1"]:focus {
|
||||
outline: 0 !important;
|
||||
}
|
||||
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title],
|
||||
abbr[data-original-title] {
|
||||
text-decoration: underline;
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: .5rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
background-color: transparent;
|
||||
-webkit-text-decoration-skip: objects;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #0056b3;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]):focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
-ms-overflow-style: scrollbar;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
svg {
|
||||
overflow: hidden;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
color: #6c757d;
|
||||
text-align: left;
|
||||
caption-side: bottom;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
outline: 1px dotted;
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
button,
|
||||
html [type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
input[type="radio"],
|
||||
input[type="checkbox"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input[type="date"],
|
||||
input[type="time"],
|
||||
input[type="datetime-local"],
|
||||
input[type="month"] {
|
||||
-webkit-appearance: listbox;
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: .5rem;
|
||||
font-size: 1.5rem;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type="search"] {
|
||||
outline-offset: -2px;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
[type="search"]::-webkit-search-cancel-button,
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
||||
1
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-reboot.css.map
vendored
Normal file
1
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-reboot.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
8
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-reboot.min.css
vendored
Normal file
8
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-reboot.min.css
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v4.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2018 The Bootstrap Authors
|
||||
* Copyright 2011-2018 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
|
||||
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
|
||||
1
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-reboot.min.css.map
vendored
Normal file
1
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap-reboot.min.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
9030
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap.css
vendored
Normal file
9030
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap.css.map
vendored
Normal file
1
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap.min.css
vendored
Normal file
7
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap.min.css.map
vendored
Normal file
1
app/templates/themes/creative/static/vendors/bootstrap/css/bootstrap.min.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
6461
app/templates/themes/creative/static/vendors/bootstrap/js/bootstrap.bundle.js
vendored
Normal file
6461
app/templates/themes/creative/static/vendors/bootstrap/js/bootstrap.bundle.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
app/templates/themes/creative/static/vendors/bootstrap/js/bootstrap.bundle.js.map
vendored
Normal file
1
app/templates/themes/creative/static/vendors/bootstrap/js/bootstrap.bundle.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
app/templates/themes/creative/static/vendors/bootstrap/js/bootstrap.bundle.min.js
vendored
Normal file
7
app/templates/themes/creative/static/vendors/bootstrap/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
app/templates/themes/creative/static/vendors/bootstrap/js/bootstrap.bundle.min.js.map
vendored
Normal file
1
app/templates/themes/creative/static/vendors/bootstrap/js/bootstrap.bundle.min.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user