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 +
+
+ + type == 'text'):?> + + +
+ type == 'textarea'):?> + + +
+ type == 'checkbox'):?> + + +
+ type == 'select'):?> + + + + +
+
+
+
+ -

+
@@ -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 +
+
+ + type == 'text'):?> + + +
+ type == 'textarea'):?> + + +
+ type == 'checkbox'):?> + + +
+ type == 'select'):?> + + + + +
+
+
+
+ + @@ -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

+
+ + +
+

+ +
+ + + + + + + + + +
+ +

+ + +

+ +
+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

+
+ + +
+

+ +
+ + + + + + + + + +
+ +

+ + +

+ +
+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

+
+ + +
+

+ +
+ + + + + + + + + +
+ +

+ + +

+ +
+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

+
+ + +
+

+ +
+ + + + + + + + + +
+ +

+ + +

+ +
+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: +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
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 +
+
+ + type == 'text'):?> + + +
+ type == 'textarea'):?> + + +
+ type == 'checkbox'):?> + name, $content);?>> + +
+ type == 'select'):?> + + + + +
+
+
+
+ + -

+
@@ -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 +
+
+ + type == 'text'):?> + + +
+ type == 'textarea'):?> + + +
+ type == 'checkbox'):?> + name, $content);?>> + +
+ type == 'select'):?> + + + + +
+
+
+
+ @@ -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(); +});