1
0
mirror of https://github.com/til-schneider/slim-wiki.git synced 2025-08-05 08:07:35 +02:00

Added "createUser" page

This commit is contained in:
til-schneider
2015-12-23 17:39:50 +01:00
parent 520d0aead7
commit d3ae27ca9c
12 changed files with 223 additions and 93 deletions

View File

@@ -1,7 +1,6 @@
(function(window, document, console, CodeMirror) {
(function(window, document, slimwiki, console, CodeMirror) {
var slimwiki = window.slimwiki,
editor,
var editor,
updatePreviewDelay = 1000,
updatePreviewTimeout = null,
updatePreviewRunning = false,
@@ -31,7 +30,7 @@
updatePreviewRunning = true;
var start = new Date().getTime(),
articleFilename = slimwiki.settings.articleFilename;
callRpc('editor', 'saveArticle', [ articleFilename, editor.getValue() ], function(result, error) {
slimwiki.Util.callRpc('editor', 'saveArticle', [ articleFilename, editor.getValue() ], function(result, error) {
updatePreviewRunning = false;
if (error) {
@@ -59,34 +58,6 @@
window.scrollTo(0, scrollFactor * (bodyElem.scrollHeight - bodyElem.clientHeight));
}
function callRpc(objectName, methodName, paramArray, done) {
var request = new XMLHttpRequest(),
requestJson;
request.open('POST', 'rpc/' + objectName, true);
request.onreadystatechange = function () {
if (request.readyState == 4) {
if (request.status != 200) {
done(null, 'Request failed with status ' + request.status);
} else {
try {
var responseJson = JSON.parse(request.responseText);
if (responseJson.error) {
done(null, 'Request failed on server-side: ' + responseJson.error.message);
} else {
done(responseJson.result);
}
} catch (err) {
done(null, 'Request failed: ' + err);
}
}
}
};
requestJson = { jsonrpc: '2.0', method: methodName, params: paramArray || [], id: 1 };
request.send(JSON.stringify(requestJson));
}
init();
})(window, document, console, CodeMirror);
})(window, document, slimwiki, console, CodeMirror);

View File

@@ -1,17 +1,81 @@
(function(window, document, hljs) {
(function(window, document, slimwiki, hljs) {
window.slimwiki = window.slimwiki || {};
window.slimwiki.View = {
slimwiki.Util = {
callRpc: callRpc
};
slimwiki.View = {
updateSyntaxHighlighting: updateSyntaxHighlighting
};
updateSyntaxHighlighting();
init();
function updateSyntaxHighlighting() {
var blocks = document.getElementById('content').querySelectorAll('pre code');
function init() {
var mode = slimwiki.settings.mode;
if (mode == 'view' || mode == 'edit') {
updateSyntaxHighlighting();
} else if (mode == 'createUser') {
initCreateUserForm();
}
}
function initCreateUserForm() {
document.getElementById('showConfigBtn').addEventListener('click', function() {
var user = document.getElementById('user').value,
pass = document.getElementById('password').value;
callRpc('editor', 'createUserConfig', [ user, pass ], function(result, error) {
if (error) {
console.error('Creating user config failed:', error);
} else {
var resultBoxElem = document.getElementById('result-box');
resultBoxElem.style.display = 'block';
document.getElementById('result').innerHTML = result.replace(/</g, '&lt;');
updateSyntaxHighlighting(resultBoxElem);
}
});
}, false);
}
function updateSyntaxHighlighting(parentElem) {
if (! parentElem) {
parentElem = document.getElementById('content');
}
var blocks = parentElem.querySelectorAll('pre code');
Array.prototype.forEach.call(blocks, hljs.highlightBlock);
}
})(window, document, hljs);
function callRpc(objectName, methodName, paramArray, done) {
var request = new XMLHttpRequest(),
requestJson;
request.open('POST', 'rpc/' + objectName, true);
request.onreadystatechange = function () {
if (request.readyState == 4) {
if (request.status != 200) {
done(null, 'Request failed with status ' + request.status);
} else {
var responseJson;
try {
responseJson = JSON.parse(request.responseText);
} catch (err) {
done(null, 'Parsing response failed: ' + err);
}
if (responseJson.error) {
done(null, 'Request failed on server-side: ' + responseJson.error.message);
} else {
done(responseJson.result);
}
}
}
};
requestJson = { jsonrpc: '2.0', method: methodName, params: paramArray || [], id: 1 };
request.send(JSON.stringify(requestJson));
}
})(window, document, slimwiki, hljs);

View File

@@ -19,8 +19,8 @@
//@import "@{bootstrap-src}/code.less";
//@import "@{bootstrap-src}/grid.less";
//@import "@{bootstrap-src}/tables.less";
//@import "@{bootstrap-src}/forms.less";
//@import "@{bootstrap-src}/buttons.less";
@import "@{bootstrap-src}/forms.less";
@import "@{bootstrap-src}/buttons.less";
// Components
//@import "@{bootstrap-src}/component-animations.less";

View File

@@ -11,7 +11,7 @@ html, body {
position: relative;
min-height: 100%;
.edit-mode & {
.mode-edit & {
position: absolute;
top: 0;
right: 0;
@@ -19,7 +19,7 @@ html, body {
}
}
.edit-mode {
.mode-edit {
#editor-wrapper {
position: fixed;
top: 0;
@@ -42,7 +42,7 @@ html, body {
width: @contentMaxWidth;
margin: 0 auto;
.edit-mode & {
.mode-edit & {
width: auto;
margin: 0 @contentMinMarginX;
}
@@ -59,7 +59,7 @@ html, body {
top: 0;
width: 100%;
.edit-mode & {
.mode-edit & {
width: 50%;
}
}
@@ -74,3 +74,10 @@ footer {
bottom: 0;
width: 100%;
}
.mode-createUser {
form {
width: 600px;
margin: 100px auto;
}
}

View File

@@ -50,3 +50,15 @@ footer {
background: lighten(@colorEditorBg, 10%) !important;
}
}
.mode-createUser {
form {
border: 1px solid #ccc;
border-radius: 4px;
padding: 20px;
}
#result-box {
margin-top: 30px;
display: none;
}
}

View File

@@ -5,5 +5,6 @@ if (function_exists('date_default_timezone_set')) {
}
$config['wikiName'] = 'Slim Wiki';
$config['lang'] = 'en'; // 'de' or 'en'
//$config['footerHtml'] = '&copy; Copyright 2000-'.date('Y').' My name';

8
src/server/i18n/de.php Normal file
View File

@@ -0,0 +1,8 @@
<?php
$i18n = array(
'createUser.userName' => 'Benutzername',
'createUser.password' => 'Passwort',
'createUser.showConfig' => 'Konfiguration anzeigen',
'createUser.addToConfig' => 'Fügen Sie die folgende Zeile zu Ihrer <code>config.php</code> hinzu:'
);

8
src/server/i18n/en.php Normal file
View File

@@ -0,0 +1,8 @@
<?php
$i18n = array(
'createUser.userName' => 'User name',
'createUser.password' => 'Password',
'createUser.showConfig' => 'Show config',
'createUser.addToConfig' => 'Add the following line to your <code>config.php</code>:'
);

View File

@@ -1,4 +1,8 @@
<!doctype html>
<?php
$mode = $data['mode'];
?><!doctype html>
<html>
<head>
<meta charset="utf-8">
@@ -9,12 +13,12 @@
<base href="<?php echo $data['baseUrl']; ?>">
<?php if ($data['isEditMode']) { ?>
<?php if ($mode == 'edit') { ?>
<!-- build:css client/edit.css -->
<link href="client/libs/CodeMirror/lib/codemirror.css" rel="stylesheet">
<link href="client/libs/CodeMirror/theme/railscasts.css" rel="stylesheet">
<!-- endbuild -->
<?php } // if $data['isEditMode'] ?>
<?php } // if ($mode == 'edit') ?>
<!-- build:css client/view.css -->
<!--
@@ -28,50 +32,77 @@
<!-- endbuild -->
</head>
<body<?php echo $data['isEditMode'] ? ' class="edit-mode"' : '' ?>>
<?php
if ($data['isEditMode']) {
?><div id="editor-wrapper">
<textarea id="editor"><?php echo str_replace('<', '&lt;', $data['articleMarkdown']); ?></textarea>
</div><?php
}
?>
<div id="main-wrapper">
<nav class="breadcrumbs"><div class="main-column"><?php
$isFirst = true;
foreach ($data['breadcrumbs'] as $item) {
if (! $isFirst) {
echo ' / ';
}
if ($item['active']) {
echo $item['name'];
} else {
?><a href="<?php echo $data['basePath'] . $item['path'] . ($data['isEditMode'] ? '?edit' : ''); ?>"><?php echo $item['name']; ?></a><?php
}
$isFirst = false;
}
?></div></nav>
<article id="content" class="markdown main-column"><?php echo $data['articleHtml']; ?></article>
<?php
if (isset($data['footerHtml'])) {
?><footer><div class="main-column"><?php echo $data['footerHtml']; ?></div></footer><?php
}
?>
</div>
</body>
<body class="mode-<?php echo $mode; ?>">
<?php if ($data['isEditMode']) { ?>
<?php
if ($mode == 'edit') {
?><div id="editor-wrapper">
<textarea id="editor"><?php echo str_replace('<', '&lt;', $data['articleMarkdown']); ?></textarea>
</div><?php
} // if ($mode == 'edit')
?>
<div id="main-wrapper"><?php
if ($mode == 'view' || $mode == 'edit') {
?>
<nav class="breadcrumbs"><div class="main-column"><?php
$isFirst = true;
foreach ($data['breadcrumbs'] as $item) {
if (! $isFirst) {
echo ' / ';
}
if ($item['active']) {
echo $item['name'];
} else {
?><a href="<?php echo $data['basePath'] . $item['path'] . (($mode == 'edit') ? '?edit' : ''); ?>"><?php echo $item['name']; ?></a><?php
}
$isFirst = false;
}
?></div></nav>
<article id="content" class="markdown main-column"><?php echo $data['articleHtml']; ?></article>
<?php
} // if ($mode == 'view' || $mode == 'edit')
if ($mode == 'createUser') {
?>
<form onsubmit="return false">
<div class="form-group">
<label for="user"><?php echo $i18n['createUser.userName']; ?></label>
<input type="text" class="form-control" id="user" placeholder="<?php echo $i18n['createUser.userName']; ?>">
</div>
<div class="form-group">
<label for="password"><?php echo $i18n['createUser.password']; ?></label>
<input type="password" class="form-control" id="password" placeholder="<?php echo $i18n['createUser.password']; ?>">
</div>
<button id="showConfigBtn" class="btn btn-primary"><?php echo $i18n['createUser.showConfig']; ?></button>
<div id="result-box" class="markdown">
<?php echo $i18n['createUser.addToConfig']; ?>
<pre><code id="result"></code></pre>
</div>
</form>
<?php
} // if ($mode == 'createUser')
if (isset($data['footerHtml'])) {
?><footer><div class="main-column"><?php echo $data['footerHtml']; ?></div></footer><?php
}
?></div><?php // id="main-wrapper" ?>
<script type="text/javascript">
window.slimwiki = <?php
echo json_encode(array(
"settings" => array(
"articleFilename" => $data['articleFilename']
)
));
$settings = array(
"mode" => $mode
);
if ($mode == 'edit') {
$settings['articleFilename'] = $data['articleFilename'];
}
echo json_encode(array( "settings" => $settings ));
?>;
</script>
<?php if ($mode == 'edit') { ?>
<!-- build:js client/edit.js -->
<script src="client/libs/CodeMirror/lib/codemirror.js"></script>
<script src="client/libs/CodeMirror/addon/mode/overlay.js"></script> <!-- Allow language-in-language -->
@@ -89,7 +120,7 @@
<script src="client/js/app-edit.js"></script>
<!-- endbuild -->
<?php } // if $data['isEditMode'] ?>
<?php } // if ($mode == 'edit') ?>
<!-- build:js client/view.js -->
<script src="client/libs/highlightjs/highlight.pack.js"></script>
@@ -97,4 +128,5 @@
<script src="client/js/app-view.js"></script>
<!-- endbuild -->
</body>
</html>

View File

@@ -3,6 +3,7 @@
class Context {
private $config;
private $i18n;
private $articleBaseDir;
private $dataBaseDir;
@@ -26,7 +27,8 @@ class Context {
// Defaults
$config = array(
'wikiName' => 'Slim Wiki',
'timezone' => 'Europe/Berlin'
'timezone' => 'Europe/Berlin',
'lang' => 'en'
);
if (file_exists(__DIR__ . '/../../config.php')) {
@@ -37,6 +39,18 @@ class Context {
return $config;
}
public function getI18n() {
if (! is_null($this->i18n)) {
return $this->i18n;
}
$lang = $this->getConfig()['lang'];
include(__DIR__ . "/../i18n/$lang.php");
$this->i18n = $i18n;
return $i18n;
}
public function getArticleBaseDir() {
return $this->articleBaseDir;
}

View File

@@ -10,7 +10,7 @@ class EditorService {
}
public function isRpcMethod($methodName) {
return ($methodName == 'saveArticle');
return ($methodName == 'saveArticle' || $methodName == 'createUserConfig');
}
public function saveArticle($articleFilename, $markdownText) {
@@ -42,4 +42,12 @@ class EditorService {
return $this->context->getRenderService()->renderMarkdown($markdownText, true);
}
public function createUserConfig($user, $pass) {
$type = 'sha256';
$salt = uniqid(mt_rand(), true);
$hash = hash($type, $pass . $salt);
return "\$config['user.".strtolower($user)."'] = array('type' => '$type', 'salt' => '$salt', 'hash' => '$hash');";
}
}

View File

@@ -73,7 +73,11 @@ class Main {
}
private function handleGet($baseUrl, $basePath, $requestPathArray, $requestQuery) {
$isEditMode = $requestQuery == 'edit';
if ($requestQuery == 'edit' || $requestQuery == 'createUser') {
$mode = $requestQuery;
} else {
$mode = 'view';
}
$articleFilename = $this->getArticleFilename($requestPathArray);
if ($articleFilename == null) {
@@ -86,7 +90,7 @@ class Main {
$data = array();
$data['baseUrl'] = $baseUrl;
$data['basePath'] = $basePath;
$data['isEditMode'] = $isEditMode;
$data['mode'] = $mode;
foreach (array('wikiName', 'footerHtml') as $key) {
$data[$key] = $config[$key];
@@ -97,7 +101,7 @@ class Main {
$data['articleFilename'] = $articleFilename;
$articleMarkdown = file_get_contents($this->context->getArticleBaseDir() . $articleFilename);
$data['articleMarkdown'] = $articleMarkdown;
$data['articleHtml'] = $this->context->getRenderService()->renderMarkdown($articleMarkdown, $isEditMode);
$data['articleHtml'] = $this->context->getRenderService()->renderMarkdown($articleMarkdown, $mode == 'edit');
$this->renderPage($data);
}
@@ -153,6 +157,7 @@ class Main {
private function renderPage($data) {
header('Content-Type:text/html; charset=utf-8');
$i18n = $this->context->getI18n();
include(__DIR__ . '/../layout/page.php');
}