1
0
mirror of https://github.com/typemill/typemill.git synced 2025-01-17 21:38:25 +01:00

Version 1.3.3: Posts and Pages

This commit is contained in:
trendschau 2020-02-26 22:01:26 +01:00
commit 3069d0dc05
11 changed files with 235 additions and 54 deletions

View File

@ -683,6 +683,9 @@ form .large, form .medium, form .small{
width: 100%;
display: block;
}
form .hidden{
display: none;
}
.large img{
width: 100%;
}
@ -932,7 +935,7 @@ ul.cardInfo{
border: 0px;
}
.cardFields.open{
max-height: 2800px;
max-height: 5000px;
transition: max-height 0.5s ease-in;
overflow: hidden;
border: 1px;
@ -957,6 +960,19 @@ ul.cardInfo{
display: inline-block;
margin: 10px 0;
}
.cardField.full{
width: 100%;
}
.cardField.half{
width: 49.5%;
float: left;
margin-right:0.5%;
}
.cardField.third{
width: 32%;
float:left;
margin-right: 1%;
}
.cardField label{
width: 100%;
margin-top: 0px;
@ -1650,6 +1666,65 @@ button.hdown:hover,button.hdown:focus,button.hdown:active{
}
.blog-post{
}
.blog-post svg{
color: #ccc;
margin-right: 5px;
}
.blog-post a,
.blog-post a:link,
.blog-post a:visited{
color: #444;
text-decoration: none;
display: inline-block;
width: 100%;
padding: 0px 15px;
margin: 5px 0;
border-left: 3px solid;
box-sizing: border-box;
background-color: #f9f8f6;
}
.blog-post a:focus,
.blog-post a:hover,
.blog-post a:active{
background-color: #f6f5f3;
}
.blog-post a.unpublished{
border-color: #cc4146;
}
.blog-post a.published{
border-color: #66b0a3;
}
.blog-post a.modified{
border-color: #FFA500;
}
.blog-post .post-date{
float: right;
font-size: 0.8em;
font-weight: 300;
color: #444;
}
.posts.formWrapper{
margin: 20px 0;
}
.posts input{
width: 80%;
float: left;
}
button.post-button{
color: #f9f8f6;
background: #66b0a3;
border: 0px;
width: 20%;
text-align: center;
}
button.post-button:hover{
background: #4D978A;
}
/* .format-bar at the bottom of the page */
/********************

View File

@ -75,6 +75,24 @@
</section>
{% if item.elementType == "folder" %}
<section id="posts" v-if="posts">
<div class="posts formWrapper">
<input v-model="posttitle" type="text" maxlength="60" name="title" placeholder="add a short title">
<button type="button" @click.prevent="createPost()" class="post-button">create new post</button>
</div>
<div>
<single-post
v-for="post in posts"
v-bind:key="post.keyPath"
v-bind:post="post"
></single-post>
</div>
</section>
{% endif %}
{% include 'editor/publish-controller.twig' %}
<input id="path" type="hidden" value="{{ item.urlRel }}" required readonly />

View File

@ -18,7 +18,6 @@ let typemillUtilities = {
addYoutubePlayButton: function(element)
{
console.info(element.parentNode);
element.parentNode.classList.add("video-container");
var youtubePlaybutton = document.createElement("button");
@ -28,12 +27,6 @@ let typemillUtilities = {
element.parentNode.appendChild(youtubePlaybutton);
},
start: function(){
this.setYoutubeItems();
this.addYoutubePlayButtons();
this.listenToYoutube();
},
listenToYoutube: function(){
document.addEventListener('click', function (event) {
@ -58,4 +51,10 @@ let typemillUtilities = {
}
}, true);
},
start: function(){
this.setYoutubeItems();
this.addYoutubePlayButtons();
this.listenToYoutube();
},
};

View File

@ -1,13 +1,14 @@
const FormBus = new Vue();
Vue.component('component-text', {
props: ['class', 'id', 'description', 'maxlength', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
props: ['class', 'id', 'description', 'maxlength', 'hidden', 'readonly', 'required', 'disabled', 'placeholder', 'label', 'name', 'type', 'value', 'errors'],
template: '<div class="large">' +
'<label>{{ $t(label) }}</label>' +
'<input type="text"' +
' :id="id"' +
' :maxlength="maxlength"' +
' :readonly="readonly"' +
' :hidden="hidden"' +
' :required="required"' +
' :disabled="disabled"' +
' :name="name"' +
@ -357,11 +358,10 @@ Vue.component('tab-meta', {
let meta = new Vue({
i18n: new VueI18n({
locale: language,
messages: vuejsLabels
}),
i18n: new VueI18n({
locale: language,
messages: vuejsLabels
}),
delimiters: ['${', '}'],
el: '#metanav',
data: function () {
@ -416,6 +416,16 @@ let meta = new Vue({
self.formData = response.data.metadata;
var item = response.data.item;
if(item.elementType == "folder" && item.contains == "posts")
{
posts.posts = item.folderContent;
posts.folderid = item.keyPath;
}
else
{
posts.posts = false;
}
})
.catch(function (error)
{
@ -449,6 +459,17 @@ let meta = new Vue({
{
navi.items = response.data.structure;
}
var item = response.data.item;
if(item.elementType == "folder" && item.contains == "posts")
{
posts.posts = item.folderContent;
posts.folderid = item.keyPath;
}
else
{
posts.posts = false;
}
})
.catch(function (error)
{

View File

@ -1,6 +1,6 @@
const navcomponent = Vue.component('navigation', {
template: '#navigation-template',
props: ['homepage', 'showForm', 'name', 'hide', 'newItem', 'parent', 'active', 'filetype', 'status', 'elementtype', 'element', 'folder', 'level', 'url', 'root', 'freeze'],
props: ['homepage', 'showForm', 'name', 'hide', 'newItem', 'parent', 'active', 'filetype', 'status', 'elementtype', 'contains', 'element', 'folder', 'level', 'url', 'root', 'freeze'],
data: function () {
return {
showForm: false,
@ -134,9 +134,9 @@ const navcomponent = Vue.component('navigation', {
{
publishController.errors.message = false;
if(this.$root.$data.format.test(this.newItem) || !this.newItem || this.newItem.length > 40)
if(this.$root.$data.format.test(this.newItem) || !this.newItem || this.newItem.length > 60)
{
publishController.errors.message = 'Special Characters are not allowed. Length between 1 and 40.';
publishController.errors.message = 'Special Characters are not allowed. Length between 1 and 60.';
return;
}
@ -194,13 +194,13 @@ let navi = new Vue({
data: function () {
return {
title: "Navigation",
items: JSON.parse(document.getElementById("data-navi").dataset.navi),
items: navigation,
homepage: JSON.parse(document.getElementById("data-navi").dataset.homepage),
editormode: document.getElementById("data-navi").dataset.editormode,
root: document.getElementById("main").dataset.url,
freeze: false,
modalWindow: false,
format: /[!@#$%^&*()_+=\[\]{};':"\\|,.<>\/?]/,
format: /[@#*()=\[\]{};:"\\|,.<>\/]/,
folderName: '',
showForm: false,
newItem: '',

View File

@ -0,0 +1,68 @@
Vue.component('single-post', {
props: ['post'],
template: '<div class="blog-post">' +
'<a :class="post.status" :href="getUrl(post.urlRelWoF)">' +
'<h4><svg class="icon baseline icon-file-text-o"><use xlink:href="#icon-file-text-o"></use></svg> {{ post.name }} <span class="post-date">{{ getDate(post.order) }}</span></h4>' +
'</a>' +
'</div>',
methods: {
getUrl: function(posturl){
return this.$root.$data.root + '/tm/content/' + this.$root.$data.editormode + posturl;
},
getDate: function(str){
var cleandate = [str.slice(0,4), str.slice(4,6), str.slice(6,8)];
return cleandate.join("-");
}
}
})
let posts = new Vue({
el: "#posts",
data: function () {
return {
posts: false,
posttitle: '',
folderid: false,
format: /[@#*()=\[\]{};:"\\|,.<>\/]/,
root: document.getElementById("main").dataset.url,
editormode: document.getElementById("data-navi").dataset.editormode
}
},
methods: {
createPost: function(evt){
publishController.errors.message = false;
if(this.format.test(this.posttitle) || this.posttitle == '' || this.posttitle.length > 60)
{
publishController.errors.message = 'Special Characters are not allowed. Length between 1 and 60.';
return;
}
var self = this;
myaxios.post('/api/v1/post',{
'folder_id': this.folderid,
'item_name': this.posttitle,
'type': 'file',
'url': document.getElementById("path").value,
'csrf_name': document.getElementById("csrf_name").value,
'csrf_value': document.getElementById("csrf_value").value,
})
.then(function (response) {
if(response.data.posts)
{
self.posts = response.data.posts.folderContent;
self.posttitle = '';
}
})
.catch(function (error)
{
if(error.response)
{
publishController.errors.message = error.response.data.errors;
}
});
}
}
})

View File

@ -163,33 +163,35 @@
<article>
{% block content %}{% endblock %}
</article>
<footer></footer>
<footer></footer>
</div>
<script src="{{ base_url }}/system/author/js/axios.min.js?20191124"></script>
<script>
const myaxios = axios.create();
myaxios.defaults.baseURL = "{{ base_url }}";
</script>
<script src="{{ base_url }}/system/author/js/vue.min.js?20200226"></script>
<script src="{{ base_url }}/system/author/js/vue-i18n.min.js?20200226"></script>
<script src="{{ base_url }}/system/author/js/autosize.min.js?20200226"></script>
<script src="{{ base_url }}/system/author/js/sortable.min.js?20200226"></script>
<script src="{{ base_url }}/system/author/js/vuedraggable.umd.min.js?20200226"></script>
<script src="{{ base_url }}/system/author/js/author.js?20200226"></script>
<script src="{{ base_url }}/system/author/js/vue-publishcontroller.js?20200226"></script>
<script src="{{ base_url }}/system/author/js/vue-blox-config.js?20200226"></script>
<script src="{{ base_url }}/system/author/js/vue.min.js?20200120"></script>
<script src="{{ base_url }}/system/author/js/vue-i18n.min.js?20200120"></script>
<script src="{{ base_url }}/system/author/js/autosize.min.js?20200120"></script>
<script src="{{ base_url }}/system/author/js/author.js?20200120"></script>
<script src="{{ base_url }}/system/author/js/vue-publishcontroller.js?20200120"></script>
<script src="{{ base_url }}/system/author/js/vue-blox-config.js?20200120"></script>
<script>
let formatConfig = {{ settings.formats|json_encode() }};
let language = {{ settings.language|json_encode() }};
let vuejsLabels = {{ settings.vuejsLabels|json_encode() }};
let navigation = {{ navigation|json_encode() }};
</script>
{{ assets.renderEditorJS() }}
<script src="{{ base_url }}/system/author/js/vue-blox.js?20200226"></script>
<script src="{{ base_url }}/system/author/js/vue-meta.js?20200226"></script>
<script src="{{ base_url }}/system/author/js/vue-navi.js?20200226"></script>
<script src="{{ base_url }}/system/author/js/lazy-video.js?20200226"></script>
<script src="{{ base_url }}/system/author/js/vue-blox.js?20200120"></script>
<script src="{{ base_url }}/system/author/js/vue-posts.js?20200120"></script>
<script src="{{ base_url }}/system/author/js/sortable.min.js?20200120"></script>
<script src="{{ base_url }}/system/author/js/vuedraggable.umd.min.js?20200120"></script>
<script src="{{ base_url }}/system/author/js/vue-navi.js?20200120"></script>
<script src="{{ base_url }}/system/author/js/vue-meta.js?20200120"></script>
<script src="{{ base_url }}/system/author/js/lazy-video.js?20200120"></script>
{{ assets.renderJS() }}

View File

@ -27,9 +27,15 @@ meta:
description: Used as fallback when no manual date is set.
created:
type: date
label: Created at (readonly)
label: Created at (read only)
readonly: readonly
class: medium
time:
type: text
readonly: readonly
hidden: true
class: hidden
pattern: '[0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
navtitle:
type: text
label: Navigation Title
@ -45,17 +51,6 @@ meta:
# label: Show page to
# class: medium
# options:
# null: null
# public: Public (standard)
# members: Members only (logged in)
# customers: Customers only (paying)
# list:
# type: select
# label: List sub-pages
# class: medium
# options:
# null: null
# standard: Standard order
# revert: Reverse order
# asc: Date ascending
# desc: Date descending
# customers: Customers only (paying)

View File

@ -1,5 +1,5 @@
<nav id="sidebar-menu" class="sidebar-menu--content">
<div id="data-navi" data-navi='{{ navigation|json_encode() }}' data-homepage='{{ homepage|json_encode() }}' data-editormode="{{settings.editor}}"></div>
<div id="data-navi" data-homepage='{{ homepage|json_encode() }}' data-editormode="{{settings.editor}}"></div>
<div id="mobile-menu" class="menu-action">{{ __('Menu') }} <span class="button-arrow"></span></div>
<div id="navi" class="content-navi" v-model="freeze" v-cloak>
<div class="navi-list">
@ -17,7 +17,7 @@
animation="150"
:disabled="freeze">
<navigation
v-for="item in items"
v-for="item in items"
ref="draggit"
:freeze="freeze"
:name="item.name"
@ -30,8 +30,9 @@
:id="item.keyPath"
:key="item.keyPath"
:elementtype="item.elementType"
:contains="item.contains"
:filetype="item.fileType"
:status="item.status"
:status="item.status"
:folder="item.folderContent"
></navigation>
</draggable>
@ -61,7 +62,7 @@
<a v-bind:href="getUrl(root, url)" :class="checkActive(active,parent)"><span class="iconwrapper"><svg class="icon" :class="getIconClass(elementtype, filetype, hide)"><use :xlink:href="getIcon(elementtype, filetype, hide)"></use></svg></span><span :class="getLevel(level)">{{ name }}</span><span class="movewrapper"><span class="movewrapper"><svg class="icon icon-arrows-v"><use xlink:href="#icon-arrows-v"></use></svg></span></a>
<draggable v-if="folder" class="navi-list" tag="ul"
@start="onStart"
@end="onEnd"
@end="onEnd"
:list="folder"
:move="checkMove"
group="file"
@ -69,6 +70,7 @@
:disabled="freeze">
<navigation
v-for="item in folder"
v-if="contains == 'pages'"
ref="draggit"
:freeze="freeze"
:name="item.name"
@ -82,11 +84,12 @@
:key="item.keyPath"
:filetype="item.fileType"
:status="item.status"
:elementtype="item.elementType"
:elementtype="item.elementType"
:contains="item.contains"
:folder="item.folderContent"
></navigation>
</draggable>
<ul v-if="folder" class="navi-list">
<ul v-if="folder && contains == 'pages'" class="navi-list">
<li class="navi-item file">
<span class="iconwrapper">
<svg class="icon icon-plus"><use xlink:href="#icon-plus"></use></svg>

View File

@ -1,4 +1,4 @@
<div class="cardField{{ errors[itemName][field.name] ? ' error' : '' }}">
<div class="cardField{{ errors[itemName][field.name] ? ' error' : '' }}{{field.fieldsize ? ' ' ~ field.fieldsize : ''}}">
<label for="{{ itemName }}[{{ field.name }}]">{{ __( field.getLabel() ) }}
{% if field.getAttribute('required') %}<strong><abbr title="{{ __('required') }}">*</abbr></strong>{% endif %}

View File

@ -22,7 +22,7 @@
<div class="cardInner cardHead">
{% if theme.img %}
<img src="{{ base_url() }}/themes/{{themeName}}/{{themeName}}.jpg" />
<img src="{{ base_url() }}/themes/{{themeName}}/{{ theme.img }}" />
{% else %}
<div class="no-preview">{{ __('No Preview') }}</div>
{% endif %}
@ -32,7 +32,7 @@
<div class="cardDescription">
<h2>{{ themeName }}</h2>
<p>{{ __('TYPEMILL_DESCRIPTION') }}</p>
<p>{{ theme.description }}</p>
<ul class="cardInfo">
<li>{{ theme.version ? theme.version : __('Unknown') }}</li><li>
{{ theme.licence ? theme.licence : __('Unkown') }}</li><li>