added proper f3 tag extension for bulma form
This commit is contained in:
parent
1f10cc7f89
commit
6c936208b7
@ -154,6 +154,7 @@ class KBController {
|
||||
$f3->set('article_tag_ids', $article_tag_ids);
|
||||
|
||||
// render
|
||||
$f3->set('js', 'kb_edit.js');
|
||||
$f3->set('content', '../ui/views/kb/edit.html');
|
||||
echo \Template::instance()->render('../ui/templates/layout.html');
|
||||
$f3->clear('SESSION.error');
|
||||
|
||||
12
app/controllers/ParsedownPreview.php
Normal file
12
app/controllers/ParsedownPreview.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
class ParsedownPreview {
|
||||
|
||||
public function view($f3){
|
||||
|
||||
$preview_text = $f3->get('POST.content');
|
||||
echo Parsedown::instance()->text($preview_text);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
108
app/extensions/BulmaFormHelper.php
Normal file
108
app/extensions/BulmaFormHelper.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
class BulmaFormHelper extends \Prefab {
|
||||
|
||||
const H_FIELD_INPUT = 1;
|
||||
const H_FIELD_TEXTAREA = 2;
|
||||
const H_FIELD_SELECT = 3;
|
||||
|
||||
static public function render($args) {
|
||||
|
||||
$type = strtoupper($args['@attrib']['type']);
|
||||
// all *
|
||||
$label = $args['@attrib']['label'];
|
||||
$name = $args['@attrib']['name'];
|
||||
$value = isset($args['@attrib']['value']) ? $args['@attrib']['value'] : '';
|
||||
// select
|
||||
$options = isset($args['@attrib']['options']) ? $args['@attrib']['options'] : '';
|
||||
$selected = isset($args['@attrib']['selected']) ? $args['@attrib']['selected'] : '';
|
||||
//
|
||||
$label = \Template::instance()->build($label);
|
||||
$name = \Template::instance()->build($name);
|
||||
$value = \Template::instance()->build($value);
|
||||
|
||||
if(defined("BulmaFormHelper::$type")){
|
||||
|
||||
$type_const = constant("BulmaFormHelper::$type");
|
||||
|
||||
switch( $type_const ){
|
||||
case BulmaFormHelper::H_FIELD_INPUT:
|
||||
return BulmaFormHelper::build_h_field_input($label, $name, $value);
|
||||
break;
|
||||
case BulmaFormHelper::H_FIELD_TEXTAREA:
|
||||
return BulmaFormHelper::build_h_field_textarea($label, $name, $value);
|
||||
break;
|
||||
case BulmaFormHelper::H_FIELD_SELECT:
|
||||
return BulmaFormHelper::build_h_field_select($label, $name, $options, $selected);
|
||||
break;
|
||||
default:
|
||||
return '<div class="notification is-danger">Error: Bulma CSS Form TYPE ('.$type.') not defined.</div>';
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
return '<div class="notification is-danger">Error: Bulma CSS Form TYPE not defined.</div>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static function build_h_field_input($label, $name, $value){
|
||||
$string = '
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label is-normal">
|
||||
<label class="label">'.$label.'</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input" type="text" id="'.$name.'" name="'.
|
||||
$name.'" value="'.
|
||||
$value.'">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
return $string;
|
||||
}
|
||||
|
||||
static function build_h_field_select($label, $name, $options, $selected){
|
||||
$string =
|
||||
'<div class="field is-horizontal">
|
||||
<div class="field-label is-normal">
|
||||
<label class="label">'.$label.'</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="select">
|
||||
$options
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
return $string;
|
||||
}
|
||||
|
||||
static function build_h_field_textarea($label, $name, $value){
|
||||
$string = '
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label is-normal">
|
||||
<label class="label">'.$label.'</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<textarea class="textarea" id="'.$name.'" name="'.
|
||||
$name.'">'.$value.'</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
return $string;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
\Template::instance()->extend('bulma', 'BulmaFormHelper::render');
|
||||
20
app/extensions/ParsedownHelper.php
Normal file
20
app/extensions/ParsedownHelper.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
class ParsedownHelper extends \Prefab {
|
||||
|
||||
static public function render($args) {
|
||||
$content = $args[0];
|
||||
$content_token = \Template::instance()->token($content);
|
||||
|
||||
return '
|
||||
<parsedown_rendered class="content">
|
||||
<?php echo \ParsedownHelper::instance()->build('.$content_token.'); ?>
|
||||
</parsedown_rendered>';
|
||||
}
|
||||
|
||||
function build($content){
|
||||
return Parsedown::instance()->text($content);
|
||||
}
|
||||
}
|
||||
|
||||
\Template::instance()->extend('parsedown', 'ParsedownHelper::render');
|
||||
@ -8,7 +8,7 @@ class BulmaForm {
|
||||
$string = '
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label is-normal">
|
||||
<label>%label%</label>
|
||||
<label class="label">%label%</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
@ -31,7 +31,7 @@ class BulmaForm {
|
||||
$string = '
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label is-normal">
|
||||
<label>%label%</label>
|
||||
<label class="label">%label%</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
@ -54,7 +54,7 @@ class BulmaForm {
|
||||
$string = '
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label is-normal">
|
||||
<label>%label%</label>
|
||||
<label class="label">%label%</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
|
||||
@ -6,13 +6,16 @@ $f3 = \Base::instance();
|
||||
/**
|
||||
* Not required yet
|
||||
*/
|
||||
// $htmlpurifier = new \HTMLPurifier();
|
||||
$htmlpurifier = \HTMLPurifier::instance();
|
||||
// $htmlpurifier->purify($input);
|
||||
$md = \Parsedown::instance();
|
||||
$md->setSafeMode(true);
|
||||
|
||||
|
||||
$f3->set('DEBUG', 3); // development debug
|
||||
$f3->config('../app/.env.cfg');
|
||||
$f3->set('DEBUG', 3); // development debug
|
||||
$f3->set('CACHE', FALSE);
|
||||
|
||||
$f3->set('EXT', [new ParsedownHelper, new BulmaFormHelper]);
|
||||
|
||||
$f3->set('DB', new \DB\SQL(
|
||||
'mysql:host=localhost;port=3306;dbname=' . $f3->get('database.db_name'),
|
||||
@ -63,6 +66,8 @@ $f3->route('GET /tags', 'TagController->index');
|
||||
$f3->route('GET /tag/create', 'TagController->createForm');
|
||||
$f3->route('POST /tag/create', 'TagController->create');
|
||||
|
||||
// parsedown preview
|
||||
$f3->route('POST /parsedown/preview', 'ParsedownPreview->view');
|
||||
|
||||
// dashboard
|
||||
$f3->route('GET /dashboard', 'DashboardController->index');
|
||||
|
||||
75
public/js/kb_edit.js
Normal file
75
public/js/kb_edit.js
Normal file
@ -0,0 +1,75 @@
|
||||
|
||||
|
||||
// switch to target tab pane
|
||||
function switchTab(targetId){
|
||||
var panes = document.querySelectorAll('.tab-content .tab-pane');
|
||||
for (var i=0; i< panes.length; i++){
|
||||
panes[i].style.display = 'none';
|
||||
}
|
||||
var targetPane = document.getElementById(targetId);
|
||||
if(targetPane){
|
||||
targetPane.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
// send ajax post request with content to specified url
|
||||
function ajaxPost(content, url, callback){
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', url, true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
xhr.onreadystatechange = function(){
|
||||
if(xhr.readyState === XMLHttpRequest.DONE){
|
||||
if(xhr.status === 200){
|
||||
callback(xhr.responseText);
|
||||
} else {
|
||||
console.error("AJAX error: " + xhr.status);
|
||||
}
|
||||
}
|
||||
};
|
||||
var params = 'content=' + encodeURIComponent(content);
|
||||
xhr.send(params);
|
||||
}
|
||||
|
||||
// load preview via ajax into preview element
|
||||
function loadPreview(previewElement){
|
||||
var sourceId = previewElement.getAttribute('data-source');
|
||||
var handlerUrl = previewElement.getAttribute('data-handler');
|
||||
var method = previewElement.getAttribute('data-method');
|
||||
var sourceElement = document.getElementById(sourceId);
|
||||
if(sourceElement){
|
||||
var content = sourceElement.value;
|
||||
if(method && method.toLowerCase() == 'post'){
|
||||
ajaxPost(content, handlerUrl, function (response){
|
||||
previewElement.innerHTML = response;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initialise tab links to handle tab switching
|
||||
function initTabs(){
|
||||
var tabLinks = document.querySelectorAll('.tabs a[data-target]');
|
||||
for(var i=0; i<tabLinks.length; i++){
|
||||
tabLinks[i].addEventListener('click', function(e){
|
||||
e.preventDefault();
|
||||
var target = this.getAttribute('data-target');
|
||||
switchTab(target);
|
||||
|
||||
// if the new tab has a preview element, load the preview
|
||||
var pane = document.getElementById(target);
|
||||
if(pane){
|
||||
var previewElement = pane.querySelector('.preview');
|
||||
if(previewElement){
|
||||
console.log('pane has preview el')
|
||||
loadPreview(previewElement);
|
||||
} else {
|
||||
console.log('pane doesnt have preview el');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function(){
|
||||
initTabs();
|
||||
});
|
||||
@ -14,10 +14,13 @@
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma-checkradio@2.1/dist/css/bulma-checkradio.min.css">
|
||||
<!-- font awesome -->
|
||||
<link rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"
|
||||
integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg=="
|
||||
crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<!-- additional JS -->
|
||||
<check if="{{ isset(@js) }}">
|
||||
<script src="/js/{{ @js}}"></script>
|
||||
</check>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -85,7 +88,9 @@
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="content has-text-centered">
|
||||
<p>© <?php echo date('Y'); ?> Terry Probert</p>
|
||||
<p>©
|
||||
<?php echo date('Y'); ?> Terry Probert
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
@ -4,18 +4,23 @@
|
||||
<div class="content">
|
||||
<form action="/kb/create" method="POST">
|
||||
|
||||
{{ BulmaForm::horizontal_field_input('Title:', 'title') }}
|
||||
<bulma type="H_FIELD_INPUT" label="Title:" name="title" value=""></bulma>
|
||||
|
||||
<div id="editor" class="block">
|
||||
<div class="tabs">
|
||||
<ul>
|
||||
<li class="is-active"><a>Write</a></li>
|
||||
<li class=""><a>Preivew</a></li>
|
||||
<li class=""><a>Preview</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
{{ BulmaForm::horizontal_field_textarea('Content:', 'content') }}
|
||||
<div class="tab-content">
|
||||
<bulma type="H_FIELD_TEXTAREA" label="Content:" name="content" value=""></bulma>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -3,18 +3,27 @@
|
||||
|
||||
<form action="/kb/{{@article.id}}/update" method="POST">
|
||||
|
||||
{{ BulmaForm::horizontal_field_input('Title:', 'title', @article.title)}}
|
||||
<bulma type="H_FIELD_INPUT" label="Title:" name="title" value="{{@article.title}}"></bulma>
|
||||
|
||||
<div id="editor" class="block">
|
||||
<div class="tabs">
|
||||
<ul>
|
||||
<li class="is-active"><a>Write</a></li>
|
||||
<li class=""><a>Preivew</a></li>
|
||||
<li class="is-active"><a data-target="pane-editor">Write</a></li>
|
||||
<li class=""><a data-target="pane-preview">Preview</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
{{ BulmaForm::horizontal_field_textarea('Content:', 'content', @article.content) }}
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane" id="pane-editor">
|
||||
<div class="block">
|
||||
<bulma type="H_FIELD_TEXTAREA" label="Content:" name="content" value="{{@article.content}}"></bulma>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" id="pane-preview">
|
||||
<div class="block content">
|
||||
<div class="preview" data-source="content" data-handler="/parsedown/preview" data-method="post"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -13,7 +13,15 @@
|
||||
<form method="GET" action="/kb">
|
||||
<div class="level">
|
||||
<div class="level-item">
|
||||
<input class="input" type="text" name="search" placeholder="Search by title...">
|
||||
<check if="{{ isset(@GET.search)}}">
|
||||
<true>
|
||||
<input class="input" type="text" name="search" placeholder="Search by title..."
|
||||
value="{{ HTMLPurifier::instance()->purify( @GET.search) }}">
|
||||
</true>
|
||||
<false>
|
||||
<input class="input" type="text" name="search" placeholder="Search by title...">
|
||||
</false>
|
||||
</check>
|
||||
</div>
|
||||
<div class="level-right">
|
||||
<div class="select">
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<h1 class="title">{{@article.title}}</h1>
|
||||
|
||||
<div class="content">
|
||||
{{ Parsedown::instance()->text(@article.content) }}
|
||||
<parsedown>{{ @article.content | raw }}</parsedown>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user