From 3ca9ed1922ace9831ff384ad1059fcb2381d0493 Mon Sep 17 00:00:00 2001
From: Dan
Date: Mon, 17 Mar 2025 16:02:16 +0700
Subject: [PATCH] Simple custom fields
Currently only supports text, textarea, checkbox and select types.
Can add custom fields to posts, pages/subpages, profile.
---
lang/ar_AR.ini | 1 +
lang/da_DK.ini | 1 +
lang/de_DE.ini | 1 +
lang/de_DE_gender_doppelpunkt.ini | 1 +
lang/de_DE_gender_dudenkonform.ini | 1 +
lang/el_GR.ini | 1 +
lang/en_US.ini | 1 +
lang/eo_EO.ini | 1 +
lang/es_ES.ini | 1 +
lang/fa_IR.ini | 1 +
lang/fr_FR.ini | 1 +
lang/gu_GU.ini | 1 +
lang/hi_HI.ini | 1 +
lang/hr_HR.ini | 1 +
lang/hu_HU.ini | 1 +
lang/id_ID.ini | 1 +
lang/it_IT.ini | 1 +
lang/ko_KO.ini | 1 +
lang/ms_MY.ini | 1 +
lang/nl_NL.ini | 1 +
lang/pl_PL.ini | 1 +
lang/pt_BR.ini | 1 +
lang/ru_RU.ini | 1 +
lang/sv_SE.ini | 1 +
lang/tr_TR.ini | 1 +
lang/uk_UA.ini | 1 +
lang/zh_CN.ini | 1 +
lang/zh_TW.ini | 1 +
system/admin/admin.php | 87 +++-
system/admin/views/add-content.html.php | 53 ++-
system/admin/views/add-page.html.php | 64 ++-
system/admin/views/custom-field-page.html.php | 63 +++
system/admin/views/custom-field-post.html.php | 63 +++
.../admin/views/custom-field-profile.html.php | 63 +++
.../admin/views/custom-field-subpage.html.php | 63 +++
system/admin/views/custom-field.html.php | 36 ++
system/admin/views/edit-content.html.php | 59 ++-
system/admin/views/edit-page.html.php | 87 +++-
system/admin/views/layout.html.php | 7 +
system/htmly.php | 429 ++++++++++++++++--
system/resources/js/form.builder.js | 241 ++++++++++
41 files changed, 1276 insertions(+), 67 deletions(-)
create mode 100644 system/admin/views/custom-field-page.html.php
create mode 100644 system/admin/views/custom-field-post.html.php
create mode 100644 system/admin/views/custom-field-profile.html.php
create mode 100644 system/admin/views/custom-field-subpage.html.php
create mode 100644 system/admin/views/custom-field.html.php
create mode 100644 system/resources/js/form.builder.js
diff --git a/lang/ar_AR.ini b/lang/ar_AR.ini
index 83e9e36..7a04f4e 100644
--- a/lang/ar_AR.ini
+++ b/lang/ar_AR.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/da_DK.ini b/lang/da_DK.ini
index dd18563..dc7c753 100644
--- a/lang/da_DK.ini
+++ b/lang/da_DK.ini
@@ -341,3 +341,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/de_DE.ini b/lang/de_DE.ini
index aa93041..95a8c23 100644
--- a/lang/de_DE.ini
+++ b/lang/de_DE.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/de_DE_gender_doppelpunkt.ini b/lang/de_DE_gender_doppelpunkt.ini
index 524585b..ea8e6f7 100644
--- a/lang/de_DE_gender_doppelpunkt.ini
+++ b/lang/de_DE_gender_doppelpunkt.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/de_DE_gender_dudenkonform.ini b/lang/de_DE_gender_dudenkonform.ini
index d1f019b..4835034 100644
--- a/lang/de_DE_gender_dudenkonform.ini
+++ b/lang/de_DE_gender_dudenkonform.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/el_GR.ini b/lang/el_GR.ini
index b6f3b32..9fbadc7 100644
--- a/lang/el_GR.ini
+++ b/lang/el_GR.ini
@@ -332,3 +332,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/en_US.ini b/lang/en_US.ini
index 2727ad2..16ca47e 100644
--- a/lang/en_US.ini
+++ b/lang/en_US.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/eo_EO.ini b/lang/eo_EO.ini
index 8e78432..9ab02f7 100644
--- a/lang/eo_EO.ini
+++ b/lang/eo_EO.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/es_ES.ini b/lang/es_ES.ini
index 7f09ca6..103226f 100644
--- a/lang/es_ES.ini
+++ b/lang/es_ES.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/fa_IR.ini b/lang/fa_IR.ini
index 5a6a7ae..4bf824f 100644
--- a/lang/fa_IR.ini
+++ b/lang/fa_IR.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/fr_FR.ini b/lang/fr_FR.ini
index da2ab78..a7dd1ec 100644
--- a/lang/fr_FR.ini
+++ b/lang/fr_FR.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/gu_GU.ini b/lang/gu_GU.ini
index d4e7e1e..14d40b2 100644
--- a/lang/gu_GU.ini
+++ b/lang/gu_GU.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/hi_HI.ini b/lang/hi_HI.ini
index ef02915..7e4494a 100644
--- a/lang/hi_HI.ini
+++ b/lang/hi_HI.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/hr_HR.ini b/lang/hr_HR.ini
index bb796ef..44fe829 100644
--- a/lang/hr_HR.ini
+++ b/lang/hr_HR.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/hu_HU.ini b/lang/hu_HU.ini
index 801b737..4b925d2 100644
--- a/lang/hu_HU.ini
+++ b/lang/hu_HU.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/id_ID.ini b/lang/id_ID.ini
index 2d4b226..d43cc1b 100644
--- a/lang/id_ID.ini
+++ b/lang/id_ID.ini
@@ -330,3 +330,4 @@ add_search_index = "Tambahkan postingan ke Indeks"
clear_search_index = "Hapus Indeks Pencarian"
unindexed_posts = "Postingan berikut belum masuk ke Indeks Pencarian"
indexed_posts = "Postingan sudah terindeks"
+custom_fields = "Custom fields"
diff --git a/lang/it_IT.ini b/lang/it_IT.ini
index e7be747..3a166ec 100644
--- a/lang/it_IT.ini
+++ b/lang/it_IT.ini
@@ -330,3 +330,4 @@ add_search_index = "Aggiungi gli articoli all'Indice di ricerca"
clear_search_index = "Cancella l'Indice di ricerca"
unindexed_posts = "Qui ci sono gli articoli che non sono stati indicizzati"
indexed_posts = "Gli articoli sono stati indicizzati"
+custom_fields = "Custom fields"
diff --git a/lang/ko_KO.ini b/lang/ko_KO.ini
index 682a5e4..72437ec 100644
--- a/lang/ko_KO.ini
+++ b/lang/ko_KO.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/ms_MY.ini b/lang/ms_MY.ini
index efab518..93dbc3d 100644
--- a/lang/ms_MY.ini
+++ b/lang/ms_MY.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/nl_NL.ini b/lang/nl_NL.ini
index c4d05f9..4c03c40 100644
--- a/lang/nl_NL.ini
+++ b/lang/nl_NL.ini
@@ -330,3 +330,4 @@ add_search_index = "Voeg berichten toe aan Zoek Index"
clear_search_index = "Maak de Zoek Index leeg"
unindexed_posts = "Hier zijn de berichten die nog niet geindexeerd zijn"
indexed_posts = "Berichten zijn deindexeerd"
+custom_fields = "Custom fields"
diff --git a/lang/pl_PL.ini b/lang/pl_PL.ini
index 01ad1fe..2c69162 100644
--- a/lang/pl_PL.ini
+++ b/lang/pl_PL.ini
@@ -331,3 +331,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/pt_BR.ini b/lang/pt_BR.ini
index 2fbf4d9..2090c30 100644
--- a/lang/pt_BR.ini
+++ b/lang/pt_BR.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/ru_RU.ini b/lang/ru_RU.ini
index 9238ce7..f07448f 100644
--- a/lang/ru_RU.ini
+++ b/lang/ru_RU.ini
@@ -331,3 +331,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/sv_SE.ini b/lang/sv_SE.ini
index c0a968a..961eda0 100644
--- a/lang/sv_SE.ini
+++ b/lang/sv_SE.ini
@@ -342,3 +342,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/tr_TR.ini b/lang/tr_TR.ini
index b76fd7d..5ef8050 100644
--- a/lang/tr_TR.ini
+++ b/lang/tr_TR.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/uk_UA.ini b/lang/uk_UA.ini
index 91bbac6..3b591bd 100644
--- a/lang/uk_UA.ini
+++ b/lang/uk_UA.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/lang/zh_CN.ini b/lang/zh_CN.ini
index f59fec9..2a59f05 100644
--- a/lang/zh_CN.ini
+++ b/lang/zh_CN.ini
@@ -330,3 +330,4 @@ add_search_index = "添加文章到索引"
clear_search_index = "清除搜索索引"
unindexed_posts = "未被索引的文章"
indexed_posts = "文章已被索引"
+custom_fields = "Custom fields"
diff --git a/lang/zh_TW.ini b/lang/zh_TW.ini
index 12ab938..f31144c 100644
--- a/lang/zh_TW.ini
+++ b/lang/zh_TW.ini
@@ -330,3 +330,4 @@ add_search_index = "Add posts to Search Index"
clear_search_index = "Clear Search Index"
unindexed_posts = "Here are the posts that have not been indexed"
indexed_posts = "Posts has been indexed"
+custom_fields = "Custom fields"
diff --git a/system/admin/admin.php b/system/admin/admin.php
index 75b1079..74a57ca 100644
--- a/system/admin/admin.php
+++ b/system/admin/admin.php
@@ -120,7 +120,7 @@ function remove_accent($str)
}
// Add content
-function add_content($title, $tag, $url, $content, $user, $draft, $category, $type, $description = null, $media = null, $dateTime = null, $autoSave = null, $oldfile = null)
+function add_content($title, $tag, $url, $content, $user, $draft, $category, $type, $description = null, $media = null, $dateTime = null, $autoSave = null, $oldfile = null, $field = null)
{
if (!is_null($autoSave)) {
$draft = 'draft';
@@ -214,7 +214,15 @@ function add_content($title, $tag, $url, $content, $user, $draft, $category, $ty
} else {
$post_media = "";
}
- $post_content = "" . $post_description . $tagmd . $post_media . "\n\n" . $content;
+
+ $customField = "";
+ if (!empty($field)) {
+ foreach ($field as $key => $val) {
+ $customField .= "\n";
+ }
+ }
+
+ $post_content = "" . $post_description . $tagmd . $post_media . $customField . "\n\n" . $content;
if (!empty($post_title) && !empty($post_tag) && !empty($post_url) && !empty($post_content)) {
@@ -312,7 +320,7 @@ function add_content($title, $tag, $url, $content, $user, $draft, $category, $ty
}
// Edit content
-function edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, $type, $destination = null, $description = null, $date = null, $media = null, $autoSave = null)
+function edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, $type, $destination = null, $description = null, $date = null, $media = null, $autoSave = null, $field = null)
{
$tag = explode(',', preg_replace("/\s*,\s*/", ",", rtrim($tag, ',')));
$tag = array_filter(array_unique($tag));
@@ -398,7 +406,15 @@ function edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publ
} else {
$post_media = "";
}
- $post_content = "" . $post_description . $tagmd . $post_media . "\n\n" . $content;
+
+ $customField = "";
+ if (!empty($field)) {
+ foreach ($field as $key => $val) {
+ $customField .= "\n";
+ }
+ }
+
+ $post_content = "" . $post_description . $tagmd . $post_media . $customField . "\n\n" . $content;
$dirBlog = $dir[0] . '/' . $dir[1] . '/' . $dir[2] . '/' . $category . '/' . $type . '/';
$dirDraft = $dir[0] . '/' . $dir[1] . '/' . $dir[2] . '/' . $category . '/draft/';
@@ -578,7 +594,7 @@ function edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publ
}
// Add static page
-function add_page($title, $url, $content, $draft, $description = null, $autoSave = null, $oldfile = null)
+function add_page($title, $url, $content, $draft, $description = null, $autoSave = null, $oldfile = null, $field = null)
{
if (!is_null($autoSave)) {
$draft = 'draft';
@@ -613,7 +629,14 @@ function add_page($title, $url, $content, $draft, $description = null, $autoSave
}
}
- $post_content = '' . $post_description . "\n\n" . $content;
+ $customField = "";
+ if (!empty($field)) {
+ foreach ($field as $key => $val) {
+ $customField .= "\n";
+ }
+ }
+
+ $post_content = '' . $post_description . $customField . "\n\n" . $content;
if (!empty($post_title) && !empty($post_url) && !empty($post_content)) {
@@ -663,7 +686,7 @@ function add_page($title, $url, $content, $draft, $description = null, $autoSave
}
// Add static sub page
-function add_sub_page($title, $url, $content, $static, $draft, $description = null, $autoSave = null, $oldfile = null)
+function add_sub_page($title, $url, $content, $static, $draft, $description = null, $autoSave = null, $oldfile = null, $field = null)
{
if (!is_null($autoSave)) {
$draft = 'draft';
@@ -698,9 +721,16 @@ function add_sub_page($title, $url, $content, $static, $draft, $description = nu
} else {
$post_url = $post_url;
}
- }
+ }
+
+ $customField = "";
+ if (!empty($field)) {
+ foreach ($field as $key => $val) {
+ $customField .= "\n";
+ }
+ }
- $post_content = '' . $post_description . "\n\n" . $content;
+ $post_content = '' . $post_description . $customField . "\n\n" . $content;
if (!empty($post_title) && !empty($post_url) && !empty($post_content)) {
@@ -744,7 +774,7 @@ function add_sub_page($title, $url, $content, $static, $draft, $description = nu
}
// Edit static page and sub page
-function edit_page($title, $url, $content, $oldfile, $revertPage, $publishDraft, $destination = null, $description = null, $static = null, $autoSave = null)
+function edit_page($title, $url, $content, $oldfile, $revertPage, $publishDraft, $destination = null, $description = null, $static = null, $autoSave = null, $field = null)
{
$dir = pathinfo($oldfile, PATHINFO_DIRNAME);
$fn = explode('.', pathinfo($oldfile, PATHINFO_FILENAME));
@@ -770,7 +800,14 @@ function edit_page($title, $url, $content, $oldfile, $revertPage, $publishDraft,
$post_description = "";
}
- $post_content = '' . $post_description . "\n\n" . $content;
+ $customField = "";
+ if (!empty($field)) {
+ foreach ($field as $key => $val) {
+ $customField .= "\n";
+ }
+ }
+
+ $post_content = '' . $post_description . $customField . "\n\n" . $content;
if (!empty($post_title) && !empty($post_url) && !empty($post_content)) {
@@ -980,7 +1017,7 @@ function edit_category($title, $url, $content, $oldfile, $destination = null, $d
}
// Edit user profile
-function edit_profile($title, $content, $user, $description = null, $image = null)
+function edit_profile($title, $content, $user, $description = null, $image = null, $field)
{
$description = safe_html($description);
if ($description !== null) {
@@ -997,8 +1034,16 @@ function edit_profile($title, $content, $user, $description = null, $image = nul
} else {
$avatar = "";
}
+
+ $customField = "";
+ if (!empty($field)) {
+ foreach ($field as $key => $val) {
+ $customField .= "\n";
+ }
+ }
+
$user_title = safe_html($title);
- $user_content = '' . $profile_description . $avatar . "\n\n" . $content;
+ $user_content = '' . $profile_description . $avatar . $customField . "\n\n" . $content;
if (!empty($user_title) && !empty($user_content)) {
@@ -1017,10 +1062,18 @@ function edit_profile($title, $content, $user, $description = null, $image = nul
}
// Edit homepage
-function edit_frontpage($title, $content)
+function edit_frontpage($title, $content, $field = null)
{
+
+ $customField = "";
+ if (!empty($field)) {
+ foreach ($field as $key => $val) {
+ $customField .= "\n";
+ }
+ }
+
$front_title = safe_html($title);
- $front_content = '' . "\n\n" . $content;
+ $front_content = '' . $customField . "\n\n" . $content;
if (!empty($front_title) && !empty($front_content)) {
@@ -1261,7 +1314,7 @@ function find_draft_page($static = null)
$post->body = MarkdownExtra::defaultTransform(remove_html_comments($content));
if ($counter == 'true') {
- $post->views = get_views('page_' . $post->slug, $post->file, $views);
+ $post->views = get_views('page_' . $post->slug, $views);
} else {
$post->views = null;
}
@@ -1340,7 +1393,7 @@ function find_draft_subpage($static = null, $sub_static = null)
$post->body = MarkdownExtra::defaultTransform(remove_html_comments($content));
if ($counter == 'true') {
- $post->views = get_views('subpage_' . $post->parentSlug .'.'. $post->slug, $post->file, $views);
+ $post->views = get_views('subpage_' . $post->parentSlug .'.'. $post->slug, $views);
} else {
$post->views = null;
}
diff --git a/system/admin/views/add-content.html.php b/system/admin/views/add-content.html.php
index 7db1104..b2eece1 100644
--- a/system/admin/views/add-content.html.php
+++ b/system/admin/views/add-content.html.php
@@ -26,6 +26,11 @@ if (file_exists($tagslang)) {
$images = image_gallery(null, 1, 40);
+$fields = array();
+$field_file= 'content/data/field/post.json';
+if (file_exists($field_file)) {
+ $fields = json_decode(file_get_contents($field_file, true));
+}
?>
@@ -188,8 +193,40 @@ $( function() {
*
+
+
+ ">Custom fields
+
+
+
+
-
+
@@ -215,7 +252,7 @@ $( function() {
margin: 2px 2px;
border-top-right-radius: 2px;
width: 190px;
- height: 140px;
+ height: 140px;
vertical-align: top;
background-position: top left;
background-repeat: no-repeat;
@@ -314,6 +351,7 @@ $( function() {
var parent_page = '';
var addEdit = 'add';
var saveInterval = 60000;
+ const field = [name . '", ';}?>];
@@ -377,5 +415,16 @@ $('.img-container').on("click", ".the-img", function(e) {
localStorage.setItem("preview-state", 'open');
}
})
+ if (localStorage.getItem("custom-fields-state") === "open") {
+ document.getElementById("custom-fields").setAttribute("open", "");
+ }
+
+ document.getElementById("custom-fields-click").addEventListener("click", () => {
+ if (document.getElementById("custom-fields").open) {
+ localStorage.setItem("custom-fields-state", 'close');
+ } else {
+ localStorage.setItem("custom-fields-state", 'open');
+ }
+ })
diff --git a/system/admin/views/add-page.html.php b/system/admin/views/add-page.html.php
index 9817646..4bb209b 100644
--- a/system/admin/views/add-page.html.php
+++ b/system/admin/views/add-page.html.php
@@ -1,5 +1,21 @@
+
@@ -45,7 +61,39 @@
-
+
+
+ ">Custom fields
+
+
+
+
+
@@ -78,7 +126,7 @@
margin: 2px 2px;
border-top-right-radius: 2px;
width: 190px;
- height: 140px;
+ height: 140px;
vertical-align: top;
background-position: top left;
background-repeat: no-repeat;
@@ -134,6 +182,7 @@
var parent_page = '';
var addEdit = 'add';
var saveInterval = 60000;
+ const field = [name . '", ';}?>];
\ No newline at end of file
diff --git a/system/admin/views/custom-field-page.html.php b/system/admin/views/custom-field-page.html.php
new file mode 100644
index 0000000..8af5ef9
--- /dev/null
+++ b/system/admin/views/custom-field-page.html.php
@@ -0,0 +1,63 @@
+
+
: Page
+
+
+
+
+
+
+
+
Field Type
+
+ Text
+ Textarea
+ Checkbox
+ Select
+
+
+
+
+
+
Add Field
+
+
+
Options
+
+
Add Option
+
+
+
+
+
+
+
+
+
+JSON Output
+
+
+
+
+
+
\ No newline at end of file
diff --git a/system/admin/views/custom-field-post.html.php b/system/admin/views/custom-field-post.html.php
new file mode 100644
index 0000000..f056cac
--- /dev/null
+++ b/system/admin/views/custom-field-post.html.php
@@ -0,0 +1,63 @@
+
+
: Post
+
+
+
+
+
+
+
+
Field Type
+
+ Text
+ Textarea
+ Checkbox
+ Select
+
+
+
+
+
+
Add Field
+
+
+
Options
+
+
Add Option
+
+
+
+
+
+
+
+
+
+JSON Output
+
+
+
+
+
+
\ No newline at end of file
diff --git a/system/admin/views/custom-field-profile.html.php b/system/admin/views/custom-field-profile.html.php
new file mode 100644
index 0000000..e5007c8
--- /dev/null
+++ b/system/admin/views/custom-field-profile.html.php
@@ -0,0 +1,63 @@
+
+
: Profile
+
+
+
+
+
+
+
+
Field Type
+
+ Text
+ Textarea
+ Checkbox
+ Select
+
+
+
+
+
+
Add Field
+
+
+
Options
+
+
Add Option
+
+
+
+
+
+
+
+
+
+JSON Output
+
+
+
+
+
+
\ No newline at end of file
diff --git a/system/admin/views/custom-field-subpage.html.php b/system/admin/views/custom-field-subpage.html.php
new file mode 100644
index 0000000..bfdebac
--- /dev/null
+++ b/system/admin/views/custom-field-subpage.html.php
@@ -0,0 +1,63 @@
+
+
: Subpage
+
+
+
+
+
+
+
+
Field Type
+
+ Text
+ Textarea
+ Checkbox
+ Select
+
+
+
+
+
+
Add Field
+
+
+
Options
+
+
Add Option
+
+
+
+
+
+
+
+
+
+JSON Output
+
+
+
+
+
+
\ No newline at end of file
diff --git a/system/admin/views/custom-field.html.php b/system/admin/views/custom-field.html.php
new file mode 100644
index 0000000..88cd3ca
--- /dev/null
+++ b/system/admin/views/custom-field.html.php
@@ -0,0 +1,36 @@
+
+
+
+
Custom fields enable users to add extra, specific data fields to their content, allowing for more detailed and flexible content management.
+
+
Use get_field() function in your template. Example:
+
Post, Page, Subpage: <?php echo get_field('field_name', $p->raw);?>
+Profile: <?php echo get_field('field_name', $author->raw);?>
+
+
+
+
+
+ Type
+
+
+
+
+
+ Post
+
+
+
+ Page
+
+
+
+ Subpage
+
+
+
+ Profile
+
+
+
+
\ No newline at end of file
diff --git a/system/admin/views/edit-content.html.php b/system/admin/views/edit-content.html.php
index 8e77bb5..7dbfd64 100644
--- a/system/admin/views/edit-content.html.php
+++ b/system/admin/views/edit-content.html.php
@@ -71,6 +71,12 @@ if (file_exists($tagslang)) {
$images = image_gallery(null, 1, 40);
+$fields = array();
+$field_file = 'content/data/field/post.json';
+if (file_exists($field_file)) {
+ $fields = json_decode(file_get_contents($field_file, true));
+}
+
?>
@@ -233,13 +239,48 @@ $( function() {
*
-
+
+
+
+
+
+ ">Custom fields
+
+
+
+
+
-
+
@@ -265,7 +306,7 @@ $( function() {
margin: 2px 2px;
border-top-right-radius: 2px;
width: 190px;
- height: 140px;
+ height: 140px;
vertical-align: top;
background-position: top left;
background-repeat: no-repeat;
@@ -363,6 +404,7 @@ $( function() {
var parent_page = '';
var addEdit = 'edit';
var saveInterval = 60000;
+ const field = [name . '", ';}?>];
@@ -428,4 +470,15 @@ $('.img-container').on("click", ".the-img", function(e) {
localStorage.setItem("preview-state", 'open');
}
})
+ if (localStorage.getItem("custom-fields-state") === "open") {
+ document.getElementById("custom-fields").setAttribute("open", "");
+ }
+
+ document.getElementById("custom-fields-click").addEventListener("click", () => {
+ if (document.getElementById("custom-fields").open) {
+ localStorage.setItem("custom-fields-state", 'close');
+ } else {
+ localStorage.setItem("custom-fields-state", 'open');
+ }
+ })
diff --git a/system/admin/views/edit-page.html.php b/system/admin/views/edit-page.html.php
index 2a01396..14eff8d 100644
--- a/system/admin/views/edit-page.html.php
+++ b/system/admin/views/edit-page.html.php
@@ -9,6 +9,7 @@ if ($type == 'is_frontpage') {
$oldtitle = get_content_tag('t', $content, 'Welcome');
$oldcontent = remove_html_comments($content);
} else {
+ $content = 'Welcome to our website.';
$oldtitle = 'Welcome';
$oldcontent = 'Welcome to our website.';
}
@@ -27,6 +28,7 @@ if ($type == 'is_frontpage') {
$oldcontent = remove_html_comments($content);
$oldimage = get_content_tag('image', $content);
} else {
+ $content = i18n('Author_Description');
$oldtitle = $user;
$olddescription = i18n('Author_Description');
$oldcontent = i18n('Author_Description');
@@ -34,12 +36,20 @@ if ($type == 'is_frontpage') {
}
} elseif ($type == 'is_category') {
- $content = $p->body;
- $oldtitle = $p->title;
- $olddescription = $p->description;
- $oldcontent = $p->body;
- $oldmd = $p->slug;
$url = 'content/data/category/'. $p->slug . '.md';
+ if (file_exists($url)) {
+ $content = file_get_contents($url);
+ $oldtitle = get_content_tag('t', $content, $p->slug);
+ $olddescription = get_content_tag('d', $content, remove_html_comments($content));
+ $oldcontent = remove_html_comments($content);
+ $oldmd = $p->slug;
+ } else {
+ $content = $p->body;
+ $oldtitle = $p->title;
+ $olddescription = $p->description;
+ $oldcontent = $p->body;
+ $oldmd = $p->slug;
+ }
} else {
if (isset($p->file)) {
@@ -82,6 +92,24 @@ if ($type == 'is_frontpage') {
$images = image_gallery(null, 1, 40);
+$fields = array();
+if ($type == 'is_page' || $type == 'is_frontpage') {
+ $field_file = 'content/data/field/page.json';
+ if (file_exists($field_file)) {
+ $fields = json_decode(file_get_contents($field_file, true));
+ }
+} elseif ($type == 'is_subpage') {
+ $field_file = 'content/data/field/subpage.json';
+ if (file_exists($field_file)) {
+ $fields = json_decode(file_get_contents($field_file, true));
+ }
+} elseif ($type == 'is_profile') {
+ $field_file = 'content/data/field/profile.json';
+ if (file_exists($field_file)) {
+ $fields = json_decode(file_get_contents($field_file, true));
+ }
+}
+
?>
@@ -132,7 +160,6 @@ $images = image_gallery(null, 1, 40);
-
@@ -146,6 +173,38 @@ $images = image_gallery(null, 1, 40);
+
+
+ ">Custom fields
+
+
+
+
@@ -188,7 +247,7 @@ $images = image_gallery(null, 1, 40);
margin: 2px 2px;
border-top-right-radius: 2px;
width: 190px;
- height: 140px;
+ height: 140px;
vertical-align: top;
background-position: top left;
background-repeat: no-repeat;
@@ -277,7 +336,7 @@ $images = image_gallery(null, 1, 40);
-
+
@@ -355,4 +415,15 @@ $('.img-container').on("click", ".the-img", function(e) {
localStorage.setItem("preview-state", 'open');
}
})
+ if (localStorage.getItem("custom-fields-state") === "open") {
+ document.getElementById("custom-fields").setAttribute("open", "");
+ }
+
+ document.getElementById("custom-fields-click").addEventListener("click", () => {
+ if (document.getElementById("custom-fields").open) {
+ localStorage.setItem("custom-fields-state", 'close');
+ } else {
+ localStorage.setItem("custom-fields-state", 'open');
+ }
+ })
diff --git a/system/admin/views/layout.html.php b/system/admin/views/layout.html.php
index ab5ea9a..e29e55e 100644
--- a/system/admin/views/layout.html.php
+++ b/system/admin/views/layout.html.php
@@ -177,6 +177,13 @@ if (isset($author[0])) {
+
+
+
+
+
+
+
diff --git a/system/htmly.php b/system/htmly.php
index 2e8ac5c..449c721 100644
--- a/system/htmly.php
+++ b/system/htmly.php
@@ -406,6 +406,23 @@ post('/edit/profile', function () {
$login = site_url() . 'login';
header("location: $login");
}
+
+ $field = array();
+ $aField = array();
+ $field_file = 'content/data/field/profile.json';
+ if (file_exists($field_file)) {
+ $aField = json_decode(file_get_contents($field_file, true));
+ }
+ if(!empty($aField)) {
+ foreach ($aField as $af) {
+ if ($af->type == 'checkbox' && isset($_REQUEST[$af->name])) {
+ $field[$af->name] = isset($_REQUEST[$af->name]) ? "checked" : 0;
+ } else {
+ $field[$af->name] = from($_REQUEST, $af->name);
+ }
+ }
+ }
+
$proper = is_csrf_proper(from($_REQUEST, 'csrf_token'));
$user = $_SESSION[site_url()]['user'];
$title = from($_REQUEST, 'title');
@@ -413,7 +430,7 @@ post('/edit/profile', function () {
$image = from($_REQUEST, 'image');
$content = from($_REQUEST, 'content');
if ($proper && !empty($title) && !empty($content)) {
- edit_profile($title, $content, $user, $description, $image);
+ edit_profile($title, $content, $user, $description, $image, $field);
} else {
$message['error'] = '';
if (empty($title)) {
@@ -621,6 +638,23 @@ post('/edit/frontpage', function () {
$login = site_url() . 'login';
header("location: $login");
}
+
+ $field = array();
+ $aField = array();
+ $field_file = 'content/data/field/page.json';
+ if (file_exists($field_file)) {
+ $aField = json_decode(file_get_contents($field_file, true));
+ }
+ if(!empty($aField)) {
+ foreach ($aField as $af) {
+ if ($af->type == 'checkbox' && isset($_REQUEST[$af->name])) {
+ $field[$af->name] = isset($_REQUEST[$af->name]) ? "checked" : 0;
+ } else {
+ $field[$af->name] = from($_REQUEST, $af->name);
+ }
+ }
+ }
+
$proper = is_csrf_proper(from($_REQUEST, 'csrf_token'));
$user = $_SESSION[site_url()]['user'];
$role = user('role', $user);
@@ -628,7 +662,7 @@ post('/edit/frontpage', function () {
$content = from($_REQUEST, 'content');
if ($role === 'editor' || $role === 'admin') {
if ($proper && !empty($title) && !empty($content)) {
- edit_frontpage($title, $content);
+ edit_frontpage($title, $content, $field);
} else {
$message['error'] = '';
if (empty($title)) {
@@ -712,6 +746,23 @@ post('/add/content', function () {
$login = site_url() . 'login';
header("location: $login");
}
+
+ $field = array();
+ $aField = array();
+ $field_file = 'content/data/field/post.json';
+ if (file_exists($field_file)) {
+ $aField = json_decode(file_get_contents($field_file, true));
+ }
+ if(!empty($aField)) {
+ foreach ($aField as $af) {
+ if ($af->type == 'checkbox' && isset($_REQUEST[$af->name])) {
+ $field[$af->name] = isset($_REQUEST[$af->name]) ? "checked" : 0;
+ } else {
+ $field[$af->name] = from($_REQUEST, $af->name);
+ }
+ }
+ }
+
$is_image = from($_REQUEST, 'is_image');
$is_audio = from($_REQUEST, 'is_audio');
$is_video = from($_REQUEST, 'is_video');
@@ -765,17 +816,17 @@ post('/add/content', function () {
}
if ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($is_post)) {
- add_content($title, $tag, $url, $content, $user, $draft, $category, 'post', $description, null, $dateTime);
+ add_content($title, $tag, $url, $content, $user, $draft, $category, 'post', $description, null, $dateTime, null, null, $field);
} elseif ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($image)) {
- add_content($title, $tag, $url, $content, $user, $draft, $category, 'image', $description, $image, $dateTime);
+ add_content($title, $tag, $url, $content, $user, $draft, $category, 'image', $description, $image, $dateTime, null, null, $field);
} elseif ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($video)) {
- add_content($title, $tag, $url, $content, $user, $draft, $category, 'video', $description, $video, $dateTime);
+ add_content($title, $tag, $url, $content, $user, $draft, $category, 'video', $description, $video, $dateTime, null, null, $field);
} elseif ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($audio)) {
- add_content($title, $tag, $url, $content, $user, $draft, $category, 'audio', $description, $audio, $dateTime);
+ add_content($title, $tag, $url, $content, $user, $draft, $category, 'audio', $description, $audio, $dateTime, null, null, $field);
} elseif ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($quote)) {
- add_content($title, $tag, $url, $content, $user, $draft, $category, 'quote', $description, $quote, $dateTime);
+ add_content($title, $tag, $url, $content, $user, $draft, $category, 'quote', $description, $quote, $dateTime, null, null, $field);
} elseif ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($link)) {
- add_content($title, $tag, $url, $content, $user, $draft, $category, 'link', $description, $link, $dateTime);
+ add_content($title, $tag, $url, $content, $user, $draft, $category, 'link', $description, $link, $dateTime, null, null, $field);
} else {
$message['error'] = '';
if (empty($title)) {
@@ -882,6 +933,23 @@ post('/add/page', function () {
$login = site_url() . 'login';
header("location: $login");
}
+
+ $field = array();
+ $aField = array();
+ $field_file = 'content/data/field/page.json';
+ if (file_exists($field_file)) {
+ $aField = json_decode(file_get_contents($field_file, true));
+ }
+ if(!empty($aField)) {
+ foreach ($aField as $af) {
+ if ($af->type == 'checkbox' && isset($_REQUEST[$af->name])) {
+ $field[$af->name] = isset($_REQUEST[$af->name]) ? "checked" : 0;
+ } else {
+ $field[$af->name] = from($_REQUEST, $af->name);
+ }
+ }
+ }
+
$proper = is_csrf_proper(from($_REQUEST, 'csrf_token'));
$title = from($_REQUEST, 'title');
$url = from($_REQUEST, 'url');
@@ -895,7 +963,7 @@ post('/add/page', function () {
}
if ($role === 'editor' || $role === 'admin') {
if ($proper && !empty($title) && !empty($content) && login()) {
- add_page($title, $url, $content, $draft, $description);
+ add_page($title, $url, $content, $draft, $description, null, null, $field);
} else {
$message['error'] = '';
if (empty($title)) {
@@ -932,7 +1000,8 @@ post('/add/page', function () {
// Autosave
post('/admin/autosave', function () {
- if (login()) {
+ if (login()) {
+
$title = $_REQUEST['title'];
$url = $_REQUEST['url'];
$content = $_REQUEST['content'];
@@ -944,6 +1013,34 @@ post('/admin/autosave', function () {
$addEdit = $_REQUEST['addEdit'];
$user = $_SESSION[site_url()]['user'];
$role = user('role', $user);
+
+ $field = array();
+ $aField = array();
+ if ($posttype == 'is_post') {
+ $field_file = 'content/data/field/post.json';
+ if (file_exists($field_file)) {
+ $aField = json_decode(file_get_contents($field_file, true));
+ }
+ } elseif ($posttype == 'is_page') {
+ $field_file = 'content/data/field/page.json';
+ if (file_exists($field_file)) {
+ $aField = json_decode(file_get_contents($field_file, true));
+ }
+ } elseif ($posttype == 'is_subpage') {
+ $field_file = 'content/data/field/subpage.json';
+ if (file_exists($field_file)) {
+ $aField = json_decode(file_get_contents($field_file, true));
+ }
+ }
+ if(!empty($aField)) {
+ foreach ($aField as $af) {
+ if ($af->type == 'checkbox' && isset($_REQUEST[$af->name])) {
+ $field[$af->name] = !empty($_REQUEST[$af->name]) ? "checked" : '';
+ } else {
+ $field[$af->name] = from($_REQUEST, $af->name);
+ }
+ }
+ }
if (empty($url)) {
$url = $title;
@@ -960,18 +1057,18 @@ post('/admin/autosave', function () {
if ($posttype == 'is_page') {
if ($role === 'editor' || $role === 'admin') {
if ($addEdit == 'add') {
- $response = add_page($title, $url, $content, $draft, $description, $autoSave, $oldfile);
+ $response = add_page($title, $url, $content, $draft, $description, $autoSave, $oldfile, $field);
} else {
- $response = edit_page($title, $url, $content, $oldfile, $revertPage, $publishDraft, $destination, $description, null, $autoSave);
+ $response = edit_page($title, $url, $content, $oldfile, $revertPage, $publishDraft, $destination, $description, null, $autoSave, $field);
}
}
} elseif ($posttype == 'is_subpage') {
if ($role === 'editor' || $role === 'admin') {
$static = $_REQUEST['parent_page'];
if ($addEdit == 'add') {
- $response = add_sub_page($title, $url, $content, $static, $draft, $description, $autoSave, $oldfile);
+ $response = add_sub_page($title, $url, $content, $static, $draft, $description, $autoSave, $oldfile, $field);
} else {
- $response = edit_page($title, $url, $content, $oldfile, $revertPage, $publishDraft, $destination, $description, $static, $autoSave);
+ $response = edit_page($title, $url, $content, $oldfile, $revertPage, $publishDraft, $destination, $description, $static, $autoSave, $field);
}
}
} else {
@@ -1001,11 +1098,11 @@ post('/admin/autosave', function () {
if ($type == 'post') {
if (!empty($title) && !empty($tag) && !empty($content)) {
if ($addEdit == 'add') {
- $response = add_content($title, $tag, $url, $content, $user, $draft, $category, $type, $description, $media, $dateTime, $autoSave, $oldfile);
+ $response = add_content($title, $tag, $url, $content, $user, $draft, $category, $type, $description, $media, $dateTime, $autoSave, $oldfile, $field);
} else {
$arr = explode('/', $oldfile);
if ($user === $arr[1] || $role === 'editor' || $role === 'admin') {
- $response = edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, $type, $destination, $description, $dateTime, $media, $autoSave);
+ $response = edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, $type, $destination, $description, $dateTime, $media, $autoSave, $field);
}
}
} else {
@@ -1014,11 +1111,11 @@ post('/admin/autosave', function () {
} else {
if (!empty($title) && !empty($tag) && !empty($content) && !empty($media)) {
if ($addEdit == 'add') {
- $response = add_content($title, $tag, $url, $content, $user, $draft, $category, $type, $description, $media, $dateTime, $autoSave, $oldfile);
+ $response = add_content($title, $tag, $url, $content, $user, $draft, $category, $type, $description, $media, $dateTime, $autoSave, $oldfile, $field);
} else {
$arr = explode('/', $oldfile);
if ($user === $arr[1] || $role === 'editor' || $role === 'admin') {
- $response = edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, $type, $destination, $description, $dateTime, $media, $autoSave);
+ $response = edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, $type, $destination, $description, $dateTime, $media, $autoSave, $field);
}
}
} else {
@@ -2969,6 +3066,183 @@ get('/admin/categories/:category', function ($category) {
}
});
+// Show admin/field
+get('/admin/field', function () {
+ if (login()) {
+ config('views.root', 'system/admin/views');
+ render('custom-field', array(
+ 'title' => generate_title('is_default', i18n('custom_fields')),
+ 'description' => safe_html(strip_tags(blog_description())),
+ 'canonical' => site_url(),
+ 'metatags' => generate_meta(null, null),
+ 'type' => 'is_admin-content',
+ 'is_admin' => true,
+ 'bodyclass' => 'admin-content',
+ 'breadcrumb' => '' . config('breadcrumb.home') . ' » ' . i18n('custom_fields')
+ ));
+ } else {
+ $login = site_url() . 'login';
+ header("location: $login");
+ }
+});
+
+// Show admin/field/post
+get('/admin/field/post', function () {
+ if (login()) {
+ config('views.root', 'system/admin/views');
+ render('custom-field-post', array(
+ 'title' => generate_title('is_default', i18n('post')),
+ 'description' => safe_html(strip_tags(blog_description())),
+ 'canonical' => site_url(),
+ 'metatags' => generate_meta(null, null),
+ 'type' => 'is_admin-content',
+ 'is_admin' => true,
+ 'bodyclass' => 'admin-content',
+ 'breadcrumb' => '' . config('breadcrumb.home') . ' » ' . i18n('post')
+ ));
+ } else {
+ $login = site_url() . 'login';
+ header("location: $login");
+ }
+});
+
+post('/admin/field/post', function () {
+
+ if (login()) {
+ $user = $_SESSION[site_url()]['user'];
+ $role = user('role', $user);
+
+ if ($role === 'editor' || $role === 'admin') {
+ $dir = 'content/data/field/';
+ if (!is_dir($dir)) {
+ mkdir($dir, 0775, true);
+ }
+ $json = $_REQUEST['json'];
+ save_json_pretty('content/data/field/post.json', json_decode($json));
+ echo json_encode(array(
+ 'message' => 'Post fields saved successfully!',
+ ));
+ }
+ }
+});
+
+// Show admin/field/page
+get('/admin/field/page', function () {
+ if (login()) {
+ config('views.root', 'system/admin/views');
+ render('custom-field-page', array(
+ 'title' => generate_title('is_default', i18n('page')),
+ 'description' => safe_html(strip_tags(blog_description())),
+ 'canonical' => site_url(),
+ 'metatags' => generate_meta(null, null),
+ 'type' => 'is_admin-content',
+ 'is_admin' => true,
+ 'bodyclass' => 'admin-content',
+ 'breadcrumb' => '' . config('breadcrumb.home') . ' » ' . i18n('page')
+ ));
+ } else {
+ $login = site_url() . 'login';
+ header("location: $login");
+ }
+});
+
+post('/admin/field/page', function () {
+
+ if (login()) {
+ $user = $_SESSION[site_url()]['user'];
+ $role = user('role', $user);
+ if ($role === 'editor' || $role === 'admin') {
+ $dir = 'content/data/field/';
+ if (!is_dir($dir)) {
+ mkdir($dir, 0775, true);
+ }
+ $json = $_REQUEST['json'];
+ save_json_pretty('content/data/field/page.json', json_decode($json));
+ echo json_encode(array(
+ 'message' => 'Page fields saved successfully!',
+ ));
+ }
+ }
+});
+
+// Show admin/field/subpage
+get('/admin/field/subpage', function () {
+ if (login()) {
+ config('views.root', 'system/admin/views');
+ render('custom-field-subpage', array(
+ 'title' => generate_title('is_default', i18n('subpage')),
+ 'description' => safe_html(strip_tags(blog_description())),
+ 'canonical' => site_url(),
+ 'metatags' => generate_meta(null, null),
+ 'type' => 'is_admin-content',
+ 'is_admin' => true,
+ 'bodyclass' => 'admin-content',
+ 'breadcrumb' => '' . config('breadcrumb.home') . ' » ' . i18n('subpage')
+ ));
+ } else {
+ $login = site_url() . 'login';
+ header("location: $login");
+ }
+});
+
+post('/admin/field/subpage', function () {
+
+ if (login()) {
+ $user = $_SESSION[site_url()]['user'];
+ $role = user('role', $user);
+ if ($role === 'editor' || $role === 'admin') {
+ $dir = 'content/data/field/';
+ if (!is_dir($dir)) {
+ mkdir($dir, 0775, true);
+ }
+ $json = $_REQUEST['json'];
+ save_json_pretty('content/data/field/subpage.json', json_decode($json));
+ echo json_encode(array(
+ 'message' => 'Subpage fields saved successfully!',
+ ));
+ }
+ }
+});
+
+// Show admin/field/profile
+get('/admin/field/profile', function () {
+ if (login()) {
+ config('views.root', 'system/admin/views');
+ render('custom-field-profile', array(
+ 'title' => generate_title('is_default', i18n('profile')),
+ 'description' => safe_html(strip_tags(blog_description())),
+ 'canonical' => site_url(),
+ 'metatags' => generate_meta(null, null),
+ 'type' => 'is_admin-content',
+ 'is_admin' => true,
+ 'bodyclass' => 'admin-content',
+ 'breadcrumb' => '' . config('breadcrumb.home') . ' » ' . i18n('profile')
+ ));
+ } else {
+ $login = site_url() . 'login';
+ header("location: $login");
+ }
+});
+
+post('/admin/field/profile', function () {
+
+ if (login()) {
+ $user = $_SESSION[site_url()]['user'];
+ $role = user('role', $user);
+ if ($role === 'editor' || $role === 'admin') {
+ $dir = 'content/data/field/';
+ if (!is_dir($dir)) {
+ mkdir($dir, 0775, true);
+ }
+ $json = $_REQUEST['json'];
+ save_json_pretty('content/data/field/profile.json', json_decode($json));
+ echo json_encode(array(
+ 'message' => 'Profile fields saved successfully!',
+ ));
+ }
+ }
+});
+
// Show the category page
get('/category/:category', function ($category) {
@@ -3846,6 +4120,23 @@ post('/'. permalink_type() .'/:name/edit', function () {
$login = site_url() . 'login';
header("location: $login");
}
+
+ $field = array();
+ $aField = array();
+ $field_file = 'content/data/field/post.json';
+ if (file_exists($field_file)) {
+ $aField = json_decode(file_get_contents($field_file, true));
+ }
+ if(!empty($aField)) {
+ foreach ($aField as $af) {
+ if ($af->type == 'checkbox' && isset($_REQUEST[$af->name])) {
+ $field[$af->name] = isset($_REQUEST[$af->name]) ? "checked" : 0;
+ } else {
+ $field[$af->name] = from($_REQUEST, $af->name);
+ }
+ }
+ }
+
$proper = is_csrf_proper(from($_REQUEST, 'csrf_token'));
$title = from($_REQUEST, 'title');
$is_post = from($_REQUEST, 'is_post');
@@ -3899,27 +4190,27 @@ post('/'. permalink_type() .'/:name/edit', function () {
if ($user === $arr[1] || $role === 'editor' || $role === 'admin') {
if ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($image)) {
- edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'image', $destination, $description, $dateTime, $image);
+ edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'image', $destination, $description, $dateTime, $image,null, $field);
} else if ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($video)) {
- edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'video', $destination, $description, $dateTime, $video);
+ edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'video', $destination, $description, $dateTime, $video,null, $field);
} else if ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($link)) {
- edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'link', $destination, $description, $dateTime, $link);
+ edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'link', $destination, $description, $dateTime, $link,null, $field);
} else if ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($quote)) {
- edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'quote', $destination, $description, $dateTime, $quote);
+ edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'quote', $destination, $description, $dateTime, $quote,null, $field);
} else if ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($audio)) {
- edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'audio', $destination, $description, $dateTime, $audio);
+ edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'audio', $destination, $description, $dateTime, $audio,null, $field);
} else if ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($is_post)) {
- edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'post', $destination, $description, $dateTime, null);
+ edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'post', $destination, $description, $dateTime, null,null, $field);
} else {
$message['error'] = '';
@@ -4327,6 +4618,23 @@ post('/:static/add', function ($static) {
$login = site_url() . 'login';
header("location: $login");
}
+
+ $field = array();
+ $aField = array();
+ $field_file= 'content/data/field/subpage.json';
+ if (file_exists($field_file)) {
+ $aField = json_decode(file_get_contents($field_file, true));
+ }
+ if(!empty($aField)) {
+ foreach ($aField as $af) {
+ if ($af->type == 'checkbox' && isset($_REQUEST[$af->name])) {
+ $field[$af->name] = isset($_REQUEST[$af->name]) ? "checked" : 0;
+ } else {
+ $field[$af->name] = from($_REQUEST, $af->name);
+ }
+ }
+ }
+
$proper = is_csrf_proper(from($_REQUEST, 'csrf_token'));
$title = from($_REQUEST, 'title');
$url = from($_REQUEST, 'url');
@@ -4340,7 +4648,7 @@ post('/:static/add', function ($static) {
}
if ($role === 'editor' || $role === 'admin') {
if ($proper && !empty($title) && !empty($content)) {
- add_sub_page($title, $url, $content, $static, $draft, $description);
+ add_sub_page($title, $url, $content, $static, $draft, $description, null, null, $field);
} else {
$message['error'] = '';
if (empty($title)) {
@@ -4432,6 +4740,23 @@ post('/:static/edit', function () {
$login = site_url() . 'login';
header("location: $login");
}
+
+ $field = array();
+ $aField = array();
+ $field_file = 'content/data/field/page.json';
+ if (file_exists($field_file)) {
+ $aField = json_decode(file_get_contents($field_file, true));
+ }
+ if(!empty($aField)) {
+ foreach ($aField as $af) {
+ if ($af->type == 'checkbox' && isset($_REQUEST[$af->name])) {
+ $field[$af->name] = isset($_REQUEST[$af->name]) ? "checked" : 0;
+ } else {
+ $field[$af->name] = from($_REQUEST, $af->name);
+ }
+ }
+ }
+
$title = from($_REQUEST, 'title');
$url = from($_REQUEST, 'url');
$content = from($_REQUEST, 'content');
@@ -4447,7 +4772,7 @@ post('/:static/edit', function () {
}
if ($role === 'editor' || $role === 'admin') {
if ($proper && !empty($title) && !empty($content)) {
- edit_page($title, $url, $content, $oldfile, $revertPage, $publishDraft, $destination, $description);
+ edit_page($title, $url, $content, $oldfile, $revertPage, $publishDraft, $destination, $description, null, null, $field);
} else {
$message['error'] = '';
if (empty($title)) {
@@ -4462,7 +4787,7 @@ post('/:static/edit', function () {
config('views.root', 'system/admin/views');
render('edit-page', array(
- 'title' => generate_title('is_default', i18n('Edit') . ': ' . $post->title),
+ 'title' => generate_title('is_default', i18n('Edit') . ': ' . $title),
'description' => safe_html(strip_tags(blog_description())),
'canonical' => site_url(),
'metatags' => generate_meta(null, null),
@@ -4703,6 +5028,23 @@ post('/:static/:sub/edit', function ($static, $sub) {
$login = site_url() . 'login';
header("location: $login");
}
+
+ $field = array();
+ $aField = array();
+ $field_file = 'content/data/field/subpage.json';
+ if (file_exists($field_file)) {
+ $aField = json_decode(file_get_contents($field_file, true));
+ }
+ if(!empty($aField)) {
+ foreach ($aField as $af) {
+ if ($af->type == 'checkbox' && isset($_REQUEST[$af->name])) {
+ $field[$af->name] = isset($_REQUEST[$af->name]) ? "checked" : 0;
+ } else {
+ $field[$af->name] = from($_REQUEST, $af->name);
+ }
+ }
+ }
+
$title = from($_REQUEST, 'title');
$url = from($_REQUEST, 'url');
$content = from($_REQUEST, 'content');
@@ -4721,7 +5063,7 @@ post('/:static/:sub/edit', function ($static, $sub) {
}
if ($role === 'editor' || $role === 'admin') {
if ($proper && !empty($title) && !empty($content)) {
- edit_page($title, $url, $content, $oldfile, $revertPage, $publishDraft, $destination, $description, $static);
+ edit_page($title, $url, $content, $oldfile, $revertPage, $publishDraft, $destination, $description, $static, null, $field);
} else {
$message['error'] = '';
if (empty($title)) {
@@ -4736,7 +5078,7 @@ post('/:static/:sub/edit', function ($static, $sub) {
config('views.root', 'system/admin/views');
render('edit-page', array(
- 'title' => generate_title('is_default', i18n('Edit') . ': ' . $page->title),
+ 'title' => generate_title('is_default', i18n('Edit') . ': ' . $title),
'description' => safe_html(strip_tags(blog_description())),
'canonical' => site_url(),
'metatags' => generate_meta(null, null),
@@ -5024,6 +5366,23 @@ post('/:year/:month/:name/edit', function () {
$login = site_url() . 'login';
header("location: $login");
}
+
+ $field = array();
+ $aField = array();
+ $field_file = 'content/data/field/post.json';
+ if (file_exists($field_file)) {
+ $aField = json_decode(file_get_contents($field_file, true));
+ }
+ if(!empty($aField)) {
+ foreach ($aField as $af) {
+ if ($af->type == 'checkbox' && isset($_REQUEST[$af->name])) {
+ $field[$af->name] = isset($_REQUEST[$af->name]) ? "checked" : 0;
+ } else {
+ $field[$af->name] = from($_REQUEST, $af->name);
+ }
+ }
+ }
+
$proper = is_csrf_proper(from($_REQUEST, 'csrf_token'));
$title = from($_REQUEST, 'title');
$is_post = from($_REQUEST, 'is_post');
@@ -5078,27 +5437,27 @@ post('/:year/:month/:name/edit', function () {
if ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($image)) {
- edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'image', $destination, $description, $dateTime, $image);
+ edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'image', $destination, $description, $dateTime, $image, null, $field);
} else if ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($video)) {
- edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'video', $destination, $description, $dateTime, $video);
+ edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'video', $destination, $description, $dateTime, $video,null, $field);
} else if ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($link)) {
- edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'link', $destination, $description, $dateTime, $link);
+ edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'link', $destination, $description, $dateTime, $link,null, $field);
} else if ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($quote)) {
- edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'quote', $destination, $description, $dateTime, $quote);
+ edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'quote', $destination, $description, $dateTime, $quote,null, $field);
} else if ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($audio)) {
- edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'audio', $destination, $description, $dateTime, $audio);
+ edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'audio', $destination, $description, $dateTime, $audio,null, $field);
} else if ($proper && !empty($title) && !empty($tag) && !empty($content) && !empty($is_post)) {
- edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'post', $destination, $description, $dateTime, null);
+ edit_content($title, $tag, $url, $content, $oldfile, $revertPost, $publishDraft, $category, 'post', $destination, $description, $dateTime, null,null, $field);
} else {
$message['error'] = '';
diff --git a/system/resources/js/form.builder.js b/system/resources/js/form.builder.js
new file mode 100644
index 0000000..a40e0fa
--- /dev/null
+++ b/system/resources/js/form.builder.js
@@ -0,0 +1,241 @@
+/*!
+ * Simple Form Builder for HTMLy - @author danpros
+ *
+ * const fields = [];
+ */
+let editingIndex = -1; // Track index of the field being edited (-1 means not editing)
+
+// Elements
+const typeEl = document.getElementById('type');
+const nameEl = document.getElementById('name');
+const labelEl = document.getElementById('label');
+const valueEl = document.getElementById('value');
+const optionsContainerEl = document.getElementById('options-container');
+const optionListEl = document.getElementById('option-list');
+const addOptionBtn = document.getElementById('add-option');
+const addFieldBtn = document.getElementById('add-field');
+const formPreviewEl = document.getElementById('form-preview');
+const jsonOutputEl = document.getElementById('json-output');
+
+// Show or hide the options container and reset fields
+typeEl.addEventListener('change', () => {
+ nameEl.value = '';
+ labelEl.value = '';
+ valueEl.value = '';
+ optionsContainerEl.style.display = typeEl.value === 'select' ? 'block' : 'none';
+ optionListEl.innerHTML = '';
+ addFieldBtn.textContent = "Add Field";
+});
+
+// Add new option for select field
+addOptionBtn.addEventListener('click', () => {
+ const optionDiv = document.createElement('div');
+ optionDiv.classList.add('option-item');
+
+ const labelInput = document.createElement('input');
+ labelInput.type = 'text';
+ labelInput.placeholder = 'Option Label';
+ labelInput.classList.add('option-label');
+
+ const valueInput = document.createElement('input');
+ valueInput.type = 'text';
+ valueInput.placeholder = 'Option Value';
+ valueInput.classList.add('option-value');
+
+ const removeBtn = document.createElement('button');
+ removeBtn.textContent = 'Remove';
+ removeBtn.addEventListener('click', () => optionDiv.remove());
+ removeBtn.setAttribute('class', 'btn btn-danger');
+
+ optionDiv.appendChild(labelInput);
+ optionDiv.appendChild(valueInput);
+ optionDiv.appendChild(removeBtn);
+ optionListEl.appendChild(optionDiv);
+});
+
+// Add field button logic (works for both adding and updating fields)
+addFieldBtn.addEventListener('click', () => {
+ let field = {
+ type: typeEl.value,
+ name: nameEl.value.trim().replace(/\s+/g, ''), // Remove spaces
+ label: labelEl.value.trim(),
+ value: valueEl.value.trim()
+ };
+
+ if (field.type === 'select') {
+ const options = Array.from(document.querySelectorAll('.option-item')).map(item => {
+ const label = item.querySelector('.option-label').value.trim();
+ const value = item.querySelector('.option-value').value.trim();
+ return { label, value };
+ });
+
+ if (options.some(opt => !opt.label || !opt.value)) {
+ alert("All options for a select field must have both label and value!");
+ return;
+ }
+ field.options = options;
+ }
+
+ if (!field.name || !field.label || !field.type) {
+ alert("Please fill in all required fields: Type, Name, and Label.");
+ return;
+ }
+
+ if (editingIndex === -1) {
+ const existingNames = fields.map(f => f.name);
+ if (existingNames.includes(field.name)) {
+ const timestamp = Date.now();
+ field.name = `${field.name}_${timestamp}`;
+ }
+ fields.push(field);
+ } else {
+ fields[editingIndex] = field;
+ editingIndex = -1;
+ addFieldBtn.textContent = "Add Field";
+ }
+
+ updatePreviewAndOutput();
+});
+
+// Delete field logic
+function deleteField(index) {
+ if (confirm("Are you sure you want to delete this field?")) {
+ fields.splice(index, 1);
+ updatePreviewAndOutput();
+ }
+}
+
+// Edit field logic
+function editField(index) {
+ const field = fields[index];
+
+ typeEl.value = field.type;
+ nameEl.value = field.name.replace(/\s+/g, ''); // Remove spaces
+ labelEl.value = field.label;
+ valueEl.value = field.value || '';
+
+ if (field.type === 'select') {
+ optionsContainerEl.style.display = 'block';
+ optionListEl.innerHTML = '';
+ field.options.forEach(opt => {
+ const optionDiv = document.createElement('div');
+ optionDiv.classList.add('option-item');
+
+ const labelInput = document.createElement('input');
+ labelInput.type = 'text';
+ labelInput.placeholder = 'Option Label';
+ labelInput.value = opt.label;
+ labelInput.classList.add('option-label');
+
+ const valueInput = document.createElement('input');
+ valueInput.type = 'text';
+ valueInput.placeholder = 'Option Value';
+ valueInput.value = opt.value;
+ valueInput.classList.add('option-value');
+
+ const removeBtn = document.createElement('button');
+ removeBtn.textContent = 'Remove';
+ removeBtn.setAttribute('class', 'btn btn-danger');
+ removeBtn.addEventListener('click', () => {
+ if (confirm("Are you sure you want to remove this option?")) {
+ optionDiv.remove();
+ }
+ });
+
+ optionDiv.appendChild(labelInput);
+ optionDiv.appendChild(valueInput);
+ optionDiv.appendChild(removeBtn);
+ optionListEl.appendChild(optionDiv);
+ });
+ } else {
+ optionsContainerEl.style.display = 'none';
+ optionListEl.innerHTML = '';
+ }
+
+ editingIndex = index;
+ addFieldBtn.textContent = "Update Field";
+}
+
+// Update preview with Edit and Delete buttons
+function updatePreviewAndOutput() {
+ formPreviewEl.innerHTML = '';
+
+ fields.forEach((f, index) => {
+ const wrapper = document.createElement('div');
+ wrapper.setAttribute('class', 'field-preview form-group');
+
+ if (f.type !== 'checkbox') {
+ const label = document.createElement('label');
+ label.textContent = f.label;
+ wrapper.appendChild(label);
+ }
+
+ let el;
+ if (f.type === 'textarea') {
+ el = document.createElement('textarea');
+ el.placeholder = f.label;
+ el.setAttribute('class', 'form-control');
+ el.value = f.value;
+ } else if (f.type === 'checkbox') {
+ el = document.createElement('input');
+ el.type = 'checkbox';
+ el.checked = f.value === 'true';
+ const checkboxLabel = document.createElement('span');
+ checkboxLabel.textContent = ` ${f.label} `;
+ wrapper.appendChild(el);
+ wrapper.appendChild(checkboxLabel);
+ el = null;
+ } else if (f.type === 'select') {
+ el = document.createElement('select');
+ el.setAttribute('class', 'form-control');
+ f.options.forEach(opt => {
+ const option = document.createElement('option');
+ option.value = opt.value;
+ option.textContent = opt.label;
+ el.appendChild(option);
+ });
+ } else {
+ el = document.createElement('input');
+ el.type = f.type;
+ el.value = f.value;
+ el.placeholder = f.label;
+ el.setAttribute('class', 'form-control');
+ }
+
+ if (el) {
+ wrapper.appendChild(el);
+ }
+
+ const editBtn = document.createElement('button');
+ editBtn.textContent = 'Edit';
+ editBtn.addEventListener('click', () => editField(index));
+ editBtn.setAttribute('class', 'btn btn-primary btn-xs');
+ wrapper.appendChild(editBtn);
+
+ const deleteBtn = document.createElement('button');
+ deleteBtn.textContent = 'Delete';
+ deleteBtn.addEventListener('click', () => deleteField(index));
+ deleteBtn.setAttribute('class', 'btn btn-danger btn-xs');
+ wrapper.appendChild(deleteBtn);
+
+ formPreviewEl.appendChild(wrapper);
+ });
+
+ jsonOutputEl.value = JSON.stringify(fields, null, 2);
+ nameEl.value = '';
+ labelEl.value = '';
+ valueEl.value = '';
+ optionsContainerEl.style.display = 'none';
+ optionListEl.innerHTML = '';
+ typeEl.value = "text";
+ addFieldBtn.textContent = "Add Field";
+}
+
+// Real-time removal of spaces in the name field
+nameEl.addEventListener('input', () => {
+ nameEl.value = nameEl.value.replace(/\s+/g, ''); // Remove spaces in real-time
+});
+
+document.addEventListener('DOMContentLoaded', () => {
+ updatePreviewAndOutput();
+});