Update templates
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
{% extends "skeleton.html" %}
|
{% extends "skeleton.html" %}
|
||||||
{% block body %}
|
{% block content %}
|
||||||
|
|
||||||
<h3>Профиль</h3>
|
<h3>Профиль</h3>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<p>Зарегистрирован: {{ user.created.strftime('%Y-%m-%d') }}</p>
|
<p>Зарегистрирован: {{ user.created.strftime('%Y-%m-%d') }}</p>
|
||||||
|
|
||||||
{% endblock body %}
|
{% endblock content %}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "skeleton.html" %}
|
{% extends "skeleton.html" %}
|
||||||
{% block body %}
|
{% block content %}
|
||||||
|
|
||||||
{% raw %}
|
{% raw %}
|
||||||
<h3>
|
<h3>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "skeleton.html" %}
|
{% extends "skeleton.html" %}
|
||||||
{% block body %}
|
{% block content %}
|
||||||
|
|
||||||
<h3>
|
<h3>
|
||||||
<div class="btn btn-outline-success float-right" v-on:click="showFormNewTag"><i class="fa fa-plus"></i></div>
|
<div class="btn btn-outline-success float-right" v-on:click="showFormNewTag"><i class="fa fa-plus"></i></div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "skeleton.html" %}
|
{% extends "skeleton.html" %}
|
||||||
{% block body %}
|
{% block content %}
|
||||||
|
|
||||||
<h3>Список пользователей</h3>
|
<h3>Список пользователей</h3>
|
||||||
<hr />
|
<hr />
|
||||||
|
|||||||
113
myapp/static/components/pagination.js
Normal file
113
myapp/static/components/pagination.js
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
<pagination-component v-bind:pagination="pagination" v-bind:click-handler="getRecipes"></pagination-component>
|
||||||
|
<script type="text/javascript" src="/static/components/pagination.js"></script>
|
||||||
|
|
||||||
|
Vue
|
||||||
|
...
|
||||||
|
data: {
|
||||||
|
pagination: {
|
||||||
|
page: 1,
|
||||||
|
per_page: {{ per_page }},
|
||||||
|
size: {{ pagedata['count'] }}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
Flask
|
||||||
|
pagedata['pagination'] = {
|
||||||
|
"page": page,
|
||||||
|
"per_page": app.config['ITEMS_ON_PAGE'],
|
||||||
|
"size": 0
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
let paginationTemplate = `<div class="row">
|
||||||
|
<div class="col py-2 text-center">
|
||||||
|
<div class="btn btn-outline-secondary" v-if="pages()<=1">...</div>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
<button type="button" class="btn btn-outline-secondary pull-left" v-if="has_prev" v-on:click="handlePageSelected(pagination.page-1)">Предыдущая</button>
|
||||||
|
|
||||||
|
<template v-for="page in iter_pages">
|
||||||
|
<button type="button" class="btn btn-outline-secondary mr-1" v-if="page" v-on:click="handlePageSelected(page)">{{ page }}</button>
|
||||||
|
<div class="btn btn-outline-secondary mr-1" v-else>...</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-outline-secondary float-right" v-if="has_next" v-on:click="handlePageSelected(pagination.page+1)">Следующая</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
Vue.component('pagination-component', {
|
||||||
|
template: paginationTemplate,
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props:{
|
||||||
|
pagination: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
default: {
|
||||||
|
page: 1,
|
||||||
|
per_page: 25,
|
||||||
|
size: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clickHandler: {
|
||||||
|
type: Function,
|
||||||
|
default: function() { }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handlePageSelected: function(selected) {
|
||||||
|
/* Установить номер текущей страницы и вызвать функция обновления
|
||||||
|
* страницы
|
||||||
|
*
|
||||||
|
* Аргументы:
|
||||||
|
* selected -- номер страницы
|
||||||
|
*/
|
||||||
|
let vm = this;
|
||||||
|
vm.pagination.page = selected;
|
||||||
|
vm.clickHandler();
|
||||||
|
},
|
||||||
|
pages: function() {
|
||||||
|
let vm = this;
|
||||||
|
return Math.ceil(vm.pagination.size/vm.pagination.per_page);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
has_prev: function() {
|
||||||
|
let vm = this;
|
||||||
|
return vm.pagination.page > 1;
|
||||||
|
},
|
||||||
|
has_next: function() {
|
||||||
|
let vm = this;
|
||||||
|
return vm.pagination.page < vm.pages();
|
||||||
|
},
|
||||||
|
iter_pages: function() {
|
||||||
|
/* */
|
||||||
|
let vm = this;
|
||||||
|
let last = 0;
|
||||||
|
let left_edge=2, left_current=2,
|
||||||
|
right_current=5, right_edge=2;
|
||||||
|
let result = [];
|
||||||
|
for (let num = 1; num < vm.pages()+1; num++) {
|
||||||
|
if (num <= left_edge ||
|
||||||
|
(num > vm.pagination.page - left_current - 1 &&
|
||||||
|
num < vm.pagination.page + right_current) ||
|
||||||
|
num > vm.pages() - right_edge) {
|
||||||
|
if (last + 1 != num) {
|
||||||
|
result.push(null);
|
||||||
|
} else {
|
||||||
|
result.push(num);
|
||||||
|
}
|
||||||
|
last = num
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
268
myapp/static/components/tags.js
Normal file
268
myapp/static/components/tags.js
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
var tagsTemplate = `
|
||||||
|
<div>
|
||||||
|
<!-- Начало: Теги -->
|
||||||
|
<div class="row my-3">
|
||||||
|
<div class="col">
|
||||||
|
<div class="btn mb-1"><i class="fa fa-tags"></i></div>
|
||||||
|
|
||||||
|
<div class="btn btn-outline-success mb-1" v-on:click="showPanel(panels.standart)"><i class="fa fa-plus"></i></div>
|
||||||
|
|
||||||
|
<div class="btn-group mr-2 mb-1" v-for="(tag, index) in sortedTags">
|
||||||
|
<a class="btn btn-outline-secondary text-monospace" :href="'/tag/' + tag.id">{{ tag.name }}</a>
|
||||||
|
<div class="btn btn-outline-danger" v-on:click="removeTag(tag.id)"><i class="fa fa-remove"></i></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-3" v-if="panels.standart.visible">
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<input v-model="newtag" v-on:keyup.13="addTag" class="form-control" />
|
||||||
|
<div class="input-group-append">
|
||||||
|
<div class="btn btn-outline-success" v-on:click="addTag"><i class="fa fa-save"></i></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-3">
|
||||||
|
<div class="col">
|
||||||
|
<template v-for="(tags, key, index) in groups">
|
||||||
|
|
||||||
|
<a class="btn btn-outline-secondary mt-2 mr-2" v-if="(index % 2)===0" :href="'#' + index">{{ key }}</a>
|
||||||
|
<a class="btn btn-outline-primary mt-2 mr-2" v-else :href="'#' + index">{{ key }}</a>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Начало: Форма добавления нового тега -->
|
||||||
|
<div class="row" v-if="panels.new.visible">
|
||||||
|
<div class="col py-2">
|
||||||
|
Добавить новый тег [<b id="newTag">{{ newtag }}</b>]?
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col py-2">
|
||||||
|
<div class="btn btn-outline-danger" v-on:click="cancelNewTag">Отмена</div>
|
||||||
|
<div class="btn btn-outline-success float-right" v-on:click="addNewTag">Добавить</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Конец: Форма добавления нового тега -->
|
||||||
|
|
||||||
|
<div class="row mt-3" v-for="(tags, key, index) in groups">
|
||||||
|
<div class="col pr-0">
|
||||||
|
<a :name="index" class="btn btn-outline-danger mr-2 mb-1">{{ key }}</a>
|
||||||
|
<template v-for="(tag, tagIdx) in tags">
|
||||||
|
<div class="btn btn-outline-secondary mr-2 mb-1" v-if="!tag_ids.includes(tag.id)" v-on:click="tag_add_to_node(tag)">{{ tag.name }}</div>
|
||||||
|
<div class="btn btn-primary mr-2 mb-1" v-else v-on:click="removeTag(tag.id)">{{ tag.name }}</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Конец: Теги -->
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
Vue.component('tags-component', {
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
newtag: '',
|
||||||
|
groups: {},
|
||||||
|
forms: {
|
||||||
|
modal: false,
|
||||||
|
panel: false
|
||||||
|
},
|
||||||
|
panels: {
|
||||||
|
standart: {
|
||||||
|
visible: false
|
||||||
|
},
|
||||||
|
new: {
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: ['tags', 'node', 'url'],
|
||||||
|
template: tagsTemplate,
|
||||||
|
methods: {
|
||||||
|
arrayRemove: function(arr, value) {
|
||||||
|
/* Удаление элемента из списка */
|
||||||
|
return arr.filter(function(ele){
|
||||||
|
return ele != value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
removeTag: function (id) {
|
||||||
|
/* Удаление тега из ресурса */
|
||||||
|
let vm = this;
|
||||||
|
var tag = null;
|
||||||
|
for (var i = 0; i < vm.tags.length; i++) {
|
||||||
|
if (id == vm.tags[i].id) {
|
||||||
|
tag = vm.tags[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tag) {return;}
|
||||||
|
axios.post(
|
||||||
|
'/api',
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": 'tag.deleteFrom' + vm.url,
|
||||||
|
"params": {
|
||||||
|
"id": vm.node,
|
||||||
|
"tag": tag.id
|
||||||
|
},
|
||||||
|
"id": 1
|
||||||
|
}
|
||||||
|
).then(
|
||||||
|
function(response) {
|
||||||
|
if ('result' in response.data) {
|
||||||
|
vm.tags = vm.arrayRemove(vm.tags, tag);
|
||||||
|
} else if ('error' in response.data) {
|
||||||
|
console.log(response.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
addTag: function () {
|
||||||
|
/* Добавить тег к ресурсу */
|
||||||
|
let vm = this;
|
||||||
|
var newtag = vm.newtag.trim();
|
||||||
|
vm.newtag = newtag;
|
||||||
|
axios.post(
|
||||||
|
'/api',
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": 'tag.exist',
|
||||||
|
"params": {
|
||||||
|
name: vm.newtag
|
||||||
|
},
|
||||||
|
"id": 1
|
||||||
|
}
|
||||||
|
).then(
|
||||||
|
function(response) {
|
||||||
|
if ('result' in response.data) {
|
||||||
|
vm.tag_add_to_node( response.data['result'] );
|
||||||
|
} else if ('error' in response.data) {
|
||||||
|
console.log(response.data);
|
||||||
|
vm.panels.new.visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).catch(
|
||||||
|
function (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
addNewTag:function () {
|
||||||
|
/* Добавление нового тега */
|
||||||
|
let vm = this;
|
||||||
|
axios.post(
|
||||||
|
'/api',
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": 'tag.add',
|
||||||
|
"params": {
|
||||||
|
name: vm.newtag
|
||||||
|
},
|
||||||
|
"id": 1
|
||||||
|
}
|
||||||
|
).then(
|
||||||
|
function(response) {
|
||||||
|
if ('result' in response.data) {
|
||||||
|
vm.getTags();
|
||||||
|
vm.tag_add_to_node( response.data['result'] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
cancelNewTag:function () {
|
||||||
|
let vm = this;
|
||||||
|
vm.newtag = '';
|
||||||
|
vm.panels.new.visible = false;
|
||||||
|
},
|
||||||
|
// Добавление тега к ресурсу
|
||||||
|
tag_add_to_node: function(tag) {
|
||||||
|
let vm = this;
|
||||||
|
axios.post(
|
||||||
|
'/api',
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": 'tag.addTo' + this.url,
|
||||||
|
"params": {
|
||||||
|
"id": vm.node,
|
||||||
|
"tag": tag.id
|
||||||
|
},
|
||||||
|
"id": 1
|
||||||
|
}
|
||||||
|
).then(
|
||||||
|
function(response) {
|
||||||
|
if ('result' in response.data) {
|
||||||
|
vm.tags.push(response.data['result']);
|
||||||
|
vm.newtag = '';
|
||||||
|
vm.panels.new.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// Получить список тегов
|
||||||
|
getTags: function() {
|
||||||
|
let vm = this;
|
||||||
|
axios.post(
|
||||||
|
'/api',
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": 'tags.groups',
|
||||||
|
"params": {},
|
||||||
|
"id": 1
|
||||||
|
}
|
||||||
|
).then(
|
||||||
|
function(response) {
|
||||||
|
if ('result' in response.data) {
|
||||||
|
vm.groups = response.data['result'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).catch(
|
||||||
|
function (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
showPanel: function(panel) {
|
||||||
|
/* Показать/скрыть панель */
|
||||||
|
panel.visible = !panel.visible;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted: function() {
|
||||||
|
let vm = this;
|
||||||
|
vm.getTags();
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
tag_ids: function() {
|
||||||
|
let vm = this;
|
||||||
|
var result = [];
|
||||||
|
for (var i = 0; i < vm.tags.length; i++) {
|
||||||
|
result.push(vm.tags[i].id);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
sortedTags: function() {
|
||||||
|
let vm = this;
|
||||||
|
if (vm.tags === undefined) {return [];}
|
||||||
|
vm.tags.sort(
|
||||||
|
function(a, b) {
|
||||||
|
if (a.name > b.name) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (a.name < b.name) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return vm.tags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "skeleton.html" %}
|
{% extends "skeleton.html" %}
|
||||||
{% block body %}
|
{% block content %}
|
||||||
|
|
||||||
<h3 class="text-danger">{{ error_code }}: {{ error_message }}</h3>
|
<h3 class="text-danger">{{ error_code }}: {{ error_message }}</h3>
|
||||||
<hr />
|
<hr />
|
||||||
|
|||||||
37
myapp/templates/inc/editor.js
Normal file
37
myapp/templates/inc/editor.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{% macro plugin(type="tinymce") -%}
|
||||||
|
{% if type=="tinymce" %}
|
||||||
|
<script type="text/javascript" src="/static/tinymce/tinymce.min.js"></script>
|
||||||
|
{% elif type=="ckeditor" %}
|
||||||
|
<script type="text/javascript" src="/static/ckeditor/ckeditor.js"></script>
|
||||||
|
{% endif %}
|
||||||
|
{%- endmacro %}
|
||||||
|
|
||||||
|
{% macro ckeditor(name) -%}
|
||||||
|
CKEDITOR.replace( '{{ name }}', {
|
||||||
|
customConfig: '/static/js/ckeditor-conf.js'
|
||||||
|
} );
|
||||||
|
{%- endmacro %}
|
||||||
|
|
||||||
|
{% macro tinymce(name) -%}
|
||||||
|
tinymce.init({
|
||||||
|
selector: 'textarea#{{ name }}',
|
||||||
|
height: 400,
|
||||||
|
language: 'ru',
|
||||||
|
plugins: "code link image table",
|
||||||
|
toolbar: "table tabledelete | tableprops tablerowprops tablecellprops | tableinsertrowbefore tableinsertrowafter tabledeleterow | tableinsertcolbefore tableinsertcolafter tabledeletecol"
|
||||||
|
});
|
||||||
|
{%- endmacro %}
|
||||||
|
|
||||||
|
{% macro getValue(name, param, type="tinymce") -%}
|
||||||
|
{% if type=="tinymce" %}
|
||||||
|
let value = tinymce.get("{{ name }}").getContent();
|
||||||
|
if (value != {{ param }}) {
|
||||||
|
{{ param }} = value;
|
||||||
|
}
|
||||||
|
{% elif type=="ckeditor" %}
|
||||||
|
var value = CKEDITOR.instances["{{ name }}"].getData();
|
||||||
|
if (value != {{ param }}) {
|
||||||
|
{{ param }} = value;
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
{%- endmacro %}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "skeleton.html" %}
|
{% extends "skeleton.html" %}
|
||||||
{% block body %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col py-2">
|
<div class="col py-2">
|
||||||
|
|
||||||
{% if session.logged_in %}
|
|
||||||
<div class="btn-group float-right">
|
|
||||||
<a class="btn btn-outline-secondary border-0" href="/profile"><i class="fa fa-user"></i></a>
|
|
||||||
<a class="btn btn-outline-danger border-0" href="/logout"><i class="fa fa-sign-out"></i></a>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<a class="btn btn-outline-success border-0 float-right" href="/login"><i class="fa fa-sign-in"></i></a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<a class="btn btn-outline-secondary border-0" href="/"><i class="fa fa-home"></i></a>
|
<a class="btn btn-outline-secondary border-0" href="/"><i class="fa fa-home"></i></a>
|
||||||
<a class="btn btn-outline-secondary border-0" href="/page">Статья</a>
|
<a class="btn btn-outline-secondary border-0" href="/pages">Статьи</a>
|
||||||
<a class="btn btn-outline-secondary border-0" href="/tags">Метки</a>
|
<a class="btn btn-outline-secondary border-0" href="/tags">Метки</a>
|
||||||
<a class="btn btn-outline-secondary border-0" href="/users">Пользователи</a>
|
<a class="btn btn-outline-secondary border-0" href="/users">Пользователи</a>
|
||||||
<a class="btn btn-outline-secondary border-0" href="/api/browse">API JSON-RPC</a>
|
<a class="btn btn-outline-secondary border-0" href="/api/browse">API JSON-RPC</a>
|
||||||
|
|
||||||
|
<a class="btn btn-outline-success border-0 float-right" href="/login"><i class="fa fa-sign-in"></i></a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,112 +0,0 @@
|
|||||||
{% extends "skeleton.html" %}
|
|
||||||
{% block body %}
|
|
||||||
|
|
||||||
{% raw %}
|
|
||||||
<h3>
|
|
||||||
<div class="btn btn-outline-secondary float-right" v-on:click="showPanel(panels.edit)"><i class="fa fa-edit"></i></div>
|
|
||||||
{{ page.title }}</h3>
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
<div class="row" v-if="panels.edit.visible">
|
|
||||||
<div class="col">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="title">Заголовок</label>
|
|
||||||
<input id="title" name="title" type="text" value="Заголовок страницы" class="form-control" v-model="newPage.title">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="text">Текст</label>
|
|
||||||
<textarea class="form-control" id="text" name="text" v-model="newPage.text"></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<button class="btn btn-outline-success float-right" v-on:click="send"><i class="fa fa-save-o"></i> Сохранить</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mt-3" v-if="error">
|
|
||||||
<div class="col bg-danger text-white" v-html="error">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span v-html="page.text" v-else></span>
|
|
||||||
|
|
||||||
{% endraw %}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block breadcrumb %}
|
|
||||||
<ol class="breadcrumb mt-3">
|
|
||||||
<li class="breadcrumb-item"><a href="/"><i class="fa fa-home"></i></a></li>
|
|
||||||
<li class="breadcrumb-item active">Редактирование страницы</li>
|
|
||||||
</ol>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block script %}
|
|
||||||
<script type="text/javascript" src="/static/ckeditor/ckeditor.js"></script>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
var app = new Vue({
|
|
||||||
el: '#app',
|
|
||||||
data: {
|
|
||||||
page: {{ pagedata['page']|tojson|safe }},
|
|
||||||
newPage: {{ pagedata['page']|tojson|safe }},
|
|
||||||
panels: {
|
|
||||||
edit: {
|
|
||||||
visible: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: null
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
showPanel: function(panel) {
|
|
||||||
/* Показать/скрыть панель */
|
|
||||||
panel.visible = !panel.visible;
|
|
||||||
},
|
|
||||||
send: function() {
|
|
||||||
let vm = this;
|
|
||||||
var value = CKEDITOR.instances["text"].getData();
|
|
||||||
if (value != vm.newPage.text) {
|
|
||||||
vm.newPage.text = value;
|
|
||||||
}
|
|
||||||
axios.post(
|
|
||||||
'/api',
|
|
||||||
{
|
|
||||||
"jsonrpc": "2.0",
|
|
||||||
"method": 'page.update',
|
|
||||||
"params": {
|
|
||||||
"title": vm.newPage.title,
|
|
||||||
"text": vm.newPage.text
|
|
||||||
},
|
|
||||||
"id": 1
|
|
||||||
}
|
|
||||||
).then(
|
|
||||||
function(response) {
|
|
||||||
if ('result' in response.data) {
|
|
||||||
vm.page = response.data['result'];
|
|
||||||
vm.newPage = vm.page;
|
|
||||||
vm.error = null;
|
|
||||||
} else if ('error' in response.data) {
|
|
||||||
vm.error = response.data['error'].message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updated: function() {
|
|
||||||
let vm = this;
|
|
||||||
for(var instanceName in CKEDITOR.instances) {
|
|
||||||
CKEDITOR.instances[instanceName].destroy(true);
|
|
||||||
}
|
|
||||||
if (vm.panels.edit.visible) {
|
|
||||||
CKEDITOR.replace( "text", {
|
|
||||||
customConfig: '/static/js/ckeditor-conf.js'
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -7,8 +7,8 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
{% include 'navbar.html' %}
|
{% include 'navbar.html' %}
|
||||||
|
|
||||||
{% block body %}
|
{% block content %}
|
||||||
{% endblock body %}
|
{% endblock content %}
|
||||||
|
|
||||||
{% block breadcrumb %}
|
{% block breadcrumb %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
16
myapp/templates/user/navbar.html
Normal file
16
myapp/templates/user/navbar.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<div class="row">
|
||||||
|
<div class="col py-2">
|
||||||
|
|
||||||
|
<a class="btn btn-outline-secondary border-0" href="/"><i class="fa fa-home"></i></a>
|
||||||
|
<a class="btn btn-outline-secondary border-0" href="/pages">Статьи</a>
|
||||||
|
<a class="btn btn-outline-secondary border-0" href="/tags">Метки</a>
|
||||||
|
<a class="btn btn-outline-secondary border-0" href="/users">Пользователи</a>
|
||||||
|
<a class="btn btn-outline-secondary border-0" href="/api/browse">API JSON-RPC</a>
|
||||||
|
|
||||||
|
<div class="btn-group float-right">
|
||||||
|
<a class="btn btn-outline-secondary border-0" href="/profile"><i class="fa fa-user"></i></a>
|
||||||
|
<a class="btn btn-outline-danger border-0" href="/logout"><i class="fa fa-sign-out"></i></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
33
myapp/templates/user/skeleton.html
Normal file
33
myapp/templates/user/skeleton.html
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
{% include 'header.html' %}
|
||||||
|
<body>
|
||||||
|
<section id="app">
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
{% include 'user/navbar.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% endblock content %}
|
||||||
|
|
||||||
|
{% block breadcrumb %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% include 'footer.html' %}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{% block script %}
|
||||||
|
<script type="text/javascript">
|
||||||
|
var app = new Vue({
|
||||||
|
el: '#app',
|
||||||
|
data: {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{% endblock script %}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user