WIP commit. Changed routes to POST/PUT/DELETE on page name endpoint to be more RESTful. Check wiki dir permissions Add comments Add dummy favicon, robots.txt, humans.txt Remove create.html (wasn't being used) Fix version command
這個提交存在於:
父節點
b99128e47a
當前提交
e6bc4928c9
共有 13 個檔案被更改,包括 321 行新增 和 144 行删除
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
0.3.19
|
||||
0.3.20
|
|
@ -210,7 +210,8 @@ assets.register('main.js',
|
|||
'vendor/datatables/media/js/jquery.dataTables.js',
|
||||
'vendor/datatables-plugins/integration/bootstrap/3/dataTables.bootstrap.js',
|
||||
'js/hbs-helpers.js',
|
||||
'js/mdr.js')
|
||||
'js/mdr.js',
|
||||
'js/main.js')
|
||||
|
||||
assets.register('main.css',
|
||||
'vendor/bootswatch-dist/css/bootstrap.css',
|
||||
|
|
|
@ -330,8 +330,8 @@ def test():
|
|||
def version():
|
||||
""" Output version
|
||||
"""
|
||||
with open('VERSION') as f:
|
||||
return f.read().strip()
|
||||
with open(os.path.join(config.APP_PATH, 'VERSION')) as f:
|
||||
click.echo(f.read().strip())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import os
|
||||
import sys
|
||||
from realms import app
|
||||
from realms.modules.wiki.models import Wiki
|
||||
|
||||
# Init Wiki
|
||||
Wiki(app.config['WIKI_PATH'])
|
||||
|
||||
# Check paths
|
||||
for mode in [os.W_OK, os.R_OK]:
|
||||
for dir_ in [app.config['WIKI_PATH'], os.path.join(app.config['WIKI_PATH'], '.git')]:
|
||||
if not os.access(dir_, mode):
|
||||
sys.exit('Read and write access to WIKI_PATH is required (%s)' % dir_)
|
|
@ -14,15 +14,30 @@ from realms.lib.hook import HookMixin
|
|||
|
||||
|
||||
def cname_to_filename(cname):
|
||||
""" Convert canonical name to filename
|
||||
|
||||
:param cname: Canonical name
|
||||
:return: str -- Filename
|
||||
|
||||
"""
|
||||
return cname.lower() + ".md"
|
||||
|
||||
|
||||
def filename_to_cname(filename):
|
||||
""" It's assumed filename is already cname format
|
||||
"""Convert filename to canonical name.
|
||||
|
||||
.. note::
|
||||
|
||||
It's assumed filename is already canonical format
|
||||
|
||||
"""
|
||||
return os.path.splitext(filename)[0]
|
||||
|
||||
|
||||
class PageNotFound(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Wiki(HookMixin):
|
||||
path = None
|
||||
base_path = '/'
|
||||
|
@ -48,56 +63,42 @@ class Wiki(HookMixin):
|
|||
return "Wiki: %s" % self.path
|
||||
|
||||
def revert_page(self, name, commit_sha, message, username):
|
||||
"""Revert page to passed commit sha1
|
||||
|
||||
:param name: Name of page to revert.
|
||||
:param commit_sha: Commit Sha1 to revert to.
|
||||
:param message: Commit message.
|
||||
:param username:
|
||||
:return: Git commit sha1
|
||||
|
||||
"""
|
||||
page = self.get_page(name, commit_sha)
|
||||
if not page:
|
||||
# Page not found
|
||||
return None
|
||||
commit_info = gittle.utils.git.commit_info(self.gittle[commit_sha.encode('latin-1')])
|
||||
message = commit_info['message']
|
||||
raise PageNotFound()
|
||||
|
||||
if not message:
|
||||
commit_info = gittle.utils.git.commit_info(self.gittle[commit_sha.encode('latin-1')])
|
||||
message = commit_info['message']
|
||||
|
||||
return self.write_page(name, page['data'], message=message, username=username)
|
||||
|
||||
def write_page(self, name, content, message=None, create=False, username=None, email=None):
|
||||
"""Write page to git repo
|
||||
|
||||
def escape_repl(m):
|
||||
if m.group(1):
|
||||
return "```" + escape(m.group(1)) + "```"
|
||||
|
||||
def unescape_repl(m):
|
||||
if m.group(1):
|
||||
return "```" + unescape(m.group(1)) + "```"
|
||||
:param name: Name of page.
|
||||
:param content: Content of page.
|
||||
:param message: Commit message.
|
||||
:param create: Perform git add operation?
|
||||
:param username: Commit Name.
|
||||
:param email: Commit Email.
|
||||
:return: Git commit sha1.
|
||||
"""
|
||||
|
||||
cname = to_canonical(name)
|
||||
|
||||
# prevents p tag from being added, we remove this later
|
||||
content = '<div>' + content + '</div>'
|
||||
content = re.sub(r"```(.*?)```", escape_repl, content, flags=re.DOTALL)
|
||||
|
||||
tree = lxml.html.fromstring(content)
|
||||
|
||||
cleaner = Cleaner(remove_unknown_tags=False,
|
||||
kill_tags=set(['style']),
|
||||
safe_attrs_only=False)
|
||||
tree = cleaner.clean_html(tree)
|
||||
|
||||
content = lxml.html.tostring(tree, encoding='utf-8', method='html')
|
||||
|
||||
# remove added div tags
|
||||
content = content[5:-6]
|
||||
|
||||
# FIXME this is for block quotes, doesn't work for double ">"
|
||||
content = re.sub(r"(\n>)", "\n>", content)
|
||||
content = re.sub(r"(^>)", ">", content)
|
||||
|
||||
# Handlebars partial ">"
|
||||
content = re.sub(r"\{\{>(.*?)\}\}", r'{{>\1}}', content)
|
||||
|
||||
# Handlebars, allow {{}} inside HTML links
|
||||
content = content.replace("%7B", "{")
|
||||
content = content.replace("%7D", "}")
|
||||
|
||||
content = re.sub(r"```(.*?)```", unescape_repl, content, flags=re.DOTALL)
|
||||
|
||||
filename = cname_to_filename(cname)
|
||||
|
||||
content = self.clean(content)
|
||||
|
||||
with open(self.path + "/" + filename, 'w') as f:
|
||||
f.write(content)
|
||||
|
||||
|
@ -122,7 +123,60 @@ class Wiki(HookMixin):
|
|||
|
||||
return ret
|
||||
|
||||
def clean(self, content):
|
||||
"""Clean any HTML, this might not be necessary.
|
||||
|
||||
:param content: Content of page.
|
||||
:return: str
|
||||
|
||||
"""
|
||||
def escape_repl(m):
|
||||
if m.group(1):
|
||||
return "```" + escape(m.group(1)) + "```"
|
||||
|
||||
def unescape_repl(m):
|
||||
if m.group(1):
|
||||
return "```" + unescape(m.group(1)) + "```"
|
||||
|
||||
# prevents p tag from being added, we remove this later
|
||||
content = '<div>' + content + '</div>'
|
||||
content = re.sub(r"```(.*?)```", escape_repl, content, flags=re.DOTALL)
|
||||
|
||||
tree = lxml.html.fromstring(content)
|
||||
|
||||
cleaner = Cleaner(remove_unknown_tags=False,
|
||||
kill_tags={'style'},
|
||||
safe_attrs_only=False)
|
||||
tree = cleaner.clean_html(tree)
|
||||
|
||||
content = lxml.html.tostring(tree, encoding='utf-8', method='html')
|
||||
|
||||
# remove added div tags
|
||||
content = content[5:-6]
|
||||
|
||||
# FIXME this is for block quotes, doesn't work for double ">"
|
||||
content = re.sub(r"(\n>)", "\n>", content)
|
||||
content = re.sub(r"(^>)", ">", content)
|
||||
|
||||
# Handlebars partial ">"
|
||||
content = re.sub(r"\{\{>(.*?)\}\}", r'{{>\1}}', content)
|
||||
|
||||
# Handlebars, allow {{}} inside HTML links
|
||||
content = content.replace("%7B", "{")
|
||||
content = content.replace("%7D", "}")
|
||||
|
||||
content = re.sub(r"```(.*?)```", unescape_repl, content, flags=re.DOTALL)
|
||||
return content
|
||||
|
||||
def rename_page(self, old_name, new_name, user=None):
|
||||
"""Rename page.
|
||||
|
||||
:param old_name: Page that will be renamed.
|
||||
:param new_name: New name of page.
|
||||
:param user: User object if any.
|
||||
:return: str -- Commit sha1
|
||||
|
||||
"""
|
||||
old_filename, new_filename = map(cname_to_filename, [old_name, new_name])
|
||||
if old_filename not in self.gittle.index:
|
||||
# old doesn't exist
|
||||
|
@ -137,14 +191,38 @@ class Wiki(HookMixin):
|
|||
self.gittle.add(new_filename)
|
||||
self.gittle.rm(old_filename)
|
||||
|
||||
self.gittle.commit(name=getattr(user, 'username', self.default_committer_name),
|
||||
email=getattr(user, 'email', self.default_committer_email),
|
||||
message="Moved %s to %s" % (old_name, new_name),
|
||||
files=[old_filename, new_filename])
|
||||
commit = self.gittle.commit(name=getattr(user, 'username', self.default_committer_name),
|
||||
email=getattr(user, 'email', self.default_committer_email),
|
||||
message="Moved %s to %s" % (old_name, new_name),
|
||||
files=[old_filename, new_filename])
|
||||
|
||||
cache.delete_many(old_filename, new_filename)
|
||||
|
||||
return commit
|
||||
|
||||
def delete_page(self, name, user=None):
|
||||
"""Delete page.
|
||||
:param name: Page that will be deleted
|
||||
:param user: User object if any
|
||||
:return: str -- Commit sha1
|
||||
|
||||
"""
|
||||
self.gittle.rm(name)
|
||||
commit = self.gittle.commit(name=getattr(user, 'username', self.default_committer_name),
|
||||
email=getattr(user, 'email', self.default_committer_email),
|
||||
message="Deleted %s" % name,
|
||||
files=[name])
|
||||
cache.delete_many(name)
|
||||
return commit
|
||||
|
||||
def get_page(self, name, sha='HEAD'):
|
||||
"""Get page data, partials, commit info.
|
||||
|
||||
:param name: Name of page.
|
||||
:param sha: Commit sha.
|
||||
:return: dict
|
||||
|
||||
"""
|
||||
cached = cache.get(name)
|
||||
if cached:
|
||||
return cached
|
||||
|
@ -172,22 +250,46 @@ class Wiki(HookMixin):
|
|||
return None
|
||||
|
||||
def get_meta(self, content):
|
||||
"""Get metadata from page if any.
|
||||
|
||||
:param content: Page content
|
||||
:return: dict
|
||||
|
||||
"""
|
||||
if not content.startswith("---"):
|
||||
return None
|
||||
|
||||
meta_end = re.search("\n(\.{3}|\-{3})", content)
|
||||
|
||||
if not meta_end:
|
||||
return None
|
||||
|
||||
try:
|
||||
return yaml.safe_load(content[0:meta_end.start()])
|
||||
except Exception as e:
|
||||
return {'error': e.message}
|
||||
|
||||
def compare(self, name, old_sha, new_sha):
|
||||
"""Compare two revisions of the same page.
|
||||
|
||||
:param name: Name of page.
|
||||
:param old_sha: Older sha.
|
||||
:param new_sha: Newer sha.
|
||||
:return: str - Raw markup with styles
|
||||
|
||||
"""
|
||||
|
||||
# TODO: This could be effectively done in the browser
|
||||
old = self.get_page(name, sha=old_sha)
|
||||
new = self.get_page(name, sha=new_sha)
|
||||
return ghdiff.diff(old['data'], new['data'])
|
||||
|
||||
def get_index(self):
|
||||
"""Get repo index of head.
|
||||
|
||||
:return: list -- List of dicts
|
||||
|
||||
"""
|
||||
rv = []
|
||||
index = self.repo.open_index()
|
||||
for name in index:
|
||||
|
@ -201,8 +303,20 @@ class Wiki(HookMixin):
|
|||
return rv
|
||||
|
||||
def get_history(self, name, limit=100):
|
||||
"""Get page history.
|
||||
|
||||
:param name: Name of page.
|
||||
:param limit: Limit history size.
|
||||
:return: list -- List of dicts
|
||||
|
||||
"""
|
||||
if not len(self.repo.open_index()):
|
||||
# Index is empty, no commits
|
||||
return []
|
||||
|
||||
file_path = cname_to_filename(name)
|
||||
versions = []
|
||||
|
||||
walker = self.repo.get_walker(paths=[file_path], max_entries=limit)
|
||||
for entry in walker:
|
||||
change_type = None
|
||||
|
@ -220,4 +334,3 @@ class Wiki(HookMixin):
|
|||
type=change_type))
|
||||
|
||||
return versions
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from flask import g, render_template, request, redirect, Blueprint, flash, url_for, current_app
|
||||
from flask import abort, g, render_template, request, redirect, Blueprint, flash, url_for, current_app
|
||||
from flask.ext.login import login_required
|
||||
from realms.lib.util import to_canonical, remove_ext
|
||||
from realms.modules.wiki.models import Wiki
|
||||
|
@ -17,10 +17,11 @@ def commit(name, sha):
|
|||
cname = to_canonical(name)
|
||||
|
||||
data = g.current_wiki.get_page(cname, sha=sha)
|
||||
if data:
|
||||
return render_template('wiki/page.html', name=name, page=data, commit=sha)
|
||||
else:
|
||||
return redirect(url_for('wiki.create', name=cname))
|
||||
|
||||
if not data:
|
||||
abort(404)
|
||||
|
||||
return render_template('wiki/page.html', name=name, page=data, commit=sha)
|
||||
|
||||
|
||||
@blueprint.route("/_compare/<name>/<regex('[^.]+'):fsha><regex('\.{2,3}'):dots><regex('.+'):lsha>")
|
||||
|
@ -35,15 +36,17 @@ def revert():
|
|||
name = request.form.get('name')
|
||||
commit = request.form.get('commit')
|
||||
cname = to_canonical(name)
|
||||
message = request.form.get('message', "Reverting %s" % cname)
|
||||
|
||||
if cname in app.config.WIKI_LOCKED_PAGES:
|
||||
flash("Page is locked")
|
||||
return redirect(url_for(app.config['ROOT_ENDPOINT']))
|
||||
if cname in app.config.get('WIKI_LOCKED_PAGES'):
|
||||
return dict(error=True, message="Page is locked")
|
||||
|
||||
g.current_wiki.revert_page(name, commit, message="Reverting %s" % cname,
|
||||
username=current_user.username)
|
||||
flash('Page reverted', 'success')
|
||||
return redirect(url_for('wiki.page', name=cname))
|
||||
sha = g.current_wiki.revert_page(name, commit, message=message,
|
||||
username=current_user.username)
|
||||
if sha:
|
||||
flash("Page reverted")
|
||||
|
||||
return dict(sha=sha)
|
||||
|
||||
|
||||
@blueprint.route("/_history/<name>")
|
||||
|
@ -51,74 +54,40 @@ def history(name):
|
|||
return render_template('wiki/history.html', name=name, history=g.current_wiki.get_history(name))
|
||||
|
||||
|
||||
@blueprint.route("/_edit/<name>", methods=['GET', 'POST'])
|
||||
@blueprint.route("/_edit/<name>")
|
||||
@login_required
|
||||
def edit(name):
|
||||
data = g.current_wiki.get_page(name)
|
||||
cname = to_canonical(name)
|
||||
if request.method == 'POST':
|
||||
edit_cname = to_canonical(request.form['name'])
|
||||
page = g.current_wiki.get_page(name)
|
||||
|
||||
if edit_cname in app.config['WIKI_LOCKED_PAGES']:
|
||||
return redirect(url_for(app.config['ROOT_ENDPOINT']))
|
||||
if not page:
|
||||
# Page doesn't exist
|
||||
return redirect(url_for('wiki.create', name=cname))
|
||||
|
||||
if edit_cname != cname.lower():
|
||||
g.current_wiki.rename_page(cname, edit_cname)
|
||||
|
||||
g.current_wiki.write_page(edit_cname,
|
||||
request.form['content'],
|
||||
message=request.form['message'],
|
||||
username=current_user.username)
|
||||
else:
|
||||
if data:
|
||||
name = remove_ext(data['name'])
|
||||
content = data.get('data')
|
||||
g.assets['js'].append('editor.js')
|
||||
return render_template('wiki/edit.html',
|
||||
name=name,
|
||||
content=content,
|
||||
info=data.get('info'),
|
||||
sha=data.get('sha'),
|
||||
partials=data.get('partials'))
|
||||
else:
|
||||
return redirect(url_for('wiki.create', name=cname))
|
||||
name = remove_ext(page['name'])
|
||||
g.assets['js'].append('editor.js')
|
||||
return render_template('wiki/edit.html',
|
||||
name=name,
|
||||
content=page.get('data'),
|
||||
info=page.get('info'),
|
||||
sha=page.get('sha'),
|
||||
partials=page.get('partials'))
|
||||
|
||||
|
||||
@blueprint.route("/_delete/<name>", methods=['POST'])
|
||||
@login_required
|
||||
def delete(name):
|
||||
pass
|
||||
|
||||
|
||||
@blueprint.route("/_create/", defaults={'name': None}, methods=['GET', 'POST'])
|
||||
@blueprint.route("/_create/<name>", methods=['GET', 'POST'])
|
||||
@blueprint.route("/_create/", defaults={'name': None})
|
||||
@blueprint.route("/_create/<name>")
|
||||
@login_required
|
||||
def create(name):
|
||||
if request.method == 'POST':
|
||||
cname = to_canonical(request.form['name'])
|
||||
cname = to_canonical(name) if name else ""
|
||||
if cname and g.current_wiki.get_page(cname):
|
||||
# Page exists, edit instead
|
||||
return redirect(url_for('wiki.edit', name=cname))
|
||||
|
||||
if cname in app.config['WIKI_LOCKED_PAGES']:
|
||||
return redirect(url_for("wiki.create"))
|
||||
|
||||
if not cname:
|
||||
return redirect(url_for("wiki.create"))
|
||||
|
||||
g.current_wiki.write_page(request.form['name'],
|
||||
request.form['content'],
|
||||
message=request.form['message'],
|
||||
create=True,
|
||||
username=current_user.username)
|
||||
else:
|
||||
cname = to_canonical(name) if name else ""
|
||||
if cname and g.current_wiki.get_page(cname):
|
||||
# Page exists, edit instead
|
||||
return redirect(url_for('wiki.edit', name=cname))
|
||||
|
||||
g.assets['js'].append('editor.js')
|
||||
return render_template('wiki/edit.html',
|
||||
name=cname,
|
||||
content="",
|
||||
info={})
|
||||
g.assets['js'].append('editor.js')
|
||||
return render_template('wiki/edit.html',
|
||||
name=cname,
|
||||
content="",
|
||||
info={})
|
||||
|
||||
|
||||
@blueprint.route("/_index")
|
||||
|
@ -126,6 +95,48 @@ def index():
|
|||
return render_template('wiki/index.html', index=g.current_wiki.get_index())
|
||||
|
||||
|
||||
@blueprint.route("/<name>", methods=['POST', 'PUT', 'DELETE'])
|
||||
@login_required
|
||||
def page_write(name):
|
||||
cname = to_canonical(name)
|
||||
|
||||
if not cname:
|
||||
return dict(error=True, message="Invalid name")
|
||||
|
||||
if request.method == 'POST':
|
||||
# Create
|
||||
if cname in app.config.get('WIKI_LOCKED_PAGES'):
|
||||
return dict(error=True, message="Page is locked")
|
||||
|
||||
sha = g.current_wiki.write_page(cname,
|
||||
request.form['content'],
|
||||
message=request.form['message'],
|
||||
create=True,
|
||||
username=current_user.username)
|
||||
|
||||
elif request.method == 'PUT':
|
||||
edit_cname = to_canonical(request.form['name'])
|
||||
|
||||
if edit_cname in app.config.get('WIKI_LOCKED_PAGES'):
|
||||
return dict(error=True, message="Page is locked")
|
||||
|
||||
if edit_cname != cname.lower():
|
||||
g.current_wiki.rename_page(cname, edit_cname)
|
||||
|
||||
sha = g.current_wiki.write_page(edit_cname,
|
||||
request.form['content'],
|
||||
message=request.form['message'],
|
||||
username=current_user.username)
|
||||
|
||||
return dict(sha=sha)
|
||||
|
||||
else:
|
||||
# DELETE
|
||||
sha = g.current_wiki.delete_page(name, user=current_user)
|
||||
|
||||
return dict(sha=sha)
|
||||
|
||||
|
||||
@blueprint.route("/", defaults={'name': 'home'})
|
||||
@blueprint.route("/<name>")
|
||||
def page(name):
|
||||
|
@ -134,6 +145,7 @@ def page(name):
|
|||
return redirect(url_for('wiki.page', name=cname))
|
||||
|
||||
data = g.current_wiki.get_page(cname)
|
||||
|
||||
if data:
|
||||
return render_template('wiki/page.html', name=cname, page=data, partials=data.get('partials'))
|
||||
else:
|
||||
|
|
0
realms/static/humans.txt
一般檔案
0
realms/static/humans.txt
一般檔案
二進制
realms/static/img/favicon.ico
一般檔案
二進制
realms/static/img/favicon.ico
一般檔案
未顯示二進位檔案。
之後 寬度: | 高度: | 大小: 31 KiB |
|
@ -2,6 +2,8 @@ var $entry_markdown_header = $("#entry-markdown-header");
|
|||
var $entry_preview_header = $("#entry-preview-header");
|
||||
var $entry_markdown = $(".entry-markdown");
|
||||
var $entry_preview = $(".entry-preview");
|
||||
var $page_name = $("#page-name");
|
||||
var $page_message = $("#page-message");
|
||||
|
||||
// Tabs
|
||||
$entry_markdown_header.click(function(){
|
||||
|
@ -66,12 +68,26 @@ var aced = new Aced({
|
|||
info: Commit.info,
|
||||
submit: function(content) {
|
||||
var data = {
|
||||
name: $("#page-name").val(),
|
||||
message: $("#page-message").val(),
|
||||
name: $page_name.val(),
|
||||
message: $page_message.val(),
|
||||
content: content
|
||||
};
|
||||
$.post(window.location, data, function() {
|
||||
location.href = Config['RELATIVE_PATH'] + '/' + data['name'];
|
||||
|
||||
var path = Config['RELATIVE_PATH'] + '/' + data['name'];
|
||||
var type = (Commit.info['sha']) ? "PUT" : "POST";
|
||||
|
||||
$.ajax({
|
||||
type: type,
|
||||
url: path,
|
||||
data: data,
|
||||
dataType: 'json'
|
||||
}).always(function(data, status, error) {
|
||||
if (data && data['error']) {
|
||||
$page_name.addClass('parsley-error');
|
||||
bootbox.alert("<h3>" + data['message'] + "</h3>");
|
||||
} else {
|
||||
location.href = path;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
40
realms/static/js/main.js
一般檔案
40
realms/static/js/main.js
一般檔案
|
@ -0,0 +1,40 @@
|
|||
$(function(){
|
||||
$(".ajax-form").submit(function(e){
|
||||
e.preventDefault();
|
||||
|
||||
var submitting = 'submitting';
|
||||
|
||||
if ($(this).data(submitting)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$(this).data(submitting, 1);
|
||||
|
||||
var action = $(this).attr('action');
|
||||
var method = $(this).attr('method');
|
||||
var redirect = $(this).data('redirect');
|
||||
var data = $(this).serialize();
|
||||
|
||||
var req = $.ajax({
|
||||
type: method,
|
||||
url: action,
|
||||
data: data,
|
||||
dataType: 'json'
|
||||
});
|
||||
|
||||
req.done(function() {
|
||||
if (redirect) {
|
||||
location.href = redirect;
|
||||
}
|
||||
});
|
||||
|
||||
req.fail(function(data, status, error) {
|
||||
console.log(data);
|
||||
});
|
||||
|
||||
req.always(function() {
|
||||
$(this).removeData(submitting);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
0
realms/static/robots.txt
一般檔案
0
realms/static/robots.txt
一般檔案
|
@ -1,18 +0,0 @@
|
|||
{% extends 'layout.html' %}
|
||||
{% block body %}
|
||||
|
||||
<form role="form" method="post">
|
||||
<div class="form-group">
|
||||
<label for="name"></label>
|
||||
<input id="name" type="text" class="form-control" name="name" placeholder="Page Name" value="{{- name -}}" />
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="content"></label>
|
||||
<textarea name="content" id="content" class="form-control" placeholder="Content"></textarea>
|
||||
</div>
|
||||
|
||||
<input type="submit" class="btn btn-primary" value="Save" />
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
|
@ -9,7 +9,7 @@
|
|||
{% block body %}
|
||||
{% if commit %}
|
||||
<div id="page-action-bar">
|
||||
<form method="POST" action="{{ url_for('wiki.revert') }}">
|
||||
<form method="POST" action="{{ url_for('wiki.revert') }}" class="ajax-form" data-redirect="{{ url_for('wiki.page', name=name) }}">
|
||||
<input type="hidden" value="{{ name }}" name="name" />
|
||||
<input type="hidden" value="{{ commit }}" name="commit" />
|
||||
<input type="submit" class="btn btn-danger btn-sm" title="Revert back to this revision" value="Revert" />
|
||||
|
|
載入中…
新增表格
Add a link
新增問題並參考