Browse Source

adding first version of ai assistance mark

Medowar 1 month ago
parent
commit
654082d2db

+ 1 - 0
content/medowar/blog/posts/post/2026-08-09-23-06-28_framework,linux_fixing-fan-and-energy-settings-on-framework-13-linuxkubuntu.md

@@ -1,6 +1,7 @@
 <!--t Fixing fan and energy settings on Framework 13 Linux/Kubuntu t-->
 <!--d Making a Framework 13 (AMD) Quiet and Long-Lasting on Kubuntu Setup: Framework Laptop 13, Ryzen 5 7640U, BIOS 3.20, Kubuntu 26.04, kernel 7.0. The d-->
 <!--tag framework,linux tag-->
+<!--ai yes ai-->
 
 **Setup:** Framework Laptop 13, Ryzen 5 7640U, BIOS 3.20, Kubuntu 26.04, kernel 7.0.
 

+ 5 - 0
lang/de_DE.ini

@@ -336,3 +336,8 @@ custom_fields = "Custom fields"
 views_counter = "Views counter"
 themes = "Themes"
 version = "Version"
+
+; AI usage flag
+ai_assisted = "KI-Unterstützung"
+ai_assisted_info = "Diesen Beitrag als teilweise mit KI erstellt markieren. Zeigt ein Roboter-Symbol neben der Autorenzeile."
+ai_used_notice = "KI wurde teilweise zur Erstellung dieses Artikels verwendet"

+ 5 - 0
lang/de_DE_gender_doppelpunkt.ini

@@ -336,3 +336,8 @@ custom_fields = "Custom fields"
 views_counter = "Views counter"
 themes = "Themes"
 version = "Version"
+
+; AI usage flag
+ai_assisted = "KI-Unterstützung"
+ai_assisted_info = "Diesen Beitrag als teilweise mit KI erstellt markieren. Zeigt ein Roboter-Symbol neben der Autorenzeile."
+ai_used_notice = "KI wurde teilweise zur Erstellung dieses Artikels verwendet"

+ 5 - 0
lang/de_DE_gender_dudenkonform.ini

@@ -336,3 +336,8 @@ custom_fields = "Custom fields"
 views_counter = "Views counter"
 themes = "Themes"
 version = "Version"
+
+; AI usage flag
+ai_assisted = "KI-Unterstützung"
+ai_assisted_info = "Diesen Beitrag als teilweise mit KI erstellt markieren. Zeigt ein Roboter-Symbol neben der Autorenzeile."
+ai_used_notice = "KI wurde teilweise zur Erstellung dieses Artikels verwendet"

+ 5 - 0
lang/en_US.ini

@@ -336,3 +336,8 @@ custom_fields = "Custom fields"
 views_counter = "Views counter"
 themes = "Themes"
 version = "Version"
+
+; AI usage flag
+ai_assisted = "AI assisted"
+ai_assisted_info = "Mark this post as partly generated with AI. Shows a robot icon next to the byline."
+ai_used_notice = "AI was used in parts to generate this article"

+ 6 - 0
system/admin/views/add-content.html.php

@@ -186,6 +186,12 @@ $( function() {
                     <?php if ($type == 'is_post'):?>
                     <input type="hidden" name="is_post" value="is_post">
                     <?php endif;?>
+
+                    <input type="checkbox" id="pAI" name="ai" value="yes">
+                    <label for="pAI"><?php echo i18n('AI_assisted');?></label>
+                    <span class="d-block mt-1"><small><em><?php echo i18n('AI_assisted_info');?></em></small></span>
+                    <br>
+
                     <input id="oldfile" type="hidden" name="oldfile" class="text"/>
                     <input type="hidden" name="csrf_token" value="<?php echo get_csrf() ?>">
                 </div>

+ 7 - 0
system/admin/views/edit-content.html.php

@@ -21,6 +21,7 @@ $oldaudio = get_content_tag('audio', $content);
 $oldvideo = get_content_tag('video', $content);
 $oldlink = get_content_tag('link', $content);
 $oldquote = get_content_tag('quote', $content);
+$oldai = get_content_tag('ai', $content);
 
 $dir = $file_path['dirname'];
 $isdraft = explode('/', $dir);
@@ -233,6 +234,12 @@ $( function() {
                     <?php if ($type == 'is_post'):?>
                     <input type="hidden" name="is_post" value="is_post">
                     <?php endif;?>
+
+                    <input type="checkbox" id="pAI" name="ai" value="yes" <?php if (!empty($oldai)) { echo 'checked'; } ?>>
+                    <label for="pAI"><?php echo i18n('AI_assisted');?></label>
+                    <span class="d-block mt-1"><small><em><?php echo i18n('AI_assisted_info');?></em></small></span>
+                    <br>
+
                     <input id="oldfile" type="hidden" name="oldfile" class="text" value="<?php echo $filename; ?>"/>
                     <input type="hidden" name="csrf_token" value="<?php echo get_csrf() ?>">
                 </div>

+ 19 - 5
system/htmly.php

@@ -778,8 +778,11 @@ post('/add/content', function () {
                 $field[$af->name] = from($_REQUEST, $af->name);
             }
         }
-    }    
-    
+    }
+
+    // The "AI was used" flag. Unchecked means empty, so no tag is written.
+    $field['ai'] = from($_REQUEST, 'ai') ? 'yes' : '';
+
     $is_image = from($_REQUEST, 'is_image');
     $is_audio = from($_REQUEST, 'is_audio');
     $is_video = from($_REQUEST, 'is_video');
@@ -1057,7 +1060,12 @@ post('/admin/autosave', function () {
                     $field[$af->name] = from($_REQUEST, $af->name);
                 }
             }
-        }    
+        }
+
+        // The "AI was used" flag. Unchecked means empty, so no tag is written.
+        if ($posttype == 'is_post') {
+            $field['ai'] = from($_REQUEST, 'ai') ? 'yes' : '';
+        }
 
         if (empty($url)) {
             $url = $title;
@@ -4301,7 +4309,10 @@ post('/'. permalink_type() .'/:name/edit', function () {
             }
         }
     }
-    
+
+    // The "AI was used" flag. Unchecked means empty, so no tag is written.
+    $field['ai'] = from($_REQUEST, 'ai') ? 'yes' : '';
+
     $proper = is_csrf_proper(from($_REQUEST, 'csrf_token'));
     $title = from($_REQUEST, 'title');
     $is_post = from($_REQUEST, 'is_post');
@@ -5575,7 +5586,10 @@ post('/:year/:month/:name/edit', function () {
             }
         }
     }
-    
+
+    // The "AI was used" flag. Unchecked means empty, so no tag is written.
+    $field['ai'] = from($_REQUEST, 'ai') ? 'yes' : '';
+
     $proper = is_csrf_proper(from($_REQUEST, 'csrf_token'));
     $title = from($_REQUEST, 'title');
     $is_post = from($_REQUEST, 'is_post');

+ 1 - 0
system/includes/functions.php

@@ -475,6 +475,7 @@ function get_posts($posts, $page = 1, $perpage = 0)
         $post->link  = get_content_tag('link', $content);
         $post->quote  = get_content_tag('quote', $content);
         $post->audio  = get_content_tag('audio', $content);
+        $post->ai  = get_content_tag('ai', $content);
 
         $tag = array();
         $url = array();

+ 1 - 0
system/resources/js/save_draft.js

@@ -20,6 +20,7 @@ function updateData() {
     pquote: $("#pQuote").val(),
     plink: $("#pLink").val(),
     dateTime: $("#pDate").val() + " " + $("#pTime").val(),
+    ai: $("#pAI").is(":checked") ? "yes" : "",
     autoSave: 'autoSave',
     addEdit: addEdit,
     oldfile: $("#oldfile").val(),

+ 58 - 0
themes/tailwind-custom/css/style.css

@@ -195,4 +195,62 @@
 	.prose pre .copy-code {
 		opacity: 1;
 	}
+}
+
+/* "AI was used" marker next to the byline */
+.ai-badge {
+	position: relative;
+	display: inline-block;
+	cursor: help;
+	line-height: 1;
+	vertical-align: middle;
+}
+
+.ai-badge-tip {
+	position: absolute;
+	bottom: calc(100% + .5rem);
+	left: 50%;
+	transform: translateX(-50%);
+	z-index: 20;
+	width: max-content;
+	max-width: 15rem;
+	padding: .35rem .6rem;
+	border-radius: .375rem;
+	font-size: .75rem;
+	line-height: 1rem;
+	font-weight: 400;
+	text-align: center;
+	color: rgb(243 244 246);
+	background-color: rgb(31 41 55);
+	box-shadow: 0 4px 6px -1px rgb(0 0 0/.1), 0 2px 4px -2px rgb(0 0 0/.1);
+	opacity: 0;
+	visibility: hidden;
+	transition: opacity .15s ease;
+}
+
+.dark .ai-badge-tip {
+	color: rgb(31 41 55);
+	background-color: rgb(229 231 235);
+}
+
+/* The arrow pointing down at the emoji. */
+.ai-badge-tip::after {
+	content: "";
+	position: absolute;
+	top: 100%;
+	left: 50%;
+	margin-left: -.25rem;
+	border: .25rem solid transparent;
+	border-top-color: rgb(31 41 55);
+}
+
+.dark .ai-badge-tip::after {
+	border-top-color: rgb(229 231 235);
+}
+
+.ai-badge:hover .ai-badge-tip,
+.ai-badge:focus .ai-badge-tip,
+.ai-badge:focus-visible .ai-badge-tip {
+	opacity: 1;
+	visibility: visible;
 }

+ 1 - 0
themes/tailwind-custom/main.html.php

@@ -78,6 +78,7 @@
                             <dt class="sr-only"><?php echo i18n('posted_on');?></dt>
                             <dd class="text-base font-medium leading-6 text-gray-500 dark:text-gray-400"><time><?php echo format_date($p->date);?></time>
                             • <span>by <a class="text-primary-500 hover:text-primary-600 dark:hover:text-primary-400" href="<?php echo $p->authorUrl;?>"><?php echo $p->authorName;?></a></span>
+                            <?php if (!empty($p->ai)):?> <span class="ai-badge" tabindex="0" role="img" aria-label="<?php echo i18n('ai_used_notice');?>">&#129302;<span class="ai-badge-tip"><?php echo i18n('ai_used_notice');?></span></span><?php endif;?>
                             <?php if (authorized($p)):?> • <span><a href="<?php echo $p->url;?>/edit?destination=post"><?php echo i18n('edit');?></a></span><?php endif;?>
                             </dd>
                         </dl>

+ 1 - 0
themes/tailwind-custom/post.html.php

@@ -10,6 +10,7 @@
                             <dd class="text-base font-medium leading-6 text-gray-500 dark:text-gray-400"><time><?php echo format_date($p->date);?></time>
                             • <span><img class="mr-2 inline-block rounded-full align-middle" src="<?php echo $p->authorAvatar;?>" width="24" height="24" alt="<?php echo $p->authorName;?>"/><a class="text-primary-500 hover:text-primary-600 dark:hover:text-primary-400" href="<?php echo $p->authorUrl;?>"><?php echo $p->authorName;?></a></span>
                             • <span class="text-primary-500"><?php echo $p->category;?></span>
+                            <?php if (!empty($p->ai)):?> <span class="ai-badge" tabindex="0" role="img" aria-label="<?php echo i18n('ai_used_notice');?>">&#129302;<span class="ai-badge-tip"><?php echo i18n('ai_used_notice');?></span></span><?php endif;?>
                             <?php if (authorized($p)):?> • <span><a href="<?php echo $p->url;?>/edit?destination=post"><?php echo i18n('edit');?></a></span><?php endif;?>
                             </dd>
                         </div>