pull/144/head
Henrique Dias 2016-06-27 18:57:54 +01:00
parent 1c55147faa
commit 429b67f661
13 changed files with 568 additions and 215 deletions

View File

@ -113,8 +113,8 @@ button, html [type="button"], [type="reset"], [type="submit"] {
border: none;
border-radius: 2px;
display: inline-block;
height: 36px;
line-height: 36px;
height: 2.25em;
line-height: 2.25em;
outline: 0;
padding: 0 2rem;
text-transform: uppercase;
@ -504,6 +504,23 @@ header form input {
-webkit-box-flex: 1;
-ms-flex-positive: 1;
flex-grow: 1;
position: relative;
}
#listing .item .checkbox {
position: absolute;
top: 0;
right: 0;
border-radius: 50%;
background: #000;
border: 0;
-webkit-appearance: initial;
}
.item:hover {
box-shadow: 0 1px 3px rgba(0, 0, 0, .12), 0 1px 2px rgba(0, 0, 0, .24) !important;
@ -640,3 +657,15 @@ i.spin {
#editor fieldset fieldset {
margin-left: 1em;
}
#editor #submit span {
vertical-align: middle;
transition: 0.2s ease-in-out all;
}
#editor #submit span i {
vertical-align: sub;
font-size: 1.3rem;
margin-right: .2em;
}

View File

@ -455,6 +455,7 @@ var textareaAutoGrow = function() {
var handleEditorPage = function () {
let container = document.getElementById('editor');
let button = document.querySelector('#submit span:first-child');
let kind = container.dataset.kind;
if (kind != 'frontmatter-only') {
@ -482,9 +483,28 @@ var handleEditorPage = function () {
button.addEventListener('click', deleteFrontMatterItem);
});
let addFrontMatterItemButtons = document.getElementsByClassName('add');
Array.from(addFrontMatterItemButtons).forEach(button => {
button.addEventListener('click', addFrontMatterItem);
});
document.querySelector('form').addEventListener('submit', (event) => {
event.preventDefault();
return false;
let data = form2js(document.querySelector('form'));
let html = button.changeToLoading();
let request = new XMLHttpRequest();
request.open("PUT", window.location);
request.setRequestHeader('Kind', kind);
request.send(JSON.stringify(data));
request.onreadystatechange = function() {
if (request.readyState == 4) {
button.changeToDone((request.status != 200), html);
}
}
});
return false;
}
var deleteFrontMatterItem = function(event) {
@ -492,30 +512,42 @@ var deleteFrontMatterItem = function(event) {
document.getElementById(this.dataset.delete).remove();
}
const tempID = "_fm_internal_temporary_id"
var addFrontMatterItem = function(event) {
/*
event.preventDefault();
defaultID = "lorem-ipsum-sin-dolor-amet";
// Remove if there is an incomplete new item
newItem = $("#" + defaultID);
if (newItem.length) {
newItem.remove();
let newItem = document.getElementById(tempID)
if (newItem) {
newItem.remove();
}
block = $(this).parent().parent();
blockType = block.data("type");
blockID = block.attr("id");
let block = this.parentNode;
let type = block.dataset.type;
let id = block.id;
// If the Block Type is an array
if (blockType == "array") {
newID = blockID + "[]";
input = blockID;
input = input.replace(/\[/, '\\[');
input = input.replace(/\]/, '\\]');
block.append('<div id="' + newID + '-' + $('#' + input + ' > div').length + '" data-type="array-item"><input name="' + newID + ':auto" id="' + newID + '"></input><span class="actions"> <button class="delete">&#8722;</button></span></div></div>');
// If the block is an array
if (type === "array") {
let fieldID = id + "[]"
let input = fieldID
let count = block.querySelectorAll('.group > div').length
input = input.replace(/\[/, '\\[');
input = input.replace(/\]/, '\\]');
block.querySelector('.group').insertAdjacentHTML('beforeend', `<div id="${fieldID}-${count}" data-type="array-item">
<input name="${fieldID}" id="${fieldID}" type="text" data-parent-type="array"></input>
<div class="action delete" data-delete="none">
<i class="material-icons">close</i>
</div>
</div>`);
}
/*
// Main add button, after all blocks
if (block.is('div') && block.hasClass("frontmatter")) {
block = $('.blocks');
@ -608,4 +640,6 @@ var addFrontMatterItem = function(event) {
return false;
*/
return false;
}

View File

@ -1,141 +1,349 @@
/**
Author: Jhan Mateo
Date Started: 7/29/2015
Date Ended: 7/30/2015
Description: Using native javascript (no js framework), this application will serializes from form data to Json format.
The MIT License (MIT)
* Copyright (c) 2010 Maxim Vasiliev
*
* 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.
*
* @author Maxim Vasiliev
* Date: 09.09.2010
* Time: 19:02:33
*/
Copyright (c) 2015 Jhan Mateo
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:
(function (root, factory)
{
if (typeof exports !== 'undefined' && typeof module !== 'undefined' && module.exports) {
// NodeJS
module.exports = factory();
}
else if (typeof define === 'function' && define.amd)
{
// AMD. Register as an anonymous module.
define(factory);
}
else
{
// Browser globals
root.form2js = factory();
}
}(this, function ()
{
"use strict";
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
**/
/**
* Returns form values represented as Javascript object
* "name" attribute defines structure of resulting object
*
* @param rootNode {Element|String} root form element (or it's id) or array of root elements
* @param delimiter {String} structure parts delimiter defaults to '.'
* @param skipEmpty {Boolean} should skip empty text values, defaults to true
* @param nodeCallback {Function} custom function to get node value
* @param useIdIfEmptyName {Boolean} if true value of id attribute of field will be used if name of field is empty
*/
function form2js(rootNode, delimiter, skipEmpty, nodeCallback, useIdIfEmptyName, getDisabled)
{
getDisabled = getDisabled ? true : false;
if (typeof skipEmpty == 'undefined' || skipEmpty == null) skipEmpty = true;
if (typeof delimiter == 'undefined' || delimiter == null) delimiter = '.';
if (arguments.length < 5) useIdIfEmptyName = false;
'use strict';
rootNode = typeof rootNode == 'string' ? document.getElementById(rootNode) : rootNode;
function formToJson(form){
var formValues = [],
currNode,
i = 0;
if('form'!==form.nodeName.toLowerCase() && 1!==form.nodeType){
console.log('Form error');
return false;
/* If rootNode is array - combine values */
if (rootNode.constructor == Array || (typeof NodeList != "undefined" && rootNode.constructor == NodeList))
{
while(currNode = rootNode[i++])
{
formValues = formValues.concat(getFormValues(currNode, nodeCallback, useIdIfEmptyName, getDisabled));
}
}
else
{
formValues = getFormValues(rootNode, nodeCallback, useIdIfEmptyName, getDisabled);
}
return processNameValues(formValues, skipEmpty, delimiter);
}
var json_data = {}, new_arr_obj=null, index=null, key=null, input_name=null, new_obj=null;
/**
* Processes collection of { name: 'name', value: 'value' } objects.
* @param nameValues
* @param skipEmpty if true skips elements with value == '' or value == null
* @param delimiter
*/
function processNameValues(nameValues, skipEmpty, delimiter)
{
var result = {},
arrays = {},
i, j, k, l,
value,
nameParts,
currResult,
arrNameFull,
arrName,
arrIdx,
namePart,
name,
_nameParts;
for(var i=0,n=form.length; i<n; i++){
for (i = 0; i < nameValues.length; i++)
{
value = nameValues[i].value;
if(form[i].type!=='submit' || form[i].nodeName.toLowerCase()!=='fieldset' || form[i].nodeName.toLowerCase()!=='reset'){
if (skipEmpty && (value === '' || value === null)) continue;
if(
(form[i]!==undefined && form[i]!==null) &&
(form[i].type==='checkbox' && form[i].checked) ||
(form[i].type==='radio' && form[i].checked) ||
(form[i].type==='text' && form[i].value.length>0) ||
(form[i].type==='range' && form[i].value.length>0) ||
(form[i].type==='select-one' && form[i].options[form[i].selectedIndex].value.length>0) ||
(form[i].type==='select-multiple' && form[i].selectedOptions.length>0) ||
(form[i].type==='textarea' && form[i].value.length>0) ||
(form[i].type==='number' && form[i].value.length>0) ||
(form[i].type==='date' && form[i].value.length>0) ||
(form[i].type==='color' && form[i].value.length>0) ||
(form[i].type==='month' && form[i].value.length>0) ||
(form[i].type==='week' && form[i].value.length>0) ||
(form[i].type==='time' && form[i].value.length>0) ||
(form[i].type==='datetime' && form[i].value.length>0) ||
(form[i].type==='datetime-local' && form[i].value.length>0) ||
(form[i].type==='email' && form[i].value.length>0) ||
(form[i].type==='search' && form[i].value.length>0) ||
(form[i].type==='tel' && form[i].value.length>0) ||
(form[i].type==='url' && form[i].value.length>0) ||
(form[i].type==='image' && form[i].value.length>0) ||
(form[i].type==='file' && form[i].value.length>0)
){
name = nameValues[i].name;
_nameParts = name.split(delimiter);
nameParts = [];
currResult = result;
arrNameFull = '';
/*get the name of the current input*/
input_name = form[i].name;
/*array/object*/
if(input_name.match(/\[.*\]/g)){
if(input_name.match(/\[.+\]/g)){
/*array object, Object[][name]*/
if(input_name.match(/\[.+\]/g)[0].match(/\[[0-9]\]/)!==null){
new_arr_obj = input_name.replace(/\[.+\]/g,''); //get object name
index = input_name.match(/[0-9]/g)[0]; //get index group
key = input_name.match(/\[.+\]/g)[0].replace(/(\[|\]|[0-9])/g,'');
/*create an array in an object*/
if(typeof json_data[new_arr_obj]==='undefined'){
json_data[new_arr_obj] = [];
}
/*create an object inside array*/
if(typeof json_data[new_arr_obj][index]==='undefined'){
json_data[new_arr_obj][index] = {};
}
json_data[new_arr_obj][index][key] = form[i].value;
}else if(input_name.match(/\[.+\]/g)!==null){
//to object
//Object[name]
/*get object name*/
new_obj = input_name.replace(/\[.+\]/g,'');
/*set new object*/
if(typeof json_data[new_obj]==='undefined'){
json_data[new_obj] = {};
}
/*assign a key name*/
key = input_name.match(/\[.+\]/g)[0].replace(/(\[|\])/g,'');
/*set key and form value*/
json_data[new_obj][key] = form[i].value;
}else{}
}else{
/*to array, Object[]*/
key = input_name.replace(/\[.*\]/g, '');
if(form[i].type==='select-multiple'){
for(var j=0, m=form[i].selectedOptions.length; j<m; j++){
if(form[i].selectedOptions[j].value.length>0){
if(typeof json_data[key]==='undefined'){
json_data[key] = [];
}
json_data[key].push(form[i].selectedOptions[j].value);
}
}
}else{
if(typeof json_data[key]==='undefined'){
json_data[key] = [];
}
json_data[key].push(form[i].value);
for(j = 0; j < _nameParts.length; j++)
{
namePart = _nameParts[j].split('][');
if (namePart.length > 1)
{
for(k = 0; k < namePart.length; k++)
{
if (k == 0)
{
namePart[k] = namePart[k] + ']';
}
else if (k == namePart.length - 1)
{
namePart[k] = '[' + namePart[k];
}
else
{
namePart[k] = '[' + namePart[k] + ']';
}
arrIdx = namePart[k].match(/([a-z_]+)?\[([a-z_][a-z0-9_]+?)\]/i);
if (arrIdx)
{
for(l = 1; l < arrIdx.length; l++)
{
if (arrIdx[l]) nameParts.push(arrIdx[l]);
}
}
else{
nameParts.push(namePart[k]);
}
}
}else{
/*basic info*/
key = form[i].name.replace(/\[.*\]/g, '');
json_data[key] = form[i].value;
}
else
nameParts = nameParts.concat(namePart);
}
for (j = 0; j < nameParts.length; j++)
{
namePart = nameParts[j];
if (namePart.indexOf('[]') > -1 && j == nameParts.length - 1)
{
arrName = namePart.substr(0, namePart.indexOf('['));
arrNameFull += arrName;
if (!currResult[arrName]) currResult[arrName] = [];
currResult[arrName].push(value);
}
else if (namePart.indexOf('[') > -1)
{
arrName = namePart.substr(0, namePart.indexOf('['));
arrIdx = namePart.replace(/(^([a-z_]+)?\[)|(\]$)/gi, '');
/* Unique array name */
arrNameFull += '_' + arrName + '_' + arrIdx;
/*
* Because arrIdx in field name can be not zero-based and step can be
* other than 1, we can't use them in target array directly.
* Instead we're making a hash where key is arrIdx and value is a reference to
* added array element
*/
if (!arrays[arrNameFull]) arrays[arrNameFull] = {};
if (arrName != '' && !currResult[arrName]) currResult[arrName] = [];
if (j == nameParts.length - 1)
{
if (arrName == '')
{
currResult.push(value);
arrays[arrNameFull][arrIdx] = currResult[currResult.length - 1];
}
else
{
currResult[arrName].push(value);
arrays[arrNameFull][arrIdx] = currResult[arrName][currResult[arrName].length - 1];
}
}
else
{
if (!arrays[arrNameFull][arrIdx])
{
if ((/^[0-9a-z_]+\[?/i).test(nameParts[j+1])) currResult[arrName].push({});
else currResult[arrName].push([]);
arrays[arrNameFull][arrIdx] = currResult[arrName][currResult[arrName].length - 1];
}
}
currResult = arrays[arrNameFull][arrIdx];
}
else
{
arrNameFull += namePart;
if (j < nameParts.length - 1) /* Not the last part of name - means object */
{
if (!currResult[namePart]) currResult[namePart] = {};
currResult = currResult[namePart];
}
else
{
currResult[namePart] = value;
}
}
}
}
}//endfor
document.getElementById('json_result').innerHTML = JSON.stringify(json_data);
console.log("Result: ",json_data);
return false;
}//endfunc
return result;
}
function getFormValues(rootNode, nodeCallback, useIdIfEmptyName, getDisabled)
{
var result = extractNodeValues(rootNode, nodeCallback, useIdIfEmptyName, getDisabled);
return result.length > 0 ? result : getSubFormValues(rootNode, nodeCallback, useIdIfEmptyName, getDisabled);
}
function getSubFormValues(rootNode, nodeCallback, useIdIfEmptyName, getDisabled)
{
var result = [],
currentNode = rootNode.firstChild;
while (currentNode)
{
result = result.concat(extractNodeValues(currentNode, nodeCallback, useIdIfEmptyName, getDisabled));
currentNode = currentNode.nextSibling;
}
return result;
}
function extractNodeValues(node, nodeCallback, useIdIfEmptyName, getDisabled) {
if (node.disabled && !getDisabled) return [];
var callbackResult, fieldValue, result, fieldName = getFieldName(node, useIdIfEmptyName);
callbackResult = nodeCallback && nodeCallback(node);
if (callbackResult && callbackResult.name) {
result = [callbackResult];
}
else if (fieldName != '' && node.nodeName.match(/INPUT|TEXTAREA/i)) {
fieldValue = getFieldValue(node, getDisabled);
if (null === fieldValue) {
result = [];
} else {
result = [ { name: fieldName, value: fieldValue} ];
}
}
else if (fieldName != '' && node.nodeName.match(/SELECT/i)) {
fieldValue = getFieldValue(node, getDisabled);
result = [ { name: fieldName.replace(/\[\]$/, ''), value: fieldValue } ];
}
else {
result = getSubFormValues(node, nodeCallback, useIdIfEmptyName, getDisabled);
}
return result;
}
function getFieldName(node, useIdIfEmptyName)
{
if (node.name && node.name != '') return node.name;
else if (useIdIfEmptyName && node.id && node.id != '') return node.id;
else return '';
}
function getFieldValue(fieldNode, getDisabled)
{
if (fieldNode.disabled && !getDisabled) return null;
switch (fieldNode.nodeName) {
case 'INPUT':
case 'TEXTAREA':
switch (fieldNode.type.toLowerCase()) {
case 'radio':
if (fieldNode.checked && fieldNode.value === "false") return false;
case 'checkbox':
if (fieldNode.checked && fieldNode.value === "true") return true;
if (!fieldNode.checked && fieldNode.value === "true") return false;
if (fieldNode.checked) return fieldNode.value;
break;
case 'button':
case 'reset':
case 'submit':
case 'image':
return '';
break;
default:
return fieldNode.value;
break;
}
break;
case 'SELECT':
return getSelectedOptionValue(fieldNode);
break;
default:
break;
}
return null;
}
function getSelectedOptionValue(selectNode)
{
var multiple = selectNode.multiple,
result = [],
options,
i, l;
if (!multiple) return selectNode.value;
for (options = selectNode.getElementsByTagName("option"), i = 0, l = options.length; i < l; i++)
{
if (options[i].selected) result.push(options[i].value);
}
return result;
}
return form2js;
}));

View File

@ -7,6 +7,7 @@
<link href='https://fonts.googleapis.com/css?family=Roboto:400,500' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="{{ .Config.BaseURL }}/_filemanagerinternal/css/styles.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.3/ace.js"></script>
<script src="{{ .Config.BaseURL }}/_filemanagerinternal/js/form-to-json.js"></script>
<script src="{{ .Config.BaseURL }}/_filemanagerinternal/js/application.js"></script>
{{ if ne .Config.StyleSheet "" }}<style>{{.Config.StyleSheet}}</style>{{ end }}
</head>

View File

@ -2,7 +2,7 @@
<div id="editor" class="container" data-kind="{{ .Class }}">
<form method="POST" action="./">
{{ if or (eq .Class "frontmatter-only") (eq .Class "complete") }}
<div class="frontmatter">
<div class="frontmatter" data-type="parent">
{{ template "blocks" .FrontMatter }}
<button class="add">Add field</button>
</div>
@ -18,7 +18,8 @@
{{ end }}
<div>
<input type="submit" data-type="{{ .Class }}" value="Save">
<button id="submit" type="submit" data-type="{{ .Class }}"><span><i class="material-icons">save</i></span> <span>save</span>
</button>
</div>
</form>
</div>

View File

@ -28,30 +28,22 @@
{{ template "fielset" $value }}
{{ end }}
<template id="arrayItem">
</template>
<template id="objectItem">
</template>
{{ end }}
{{ define "value" }}
{{ if eq .HTMLType "textarea" }}
<textarea class="scroll" name="{{ .Name }}:{{ .Type }}" id="{{.Name }}" data-parent-type="{{ .Parent.Type }}">{{ .Content.Other }}</textarea>
<textarea class="scroll" name="{{ .Name }}" id="{{.Name }}" data-parent-type="{{ .Parent.Type }}">{{ .Content.Other }}</textarea>
{{ else if eq .HTMLType "datetime" }}
<input name="{{ .Name }}:{{ .Type }}" id="{{ .Name }}" value="{{ .Content.Other.Format "2006-01-02T15:04" }}" type="datetime-local" data-parent-type="{{ .Parent.Type }}"></input>
<input name="{{ .Name }}" id="{{ .Name }}" value="{{ .Content.Other.Format "2006-01-02T15:04" }}" type="datetime-local" data-parent-type="{{ .Parent.Type }}"></input>
{{ else }}
<input name="{{ .Name }}:{{ .Type }}" id="{{ .Name }}" value="{{ .Content.Other }}" type="{{ .HTMLType }}" data-parent-type="{{ .Parent.Type }}"></input>
<input name="{{ .Name }}" id="{{ .Name }}" value="{{ .Content.Other }}" type="{{ .HTMLType }}" data-parent-type="{{ .Parent.Type }}"></input>
{{ end }}
{{ end }}
{{ define "fielset" }}
<fieldset id="{{ .Name }}" data-type="{{ .Type }}">
<h3>{{ SplitCapitalize .Title }}</h3>
{{ if not (eq .Title "") }}<h3>{{ SplitCapitalize .Title }}</h3>{{ end }}
<div class="action add">
<i class="material-icons">add</i>
</div>

View File

@ -25,6 +25,7 @@
</p>
</a>
</div>
<span class="checkbox">
</div>
{{- end}}
</div>

View File

@ -2,6 +2,7 @@
// sources:
// assets/public/css/styles.css
// assets/public/js/application.js
// assets/public/js/form-to-json.js
// assets/templates/actions.tmpl
// assets/templates/base.tmpl
// assets/templates/editor.tmpl
@ -70,6 +71,24 @@ func publicJsApplicationJs() (*asset, error) {
return a, err
}
// publicJsFormToJsonJs reads file data from disk. It returns an error on failure.
func publicJsFormToJsonJs() (*asset, error) {
path := "D:\\Code\\Go\\src\\github.com\\hacdias\\caddy-filemanager\\assets\\public\\js\\form-to-json.js"
name := "public/js/form-to-json.js"
bytes, err := bindataRead(path, name)
if err != nil {
return nil, err
}
fi, err := os.Stat(path)
if err != nil {
err = fmt.Errorf("Error reading asset info %s at %s: %v", name, path, err)
}
a := &asset{bytes: bytes, info: fi}
return a, err
}
// templatesActionsTmpl reads file data from disk. It returns an error on failure.
func templatesActionsTmpl() (*asset, error) {
path := "D:\\Code\\Go\\src\\github.com\\hacdias\\caddy-filemanager\\assets\\templates\\actions.tmpl"
@ -232,6 +251,7 @@ func AssetNames() []string {
var _bindata = map[string]func() (*asset, error){
"public/css/styles.css": publicCssStylesCss,
"public/js/application.js": publicJsApplicationJs,
"public/js/form-to-json.js": publicJsFormToJsonJs,
"templates/actions.tmpl": templatesActionsTmpl,
"templates/base.tmpl": templatesBaseTmpl,
"templates/editor.tmpl": templatesEditorTmpl,
@ -286,6 +306,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
}},
"js": &bintree{nil, map[string]*bintree{
"application.js": &bintree{publicJsApplicationJs, map[string]*bintree{}},
"form-to-json.js": &bintree{publicJsFormToJsonJs, map[string]*bintree{}},
}},
}},
"templates": &bintree{nil, map[string]*bintree{

View File

@ -78,7 +78,6 @@ func (i *Info) GetEditor() (*Editor, error) {
editor.Class = "content-only"
editor.Content = i.Content
}
return editor, nil
}

View File

@ -146,7 +146,7 @@ func handleObjects(content interface{}, parent *Block, name string) *Block {
} else if parent.Type == arrayType {
c.Name = parent.Name + "[]"
} else {
c.Name = parent.Name + "[" + c.Title + "]"
c.Name = parent.Name + "." + c.Title
}
c.Content = rawToPretty(content, c)
@ -162,7 +162,7 @@ func handleArrays(content interface{}, parent *Block, name string) *Block {
if parent.Name == mainName {
c.Name = name
} else {
c.Name = parent.Name + "[" + name + "]"
c.Name = parent.Name + "." + name
}
c.Content = rawToPretty(content, c)
@ -199,7 +199,7 @@ func handleFlatValues(content interface{}, parent *Block, name string) *Block {
c.Title = content.(string)
} else if parent.Type == objectType {
c.Title = name
c.Name = parent.Name + "[" + name + "]"
c.Name = parent.Name + "." + name
if parent.Name == mainName {
c.Name = name

View File

@ -1,68 +1,134 @@
package file
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"path/filepath"
"strings"
"github.com/hacdias/caddy-filemanager/internal/config"
"github.com/spf13/hugo/parser"
)
// Update is
// Update is used to update a file that was edited
func (i *Info) Update(w http.ResponseWriter, r *http.Request, c *config.Config) (int, error) {
var data map[string]interface{}
kind := r.Header.Get("kind")
/*
// POST handles the POST method on editor page
func POST(w http.ResponseWriter, r *http.Request, c *config.Config, filename string) (int, error) {
var data info
// TODO: remove
fmt.Println(i.Name)
// Get the JSON information sent using a buffer
rawBuffer := new(bytes.Buffer)
rawBuffer.ReadFrom(r.Body)
err := json.Unmarshal(rawBuffer.Bytes(), &data)
if kind == "" {
return http.StatusBadRequest, nil
}
fmt.Println(string(rawBuffer.Bytes()))
// Get the JSON information
rawBuffer := new(bytes.Buffer)
rawBuffer.ReadFrom(r.Body)
err := json.Unmarshal(rawBuffer.Bytes(), &data)
if err != nil {
return server.RespondJSON(w, &response{"Error decrypting json."}, http.StatusInternalServerError, err)
}
if err != nil {
return http.StatusInternalServerError, err
}
// Initializes the file content to write
var file []byte
var code int
var file []byte
var code int
switch data.ContentType {
case "frontmatter-only":
file, code, err = parseFrontMatterOnlyFile(data, filename)
if err != nil {
return server.RespondJSON(w, &response{err.Error()}, code, err)
}
case "content-only":
// The main content of the file
mainContent := data.Content["content"].(string)
mainContent = strings.TrimSpace(mainContent)
switch kind {
case "frontmatter-only":
if file, code, err = parseFrontMatterOnlyFile(data, i.Name); err != nil {
return http.StatusInternalServerError, err
}
case "content-only":
mainContent := data["content"].(string)
mainContent = strings.TrimSpace(mainContent)
file = []byte(mainContent)
case "complete":
if file, code, err = parseCompleteFile(data, i.Name); err != nil {
return http.StatusInternalServerError, err
}
default:
return http.StatusBadRequest, nil
}
file = []byte(mainContent)
case "complete":
file, code, err = parseCompleteFile(data, filename, c)
if err != nil {
return server.RespondJSON(w, &response{err.Error()}, code, err)
}
default:
return server.RespondJSON(w, &response{"Invalid content type."}, http.StatusBadRequest, nil)
}
// Write the file
err = ioutil.WriteFile(i.Path, file, 0666)
// Write the file
err = ioutil.WriteFile(filename, file, 0666)
if err != nil {
return http.StatusInternalServerError, err
}
if err != nil {
return server.RespondJSON(w, &response{err.Error()}, http.StatusInternalServerError, err)
}
if data.Regenerate {
go hugo.Run(c, false)
}
return server.RespondJSON(w, nil, http.StatusOK, nil)
}
*/
return 0, nil
return code, nil
}
func parseFrontMatterOnlyFile(data interface{}, filename string) ([]byte, int, error) {
frontmatter := strings.TrimPrefix(filepath.Ext(filename), ".")
var mark rune
switch frontmatter {
case "toml":
mark = rune('+')
case "json":
mark = rune('{')
case "yaml":
mark = rune('-')
default:
return []byte{}, http.StatusBadRequest, errors.New("Can't define the frontmatter.")
}
f, err := parser.InterfaceToFrontMatter(data, mark)
fString := string(f)
// If it's toml or yaml, strip frontmatter identifier
if frontmatter == "toml" {
fString = strings.TrimSuffix(fString, "+++\n")
fString = strings.TrimPrefix(fString, "+++\n")
}
if frontmatter == "yaml" {
fString = strings.TrimSuffix(fString, "---\n")
fString = strings.TrimPrefix(fString, "---\n")
}
f = []byte(fString)
if err != nil {
return []byte{}, http.StatusInternalServerError, err
}
return f, http.StatusOK, nil
}
func parseCompleteFile(data map[string]interface{}, filename string) ([]byte, int, error) {
// The main content of the file
mainContent := data["content"].(string)
mainContent = "\n\n" + strings.TrimSpace(mainContent) + "\n"
// Removes the main content from the rest of the frontmatter
delete(data, "content")
if _, ok := data["date"]; ok {
data["date"] = data["date"].(string) + ":00"
}
// Converts the frontmatter in JSON
jsonFrontmatter, err := json.Marshal(data)
if err != nil {
return []byte{}, http.StatusInternalServerError, err
}
// Indents the json
frontMatterBuffer := new(bytes.Buffer)
json.Indent(frontMatterBuffer, jsonFrontmatter, "", " ")
// Generates the final file
f := new(bytes.Buffer)
f.Write(frontMatterBuffer.Bytes())
f.Write([]byte(mainContent))
return f.Bytes(), http.StatusOK, nil
}

View File

@ -27,12 +27,3 @@ func Run(c *config.Config.Config, force bool) {
log.Panic(err)
}
}
func stringInSlice(a string, list []string) (bool, int) {
for i, b := range list {
if b == a {
return true, i
}
}
return false, 0
}

View File

@ -35,3 +35,13 @@ func Dict(values ...interface{}) (map[string]interface{}, error) {
return dict, nil
}
// StringInSlice checks if a slice contains a string
func StringInSlice(a string, list []string) (bool, int) {
for i, b := range list {
if b == a {
return true, i
}
}
return false, 0
}