前言
事情是这样的:我觉得WP的说说是个好功能,应该大力用,从此告别微博。但每次发表都要进后台,这实在是太操蛋了。
需求自然而然地浮现了!我的第一反应是借用邮件发文的功能来写邮件发表,然后去github给S老师提了issue——但是S老师现在应该已经不怎么开发argon主题了。
第二反应变得合理了很多:在说说页面添加一个仅站长可见的表单,用来在前台发表说说。和这个主意比起来,用邮件发说说这件事听起来简直是苏联遗风。
问题来了:这件事听起来还挺简单的,像是不到一百行业务代码就能搞定的事情。但是我完全没有html和php经验啊!难道要在我宝贵的科研时间中抽空从头学冢中枯骨php?
于是G老师登场了。联想到以前让GPT老师帮我改论文、写小轮子的经历,我相信它也能搞定wordpress这种文档和案例都很丰富的工具。
首先是搞清楚要做什么
3月1号晚上,我还对wordpress的架构还几乎完全不懂——意思是说,我根本不知道argon主题添加的这个和“文章”逻辑上平级的“说说”是个什么东西。所以我用谦卑的语言向G老师描述了我的需求:
我使用的wordpress主题增加了一个新的,与“文章”模块逻辑上并列的模块,允许我发布类似推特的,无标题的简短文字。我希望用邮件的方式发表这些文字,我该如何开始开发类似功能?(这时我还卡在第一反应那里)
G老师是这么回答我的:
实现这个功能需要以下几个步骤:
- 首先,您需要在 WordPress 后台新建一个自定义 post type(文章类型),用来存储这些简短的文字。可以使用“register_post_type()”函数来创建自定义 post type。
- 然后,您需要编写一个自定义的邮件发送函数,可以使用 WordPress 提供的“wp_mail()”函数来发送邮件。
- 在邮件发送函数中,您需要编写代码来获取最新发布的简短文字。可以使用 WordPress 提供的“get_posts()”函数获取自定义 post type 中的最新一条记录。
- 您还需要为这个功能添加一个前端表单,让用户可以在网站上输入并提交简短文字。可以使用 WordPress 提供的“wp_insert_post()”函数将用户提交的文字插入到自定义 post type 中。
- 最后,您需要设置一个定时任务来自动发送邮件。可以使用 WordPress 提供的“wp_schedule_event()”函数来设置定时任务,并将邮件发送函数作为回调函数传递给它。
需要注意的是,这只是一个大致的开发流程,具体实现过程还需要根据您的需求进行调整和细化。同时,为了确保安全性和稳定性,建议在开发过程中遵循 WordPress 的最佳实践和安全规范。
G老师回答得很简明,但一下子让我明白了说说是个什么东西。于是我开始向G老师询问如何在前端添加一个表单来发表自定义的post type。
我现在已经有了一个创建好的post type,可以在后台正常发表。针对我的这种情况,详细地告诉我应该怎么在前台创建一个表单,来发表post。
G老师的回复还是很简明,似乎有点太高看我的php开发经验了:
好的,接下来的步骤大致如下:
- 创建一个自定义模板,用于在前端展示表单,你可以在 WordPress 的模板文件夹中创建一个 PHP 文件,比如说
my-form-template.php。- 在这个模板文件中添加一个表单,包含你想要的所有字段。每个字段需要指定一个名称和类型,以便稍后将表单数据与自定义文章类型的属性相匹配。
- 编写一个处理表单提交的 PHP 文件。你可以在主题文件夹中创建一个新的 PHP 文件,比如说
submit-form.php。在这个文件中,你需要验证表单数据,然后使用wp_insert_post()函数创建一篇新的自定义文章类型。- 将表单提交到
submit-form.php,并使用 AJAX 在不刷新页面的情况下处理表单提交。你可以使用 jQuery 或其他 JavaScript 库来实现这一点。具体实现方式可能会因为你的需求不同而有所不同,你可能需要深入了解 PHP 和 WordPress 开发的知识来实现这些步骤。
于是我告诉G老师我的这个post type很简单,没有标题,没有分类,也没有标签,要求G老师给出完整的例子。G老师给我写了一个简单的自定义模板,不过是分开写的。
如果你的自定义post type非常简单,没有任何分类和标签,那么可以使用WordPress自带的默认模板single.php来显示自定义post type的内容。不过,如果你想对这个post type的显示样式进行更加精细的控制,可以使用自定义模板。
下面是一个简单的自定义模板的例子:
- 首先,在你的主题文件夹中创建一个新的文件,命名为single-{post_type_slug}.php。例如,如果你的post type slug是“my_post_type”,那么你需要创建一个名为single-my_post_type.php的文件。
- 在这个新创建的文件中,使用以下代码作为模板的起始点:
<?php get_header(); ?> <div id="primary" class="content-area"> <main id="main" class="site-main" role="main"> <?php while ( have_posts() ) : the_post(); ?> <?php get_template_part( 'template-parts/content', get_post_type() ); ?> <?php endwhile; // End of the loop. ?> </main><!-- #main --> </div><!-- #primary --> <?php get_sidebar(); ?> <?php get_footer(); ?>(必须要提的是,G老师写的代码缩进很完美,但复制过来会有点问题……)这个模板的主要内容是使用get_template_part()函数来调用另一个模板文件template-parts/content-{post_type_slug}.php来显示你的自定义post type的内容。在这个函数中,get_post_type()函数用于获取当前文章的post type slug。
- 创建另一个名为template-parts/content-{post_type_slug}.php的文件,并在其中添加以下内容:
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <header class="entry-header"> <?php the_title( '<h1 class="entry-title">', '</h1>' ); ?> </header><!-- .entry-header --> <div class="entry-content"> <?php the_content(); ?> </div><!-- .entry-content --> </article><!-- #post-<?php the_ID(); ?> -->这个模板文件显示了自定义post type的标题和内容。你可以根据需要进行自定义,比如添加更多的元数据、特色图像等等。
- 保存这两个文件,然后访问你的自定义post type的单个页面,你应该能够看到使用自定义模板的样式。
注意:如果你的自定义post type是使用了某个插件来创建的,可能需要使用该插件提供的自定义模板文件名来替换上述例子中的文件名。
要在模板底部添加一个表单以便用户直接发表新的 post,可以按照以下步骤操作:
- 在模板底部添加一个表单,例如:
<form method="post"> <label for="post-title">标题:</label> <input type="text" name="post-title" id="post-title" /> <label for="post-content">内容:</label> <textarea name="post-content" id="post-content"></textarea> <button type="submit">发布文章</button> </form>
- 在表单提交时,通过 PHP 代码创建新的 post。例如:
// 检查表单是否提交 if ($_SERVER['REQUEST_METHOD'] === 'POST') { // 获取表单数据 $title = $_POST['post-title']; $content = $_POST['post-content']; // 创建新的 post $post_id = wp_insert_post([ 'post_title' => $title, 'post_content' => $content, 'post_status' => 'publish', 'post_type' => 'your_custom_post_type', // 替换为你的 post type 名称 ]); // 如果 post 创建成功,则显示成功消息 if ($post_id) { echo '<p>文章已发布!</p>'; } }
- 在表单中添加适当的输入验证和过滤以确保数据的安全性。
以上是一个简单的例子,可以根据需要进行更改和扩展。
G老师还会教我注意安全性……我哭死。
虽然G老师的指点很详细,但因为我真的太素了,对html如何工作、php如何工作、它们如何在一起工作毫无了解,还是折腾了好一会儿。在这个过程中,我学会了取巧的问法。
我的wordpress上站点上有一个自定义的post type(名为“shuoshuo”),它很简单,没有任何分类和标签,也不需要标题。这个post type已经可以正常工作了,不需要做额外的改动。我现在要在一个页面模板的底部添加一个表单,让管理员用户能通过这个表单直接在前端发表属于这个post type的内容。告诉我详细的过程。
请告诉我如何添加额外的代码以验证用户权限
我没有学习过php,所以请你给你刚才发表的所有代码逐行加入注释,解释一下每行是在做什么
然后G老师就真的给我一行一行写了注释……
当然,我很乐意为您解释这些代码!以下是完整代码和每行的注释:
<?php /* Template Name: Custom Shuoshuo */ // 验证提交的表单数据 if ( isset( $_POST['submit_shuoshuo'] ) ) { // 获取表单随机数码并验证它是否匹配 if ( wp_verify_nonce( $_POST['shuoshuo_nonce'], 'shuoshuo_nonce_action' ) ) { // 获取表单中的“shuoshuo”帖子类型的内容 $shuoshuo_content = $_POST['shuoshuo_content']; // 创建一个新的“shuoshuo”帖子类型 $new_post = array( 'post_content' => $shuoshuo_content, 'post_status' => 'publish', 'post_type' => 'shuoshuo' ); // 将新帖子插入数据库中并获取其ID $post_id = wp_insert_post( $new_post ); // 如果插入成功,则重定向到新帖子的URL if ( $post_id ) { wp_redirect( get_permalink( $post_id ) ); exit; } } } // 开始输出页面内容 get_header(); ?> <div id="primary" class="content-area"> <main id="main" class="site-main" role="main"> <?php // 开始WordPress循环,循环出所有“shuoshuo”帖子类型的文章 while ( have_posts() ) : the_post(); // 获取当前文章的标题和内容 $title = get_the_title(); $content = get_the_content(); // 输出标题和内容 echo '<h1>' . $title . '</h1>'; echo '<div>' . $content . '</div>'; endwhile; // 结束循环 ?> <?php // 输出一个包含文本区域和提交按钮的表单 ?> <form method="post"> <textarea name="shuoshuo_content"></textarea> <br> <input type="submit" name="submit_shuoshuo" value="发表"> <?php wp_nonce_field( 'shuoshuo_nonce_action', 'shuoshuo_nonce' ); ?> </form> </main><!-- #main --> </div><!-- #primary --> <?php get_footer(); ?>希望这些注释对您有帮助!如果您有任何疑问,请随时问我。
现在回过头来看看的话,这个自定义模板连输出评论的功能都写了,多少有点超出了我的需求……
anyway,根据G老师的指示,我成功在页面底端加了一个(只有管理员可见的)表单和提交按钮,可以用来提交post。但是它太丑了!光秃秃的文本框和按钮,简直目不忍视。
虽然这些内容只有我自己能看到,但我还是决心套用argon主题的风格将其美化。当时已经是半夜快两点,现在想想我那个时候就应该去睡觉的。
为了美化,从头让G老师教我html
我想了一下,感觉如果要美化的话,不懂一点html恐怕还是很难。于是我开始让G老师一行一行给我讲。
</div><!– .entry-content –>这句是在做什么?
这句话是一个 HTML 注释,用于标记 “entry-content” 类的 div 元素的结束位置,也就是其内容的结束位置。在这个特定的代码段中,这个 div 元素包裹了 WordPress 循环中每篇文章的内容,即标题和正文。通过这个注释,我们可以在浏览器中更轻松地阅读和理解 HTML 代码结构。
</article><!– #post-<?php the_ID(); ?> –>这句是在做什么
这句话是一个 HTML 注释,用于标记 “article” 元素的结束位置。在这个特定的代码段中,”article” 元素用于包裹 WordPress 循环中每篇文章的整个内容,包括标题、正文、评论等。通过这个注释,我们可以在浏览器中更轻松地阅读和理解 HTML 代码结构。在这个注释中,我们使用了 PHP 的
the_ID()函数,将当前文章的 ID 输出到 HTML 注释中,以帮助开发者在调试和排查问题时更轻松地定位到特定文章的 HTML 代码。
<main id=”main” class=”site-main” role=”main”>这句是在做什么
这句话是一个 HTML 元素,定义了一个主要的页面区域,其 ID 为 “main”,类名为 “site-main”,并且具有 “main” 的角色。在 WordPress 主题中,”main” 元素通常用于包裹文章列表、搜索结果、存档等页面的主要内容区域。它是语义化的 HTML 元素之一,有助于开发者编写可访问和可维护的代码。在这个特定的代码段中,我们使用了 WordPress 提供的 “main” 元素样式和相关函数,以确保这个元素可以正确地与主题的样式和功能相集成。
试着为我解释这句代码:<h3 class=”text-black”><?php _e(‘自说自话’, ‘argon’);?></h3>。其中argon是主题的名称,可能指定了某种文本样式
这段代码创建了一个包含文本 “自说自话” 的标题标签 “h3″,并且给它添加了一个类名 “text-black”。在这个特定的代码段中,我们使用了 PHP 的
_e()函数来输出 “自说自话” 这个文本字符串,并且指定了 “argon” 作为翻译域名。翻译域名用于在 WordPress 主题或插件中对文本进行国际化和本地化处理。这里 “argon” 可能是主题名称,也可能是在主题中指定的某个翻译域名,具体取决于主题的实现方式。样式名称 “text-black” 可能是定义在主题的 CSS 文件中的一个类名,用于指定标题文本的颜色样式。
我可以用相似的方法来输出上文中“submit”这个按钮里面的文本吗?
是的,您可以使用类似的方式来输出 “submit” 按钮里面的文本。在提交按钮的代码中,我们使用了
value属性来指定按钮上的文本。因此,您可以使用 PHP 的_e()函数或者__()函数来输出文本,并将其赋值给value属性。例如:<input type="submit" name="submit" value="<?php _e('提交', 'argon'); ?>">这段代码将会在 “submit” 按钮上输出 “提交” 这个文本字符串,并且使用 “argon” 作为翻译域名。如果主题使用了不同的翻译域名,您需要相应地更改翻译域名参数。
我就这么让G老师给我讲了半小时html……不得不说,G老师讲得比CSDN强多了……
于是我如法炮制,又把留言板页面的代码复制出来让G老师给我讲。这个过程还比较长,就不全都写出来了。
总之,最后在G老师的指导下,我成功给说说底端加了一个表单,还搞了一个新的页面来单独发说说。整个过程大概用了……8小时?对于0基础html来说应该算是很好的老师了。
G老师,我的超人
在过程中,我还让G老师写了一个搜索路径下所有文本文件内容的小程序。
给我用python写一个GUI,可以在一个指定文件夹下的所有文本文件(包含.php,.md等可以用文本编辑器打开的文件)的内容中查找字符串,并输出它在哪些文件中存在。
代码有点长(因为代码块排版有点问题)就不放了,但是G老师写的东西虽然不好看却真的直接就能用……就这么个小程序,写肯定是不难,但是怎么说也要写个十分钟——大部分时间都用来查平时不常用的轮子了!但G老师2分钟就能写出一个能用的东西,实在是太棒了。
最后把G老师(和我的,但主要是G老师的)的成果放在下面,万一有人看到呢:
一个是重写了的说说页面模板,另一个是去掉了sidebar的纯净发po页面。
总结一下的话:
- G老师对入门级问题的指导是极其精准且全面的,越初级的问题G老师答得越好。对于有一点经验的人来说,使用G老师后新工具的学习曲线会陡峭得吓人。
- G老师的理解能力非常惊人。在调试的过程中,我多次把写好的页面模板直接扔给G老师,有时扔到一个新的对话里,G老师都能迅速分析出这个页面是干什么的。
- G老师的注释能力也很厉害,当我把一段全新的、夹杂了一些自定义style的html代码扔给G老师,G老师也能迅速理解这是在干什么。
- G老师甚至能做出猜测,按照我提供的html样式给我写模板,这个就很吓人…
总之,G老师目前已经成为CSDN的超级上位替代,废话-80%,效率+200%,而且极其善解人意。我现在深深地为几个月前试图和G老师文爱而感到愧疚,面对这么好的老师我居然第一反应是冲着下三路去的,简直是行走的鸡巴……


