mirror of
https://github.com/danpros/htmly.git
synced 2026-04-18 11:36:20 +05:30
Add markdown editor
Add markdown editor so anyone can test it. Fix explode on tags.
This commit is contained in:
parent
8c685f9d68
commit
e829ae974f
22 changed files with 4398 additions and 5 deletions
32
admin/editor/LICENSE.txt
Normal file
32
admin/editor/LICENSE.txt
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
A javascript port of Markdown, as used on Stack Overflow
|
||||
and the rest of Stack Exchange network.
|
||||
|
||||
Largely based on showdown.js by John Fraser (Attacklab).
|
||||
|
||||
Original Markdown Copyright (c) 2004-2005 John Gruber
|
||||
<http://daringfireball.net/projects/markdown/>
|
||||
|
||||
|
||||
Original Showdown code copyright (c) 2007 John Fraser
|
||||
|
||||
Modifications and bugfixes (c) 2009 Dana Robinson
|
||||
Modifications and bugfixes (c) 2009-2013 Stack Exchange Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
0
admin/editor/README.txt
Normal file
0
admin/editor/README.txt
Normal file
141
admin/editor/css/editor.css
Normal file
141
admin/editor/css/editor.css
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 2px dotted #888;
|
||||
padding-left: 5px;
|
||||
background: #d0f0ff;
|
||||
}
|
||||
|
||||
.wmd-panel{
|
||||
width: 46%;
|
||||
float:left;
|
||||
padding:2%;
|
||||
}
|
||||
|
||||
.wmd-button-bar {
|
||||
background-color: #FEFEFE;
|
||||
padding: 5px 0;
|
||||
margin-bottom:10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wmd-input {
|
||||
height: 300px;
|
||||
width: 96%;
|
||||
background-color: #FFFFFF;
|
||||
border:none;
|
||||
padding: 2%;
|
||||
}
|
||||
|
||||
.wmd-preview {
|
||||
background-color: #c0e0ff;
|
||||
width: 46%;
|
||||
float:left;
|
||||
padding:2%;
|
||||
}
|
||||
|
||||
.wmd-button-row {
|
||||
position: relative;
|
||||
margin:0px;
|
||||
padding: 0px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.wmd-spacer{
|
||||
width: 1px;
|
||||
height: 20px;
|
||||
margin-left: 14px;
|
||||
position: absolute;
|
||||
background-color: Silver;
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.wmd-button {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding-left: 2px;
|
||||
padding-right: 3px;
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wmd-button > span {
|
||||
background-image: url(../img/wmd-buttons.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0px 0px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.wmd-spacer1{
|
||||
left: 50px;
|
||||
}
|
||||
|
||||
.wmd-spacer2{
|
||||
left: 175px;
|
||||
}
|
||||
.wmd-spacer3{
|
||||
left: 300px;
|
||||
}
|
||||
|
||||
.wmd-prompt-background{
|
||||
background-color: Black;
|
||||
}
|
||||
|
||||
.wmd-prompt-dialog{
|
||||
border: 1px solid #999999;
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
.wmd-prompt-dialog > div {
|
||||
font-size: 0.8em;
|
||||
font-family: arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
.wmd-prompt-dialog > form > input[type="text"] {
|
||||
border: 1px solid #999999;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.wmd-prompt-dialog > form > input[type="button"]{
|
||||
border: 1px solid #888888;
|
||||
font-family: trebuchet MS, helvetica, sans-serif;
|
||||
font-size: 0.8em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
background: #F1F1FF;
|
||||
}
|
||||
|
||||
pre code {
|
||||
color: #333333;
|
||||
display: block;
|
||||
font-family: Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;
|
||||
font-size: 14px;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
@media all and (max-width: 980px) {
|
||||
|
||||
.wmd-panel, .wmd-preview {
|
||||
width: 96%;
|
||||
float:left;
|
||||
padding:2%;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-wrap:break-word;
|
||||
}
|
||||
|
||||
}
|
||||
BIN
admin/editor/img/wmd-buttons.png
Normal file
BIN
admin/editor/img/wmd-buttons.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.3 KiB |
1412
admin/editor/js/Markdown.Converter.js
Normal file
1412
admin/editor/js/Markdown.Converter.js
Normal file
File diff suppressed because it is too large
Load diff
2212
admin/editor/js/Markdown.Editor.js
Normal file
2212
admin/editor/js/Markdown.Editor.js
Normal file
File diff suppressed because it is too large
Load diff
108
admin/editor/js/Markdown.Sanitizer.js
Normal file
108
admin/editor/js/Markdown.Sanitizer.js
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
(function () {
|
||||
var output, Converter;
|
||||
if (typeof exports === "object" && typeof require === "function") { // we're in a CommonJS (e.g. Node.js) module
|
||||
output = exports;
|
||||
Converter = require("./Markdown.Converter").Converter;
|
||||
} else {
|
||||
output = window.Markdown;
|
||||
Converter = output.Converter;
|
||||
}
|
||||
|
||||
output.getSanitizingConverter = function () {
|
||||
var converter = new Converter();
|
||||
converter.hooks.chain("postConversion", sanitizeHtml);
|
||||
converter.hooks.chain("postConversion", balanceTags);
|
||||
return converter;
|
||||
}
|
||||
|
||||
function sanitizeHtml(html) {
|
||||
return html.replace(/<[^>]*>?/gi, sanitizeTag);
|
||||
}
|
||||
|
||||
// (tags that can be opened/closed) | (tags that stand alone)
|
||||
var basic_tag_whitelist = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i;
|
||||
// <a href="url..." optional title>|</a>
|
||||
var a_white = /^(<a\shref="((https?|ftp):\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+"(\stitle="[^"<>]+")?\s?>|<\/a>)$/i;
|
||||
|
||||
// <img src="url..." optional width optional height optional alt optional title
|
||||
var img_white = /^(<img\ssrc="(https?:\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+"(\swidth="\d{1,3}")?(\sheight="\d{1,3}")?(\salt="[^"<>]*")?(\stitle="[^"<>]*")?\s?\/?>)$/i;
|
||||
|
||||
function sanitizeTag(tag) {
|
||||
if (tag.match(basic_tag_whitelist) || tag.match(a_white) || tag.match(img_white))
|
||||
return tag;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// attempt to balance HTML tags in the html string
|
||||
/// by removing any unmatched opening or closing tags
|
||||
/// IMPORTANT: we *assume* HTML has *already* been
|
||||
/// sanitized and is safe/sane before balancing!
|
||||
///
|
||||
/// adapted from CODESNIPPET: A8591DBA-D1D3-11DE-947C-BA5556D89593
|
||||
/// </summary>
|
||||
function balanceTags(html) {
|
||||
|
||||
if (html == "")
|
||||
return "";
|
||||
|
||||
var re = /<\/?\w+[^>]*(\s|$|>)/g;
|
||||
// convert everything to lower case; this makes
|
||||
// our case insensitive comparisons easier
|
||||
var tags = html.toLowerCase().match(re);
|
||||
|
||||
// no HTML tags present? nothing to do; exit now
|
||||
var tagcount = (tags || []).length;
|
||||
if (tagcount == 0)
|
||||
return html;
|
||||
|
||||
var tagname, tag;
|
||||
var ignoredtags = "<p><img><br><li><hr>";
|
||||
var match;
|
||||
var tagpaired = [];
|
||||
var tagremove = [];
|
||||
var needsRemoval = false;
|
||||
|
||||
// loop through matched tags in forward order
|
||||
for (var ctag = 0; ctag < tagcount; ctag++) {
|
||||
tagname = tags[ctag].replace(/<\/?(\w+).*/, "$1");
|
||||
// skip any already paired tags
|
||||
// and skip tags in our ignore list; assume they're self-closed
|
||||
if (tagpaired[ctag] || ignoredtags.search("<" + tagname + ">") > -1)
|
||||
continue;
|
||||
|
||||
tag = tags[ctag];
|
||||
match = -1;
|
||||
|
||||
if (!/^<\//.test(tag)) {
|
||||
// this is an opening tag
|
||||
// search forwards (next tags), look for closing tags
|
||||
for (var ntag = ctag + 1; ntag < tagcount; ntag++) {
|
||||
if (!tagpaired[ntag] && tags[ntag] == "</" + tagname + ">") {
|
||||
match = ntag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match == -1)
|
||||
needsRemoval = tagremove[ctag] = true; // mark for removal
|
||||
else
|
||||
tagpaired[match] = true; // mark paired
|
||||
}
|
||||
|
||||
if (!needsRemoval)
|
||||
return html;
|
||||
|
||||
// delete all orphaned tags from the string
|
||||
|
||||
var ctag = 0;
|
||||
html = html.replace(re, function (match) {
|
||||
var res = tagremove[ctag] ? "" : match;
|
||||
ctag++;
|
||||
return res;
|
||||
});
|
||||
return html;
|
||||
}
|
||||
})();
|
||||
43
admin/editor/js/local/Markdown.local.fr.js
Normal file
43
admin/editor/js/local/Markdown.local.fr.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Usage:
|
||||
//
|
||||
// var myConverter = new Markdown.Editor(myConverter, null, { strings: Markdown.local.fr });
|
||||
|
||||
(function () {
|
||||
Markdown.local = Markdown.local || {};
|
||||
Markdown.local.fr = {
|
||||
bold: "Gras <strong> Ctrl+B",
|
||||
boldexample: "texte en gras",
|
||||
|
||||
italic: "Italique <em> Ctrl+I",
|
||||
italicexample: "texte en italique",
|
||||
|
||||
link: "Hyperlien <a> Ctrl+L",
|
||||
linkdescription: "description de l'hyperlien",
|
||||
linkdialog: "<p><b>Insérer un hyperlien</b></p><p>http://example.com/ \"titre optionnel\"</p>",
|
||||
|
||||
quote: "Citation <blockquote> Ctrl+Q",
|
||||
quoteexample: "Citation",
|
||||
|
||||
code: "Extrait de code <pre><code> Ctrl+K",
|
||||
codeexample: "votre extrait de code",
|
||||
|
||||
image: "Image <img> Ctrl+G",
|
||||
imagedescription: "description de l'image",
|
||||
imagedialog: "<p><b>Insérer une image</b></p><p>http://example.com/images/diagram.jpg \"titre optionnel\"<br><br><a href='http://www.google.com/search?q=free+image+hosting' target='_blank'>Vous chercher un hébergement d'image grauit ?</a></p>",
|
||||
|
||||
olist: "Liste numérotée <ol> Ctrl+O",
|
||||
ulist: "Liste à point <ul> Ctrl+U",
|
||||
litem: "Elément de liste",
|
||||
|
||||
heading: "Titre <h1>/<h2> Ctrl+H",
|
||||
headingexample: "Titre",
|
||||
|
||||
hr: "Trait horizontal <hr> Ctrl+R",
|
||||
|
||||
undo: "Annuler - Ctrl+Z",
|
||||
redo: "Refaire - Ctrl+Y",
|
||||
redomac: "Refaire - Ctrl+Shift+Z",
|
||||
|
||||
help: "Aide sur Markdown"
|
||||
};
|
||||
})();
|
||||
2
admin/editor/js/node-pagedown.js
Normal file
2
admin/editor/js/node-pagedown.js
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
exports.Converter = require("./Markdown.Converter").Converter;
|
||||
exports.getSanitizingConverter = require("./Markdown.Sanitizer").getSanitizingConverter;
|
||||
12
admin/editor/package.json
Normal file
12
admin/editor/package.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "pagedown",
|
||||
"version": "1.1.0",
|
||||
"description": "markdown converter, based on showdown",
|
||||
"repository": { "type": "hg", "url": "https://code.google.com/p/pagedown/" },
|
||||
"keywords": ["markdown"],
|
||||
"license": "MIT",
|
||||
"files": ["Markdown.Converter.js", "Markdown.Sanitizer.js", "node-pagedown.js"],
|
||||
"main": "node-pagedown.js",
|
||||
"bugs": "http://code.google.com/p/pagedown/issues/list",
|
||||
"homepage": "http://code.google.com/p/pagedown/wiki/PageDown"
|
||||
}
|
||||
18
admin/includes/auth.php
Normal file
18
admin/includes/auth.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<div id="login">
|
||||
<?php if (login()) { ?>
|
||||
|
||||
<div class="nav">
|
||||
<a href="<?php echo config('site.url');?>/admin">Admin</a>
|
||||
<a href="includes/create_post.php">Create post</a>
|
||||
<a href="includes/logout.php">Logout</a>
|
||||
<span class="welcome">Welcome <?php echo $_SESSION['user'];?>!</span>
|
||||
</div>
|
||||
<?php include 'includes/post_list.php';?>
|
||||
|
||||
<?php } else {?>
|
||||
|
||||
<?php include 'includes/login.php';?>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
80
admin/includes/create_post.php
Normal file
80
admin/includes/create_post.php
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
// Change this to your timezone
|
||||
date_default_timezone_set('Asia/Jakarta');
|
||||
require '../../system/includes/dispatch.php';
|
||||
config('source', '../../admin/config.ini');
|
||||
include '../includes/session.php';
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Create post</title>
|
||||
<link rel="stylesheet" type="text/css" href="../resources/style.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../editor/css/editor.css" />
|
||||
<script type="text/javascript" src="../editor/js/Markdown.Converter.js"></script>
|
||||
<script type="text/javascript" src="../editor/js/Markdown.Sanitizer.js"></script>
|
||||
<script type="text/javascript" src="../editor/js/Markdown.Editor.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper-outer">
|
||||
<div class="wrapper-inner">
|
||||
<?php if (login()) { ?>
|
||||
<div class="nav">
|
||||
<a href="<?php echo config('site.url');?>/admin">Admin</a>
|
||||
<a href="../includes/logout.php">Logout</a>
|
||||
<span class="welcome">Welcome <?php echo $_SESSION['user'];?>!</span>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if(isset($_POST['submit'])) {
|
||||
$post_date = date('Y-m-d-H');
|
||||
$post_tag = $_POST['tag'];
|
||||
$post_url = $_POST['url'];
|
||||
$post_content = $_POST['content'];
|
||||
}
|
||||
if(!empty($post_tag) && !empty($post_url) && !empty($post_content)) {
|
||||
$user = $_SESSION['user'];
|
||||
$filename = $post_date . '_' . $post_tag . '_' . $post_url . '.md';
|
||||
$dir = '../../content/' . $user. '/blog/';
|
||||
if(is_dir($dir)) {
|
||||
file_put_contents($dir . $filename, print_r($post_content, true));
|
||||
}
|
||||
else {
|
||||
mkdir($dir, 0777, true);
|
||||
file_put_contents($dir . $filename, print_r($post_content, true));
|
||||
}
|
||||
header('location: ../index.php');
|
||||
}
|
||||
?>
|
||||
<?php } else {?>
|
||||
<?php header('location: ../index.php');?>
|
||||
<?php } ?>
|
||||
<div class="wmd-panel">
|
||||
<form method="POST">
|
||||
Tag: <br><input type="text" name="tag"/><br><br>
|
||||
Url: <br><input type="text" name="url"/><br><br>
|
||||
<div id="wmd-button-bar" class="wmd-button-bar"></div>
|
||||
<textarea id="wmd-input" class="wmd-input" name="content" cols="20" rows="10"></textarea><br/>
|
||||
<input type="submit" name="submit" value="Publish"/>
|
||||
</form>
|
||||
</div>
|
||||
<div id="wmd-preview" class="wmd-panel wmd-preview"></div>
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
var converter = Markdown.getSanitizingConverter();
|
||||
|
||||
converter.hooks.chain("preBlockGamut", function (text, rbg) {
|
||||
return text.replace(/^ {0,3}""" *\n((?:.*?\n)+?) {0,3}""" *$/gm, function (whole, inner) {
|
||||
return "<blockquote>" + rbg(inner) + "</blockquote>\n";
|
||||
});
|
||||
});
|
||||
|
||||
var editor = new Markdown.Editor(converter);
|
||||
|
||||
editor.run();
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
72
admin/includes/edit_post.php
Normal file
72
admin/includes/edit_post.php
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
// Change this to your timezone
|
||||
date_default_timezone_set('Asia/Jakarta');
|
||||
require '../../system/includes/dispatch.php';
|
||||
config('source', '../../admin/config.ini');
|
||||
include '../includes/session.php';;
|
||||
if(isset($_GET['url'])) {
|
||||
$url = $_GET['url'];
|
||||
}
|
||||
else {
|
||||
header('location: ../index.php');
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Edit post</title>
|
||||
<link rel="stylesheet" type="text/css" href="../resources/style.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../editor/css/editor.css" />
|
||||
<script type="text/javascript" src="../editor/js/Markdown.Converter.js"></script>
|
||||
<script type="text/javascript" src="../editor/js/Markdown.Sanitizer.js"></script>
|
||||
<script type="text/javascript" src="../editor/js/Markdown.Editor.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper-outer">
|
||||
<div class="wrapper-inner">
|
||||
<?php if (login()) { ?>
|
||||
<div class="nav">
|
||||
<a href="<?php echo config('site.url');?>/admin">Admin</a>
|
||||
<a href="../includes/create_post.php">Create post</a>
|
||||
<a href="../includes/logout.php">Logout</a>
|
||||
<span class="welcome">Welcome <?php echo $_SESSION['user'];?>!</span>
|
||||
</div>
|
||||
<?php } else {?>
|
||||
<?php header('location: ../index.php');?>
|
||||
<?php } ?>
|
||||
<?php
|
||||
if(isset($_POST['submit'])) {
|
||||
$post_content = $_POST['content'];
|
||||
}
|
||||
if(!empty($post_content)) {
|
||||
file_put_contents('../'. $url, print_r($post_content, true));
|
||||
header('location: ../index.php');
|
||||
}
|
||||
?>
|
||||
<div class="wmd-panel">
|
||||
<form method="POST">
|
||||
<div id="wmd-button-bar" class="wmd-button-bar"></div>
|
||||
<textarea id="wmd-input" class="wmd-input" name="content" cols="20" rows="10"><?php echo file_get_contents('../' . $url)?></textarea><br>
|
||||
<input type="submit" name="submit" value="Submit"/>
|
||||
</form>
|
||||
</div>
|
||||
<div id="wmd-preview" class="wmd-panel wmd-preview"></div>
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
var converter = Markdown.getSanitizingConverter();
|
||||
|
||||
converter.hooks.chain("preBlockGamut", function (text, rbg) {
|
||||
return text.replace(/^ {0,3}""" *\n((?:.*?\n)+?) {0,3}""" *$/gm, function (whole, inner) {
|
||||
return "<blockquote>" + rbg(inner) + "</blockquote>\n";
|
||||
});
|
||||
});
|
||||
|
||||
var editor = new Markdown.Editor(converter);
|
||||
|
||||
editor.run();
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
32
admin/includes/login.php
Normal file
32
admin/includes/login.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
if(isset($_POST['submit'])) {
|
||||
|
||||
$user = $_POST['user'];
|
||||
$user_file = 'users/' . $user . '.txt';
|
||||
$pass = $_POST['password'];
|
||||
$user_pass = @file_get_contents($user_file);
|
||||
|
||||
if(file_exists($user_file)) {
|
||||
if($pass === $user_pass) {
|
||||
$_SESSION['user'] = $user;
|
||||
header('location: index.php');
|
||||
}
|
||||
else {
|
||||
echo 'Username and password not match!';
|
||||
}
|
||||
}
|
||||
else {
|
||||
echo 'Please create username.txt inside "admin/users" folder and put your password inside it.';
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
<p>Login Form</p>
|
||||
<form method="POST">
|
||||
User:<br>
|
||||
<input type="text" name="user"/><br><br>
|
||||
Pass:<br>
|
||||
<input type="password" name="password"/><br><br>
|
||||
<input type="submit" name="submit" value="Login"/>
|
||||
</form>
|
||||
9
admin/includes/logout.php
Normal file
9
admin/includes/logout.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
include 'session.php';
|
||||
|
||||
session_destroy();
|
||||
|
||||
header('location: ../index.php');
|
||||
|
||||
?>
|
||||
134
admin/includes/post_list.php
Normal file
134
admin/includes/post_list.php
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
// Get blog post with more info about the path. Sorted by filename.
|
||||
function admin_get_post(){
|
||||
|
||||
static $tmp= array();
|
||||
|
||||
static $_cache = array();
|
||||
|
||||
if(empty($_cache)){
|
||||
|
||||
// Get the names of all the posts
|
||||
|
||||
$tmp = glob('../content/*/blog/*.md', GLOB_NOSORT);
|
||||
|
||||
foreach($tmp as $file) {
|
||||
$_cache[] = pathinfo($file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
usort($_cache, "sortfile");
|
||||
|
||||
return $_cache;
|
||||
}
|
||||
|
||||
// usort function. Sort by filename.
|
||||
function sortfile($a, $b) {
|
||||
return $a['filename'] == $b['filename'] ? 0 : ( $a['filename'] < $b['filename'] ) ? 1 : -1;
|
||||
}
|
||||
// Return blog posts.
|
||||
function get_posts($posts, $page = 1, $perpage = 0){
|
||||
|
||||
if(empty($posts)) {
|
||||
$posts = admin_get_post();
|
||||
}
|
||||
|
||||
$tmp = array();
|
||||
|
||||
// Extract a specific page with results
|
||||
$posts = array_slice($posts, ($page-1) * $perpage, $perpage);
|
||||
|
||||
foreach($posts as $index => $v){
|
||||
|
||||
$post = new stdClass;
|
||||
|
||||
$filepath = $v['dirname'] . '/' . $v['basename'];
|
||||
|
||||
// Extract the date
|
||||
$arr = explode('_', $filepath);
|
||||
|
||||
// Replaced string
|
||||
$replaced = substr($arr[0], 0,strrpos($arr[0], '/')) . '/';
|
||||
|
||||
// Author string
|
||||
$str = explode('/', $replaced);
|
||||
$author = $str[count($str)-3];
|
||||
|
||||
// The post author + author url
|
||||
$post->author = $author;
|
||||
$post->authorurl = site_url() . 'author/' . $author;
|
||||
|
||||
// The post date
|
||||
$post->date = strtotime(str_replace($replaced,'',$arr[0]));
|
||||
|
||||
// The archive per day
|
||||
$post->archive = site_url(). 'archive/' . date('Y-m-d', $post->date) ;
|
||||
|
||||
// The post URL
|
||||
$post->url = site_url().date('Y/m', $post->date).'/'.str_replace('.md','',$arr[2]);
|
||||
|
||||
// The post tag
|
||||
$post->tag = str_replace($replaced,'',$arr[1]);
|
||||
|
||||
// The post tag url
|
||||
$post->tagurl = site_url(). 'tag/' . $arr[1];
|
||||
|
||||
$post->file = $filepath;
|
||||
|
||||
// Get the contents and convert it to HTML
|
||||
// $content = file_get_contents($filepath);
|
||||
// $post->content = $content;
|
||||
|
||||
$tmp[] = $post;
|
||||
}
|
||||
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
// Return posts list on profile.
|
||||
function get_profile($profile, $page, $perpage){
|
||||
|
||||
$posts = admin_get_post();
|
||||
|
||||
$tmp = array();
|
||||
|
||||
foreach ($posts as $index => $v) {
|
||||
$url = $v['dirname'];
|
||||
$str = explode('/', $url);
|
||||
$author = $str[count($str)-2];
|
||||
if($profile === $author){
|
||||
$tmp[] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
if(empty($tmp)) {
|
||||
echo '<tr><td>No posts found!</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
return $tmp = get_posts($tmp, $page, $perpage);
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<table>
|
||||
<?php
|
||||
|
||||
$posts = get_profile($_SESSION['user'], null, null);
|
||||
|
||||
if(!empty($posts)) {
|
||||
|
||||
foreach($posts as $p) {
|
||||
echo '<tr>';
|
||||
echo '<td>' . $p->file . '</td>';
|
||||
echo '<td><form method="GET" action="includes/edit_post.php"><input type="submit" name="submit" value="Edit"/><input type="hidden" name="url" value="' . $p->file . '"/></form></td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
</table>
|
||||
16
admin/includes/session.php
Normal file
16
admin/includes/session.php
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
session_start();
|
||||
|
||||
function login() {
|
||||
|
||||
if(isset($_SESSION['user']) && !empty($_SESSION['user'])) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
20
admin/index.php
Normal file
20
admin/index.php
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
date_default_timezone_set('Asia/Jakarta');
|
||||
require '../system/includes/dispatch.php';
|
||||
config('source', '../admin/config.ini');
|
||||
include 'includes/session.php';
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Admin Panel</title>
|
||||
<link rel="stylesheet" type="text/css" href="resources/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper-outer">
|
||||
<div class="wrapper-inner">
|
||||
<?php include 'includes/auth.php'; ?>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
42
admin/resources/style.css
Normal file
42
admin/resources/style.css
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
body {
|
||||
font-size: 16px;
|
||||
font-family: Arial, Verdana;
|
||||
margin:0 auto;
|
||||
padding:0;
|
||||
background: none repeat scroll 0 0 #F9F9F9;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.wrapper-outer {
|
||||
float:left;
|
||||
position:relative;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.wrapper-inner {
|
||||
margin:0 auto;
|
||||
width:980px;
|
||||
}
|
||||
|
||||
.nav {
|
||||
width: 96%;
|
||||
padding:2%;
|
||||
}
|
||||
|
||||
table {
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
table td {
|
||||
border: 1px solid #ccc;
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
@media all and (max-width: 980px) {
|
||||
|
||||
.wrapper-inner {
|
||||
margin:0 auto;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
}
|
||||
1
admin/users/.htaccess
Normal file
1
admin/users/.htaccess
Normal file
|
|
@ -0,0 +1 @@
|
|||
deny from all
|
||||
|
|
@ -207,11 +207,16 @@ function get_tag($tag, $page, $perpage){
|
|||
|
||||
foreach ($posts as $index => $v) {
|
||||
$url = $v['filename'];
|
||||
if( strpos($url, "$tag") !== false){
|
||||
$str = explode('_', $url);
|
||||
if($tag === $str[1]){
|
||||
$tmp[] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
if(empty($tmp)) {
|
||||
not_found();
|
||||
}
|
||||
|
||||
return $tmp = get_posts($tmp, $page, $perpage);
|
||||
|
||||
}
|
||||
|
|
@ -225,11 +230,16 @@ function get_archive($req, $page, $perpage){
|
|||
|
||||
foreach ($posts as $index => $v) {
|
||||
$url = $v['filename'];
|
||||
if( strpos($url, "$req") !== false){
|
||||
$str = explode('_', $url);
|
||||
if( strpos($str[0], "$req") !== false ){
|
||||
$tmp[] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
if(empty($tmp)) {
|
||||
not_found();
|
||||
}
|
||||
|
||||
return $tmp = get_posts($tmp, $page, $perpage);
|
||||
|
||||
}
|
||||
|
|
@ -890,9 +900,6 @@ function get_static_path(){
|
|||
|
||||
$tmp = array();
|
||||
|
||||
// Create a new instance of the markdown parser
|
||||
$md = new MarkdownParser();
|
||||
|
||||
foreach($posts as $index => $v){
|
||||
|
||||
$post = new stdClass;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue