推荐几个wordpress下的markdown格式发布插件

WP Githuber MD 插件因安全问题已关闭,我们可以选择其他可靠的Markdown插件来替代。以下是几个推荐的Markdown插件:


推荐替代插件

  1. Jetpack(由Automattic开发)

    • Jetpack 是一个多功能插件,其中包含Markdown支持。
    • 下载地址:Jetpack on WordPress.org
    • 安装后,启用“Markdown”模块即可使用。
  2. WP-Markdown

  3. Markdown Editor

  4. Easy Markdown


安装步骤

方法一:通过WordPress后台安装

  1. 登录WordPress后台。
  2. 进入“插件” > “安装插件”。
  3. 在搜索框中输入插件名称(如“Jetpack”或“WP-Markdown”)。
  4. 找到插件后,点击“安装”,然后点击“激活”。

方法二:手动下载并安装

  1. 访问插件的WordPress页面(如上面的下载地址)。
  2. 下载插件的ZIP文件。
  3. 登录WordPress后台,进入“插件” > “安装插件” > “上传插件”。
  4. 上传ZIP文件并激活。

注意事项

  1. 备份网站:在安装新插件前,建议备份你的网站数据和数据库。
  2. 兼容性:确保插件支持WordPress 4.9.26版本。如果不确定,可以在插件的WordPress页面查看兼容性信息。
  3. 安全性:选择官方推荐的插件,避免使用来源不明的插件,以防止安全问题。
Posted in 网络相关 | Tagged | Leave a comment

如何让wordpress支持markdown格式的文章发布

要让WordPress支持Markdown格式的文章发布,可以按照以下步骤操作:

方法一:使用插件

  1. 安装Markdown插件

    • 登录WordPress后台,进入“插件” > “安装插件”。
    • 搜索“Markdown”插件,如“Jetpack”或“WP Githuber MD”。
    • 安装并激活插件。
  2. 配置插件

    • 激活后,进入插件设置页面,启用Markdown支持。
    • 部分插件可能需额外配置,如“WP Githuber MD”允许在文章编辑器中直接使用Markdown语法。

方法二:手动添加Markdown支持

  1. 编辑主题文件

    • 通过FTP或文件管理器,找到当前主题的functions.php文件。
    • 在文件末尾添加以下代码:
      php
      function enable_markdown_for_posts() {
      add_post_type_support( 'post', 'markdown' );
      }
      add_action( 'init', 'enable_markdown_for_posts' );
  2. 使用Markdown解析库

    • 下载并安装Markdown解析库,如Parsedown。
    • 将库文件上传到主题目录,并在functions.php中引入:
      php
      require_once get_template_directory() . '/parsedown/Parsedown.php';
  3. 在主题中解析Markdown

    • 修改主题模板文件,使用Parsedown解析Markdown内容:
      php
      $parsedown = new Parsedown();
      echo $parsedown->text( get_the_content() );

方法三:使用Markdown编辑器

  1. 安装Markdown编辑器插件
    • 搜索并安装Markdown编辑器插件,如“WP Editor.md”或“Markdown Editor”。
    • 安装后,激活插件即可在文章编辑器中使用Markdown格式。

注意事项

  • 备份:修改主题文件前,务必备份。
  • 插件冲突:某些插件可能与Markdown插件冲突,需测试兼容性。
  • 主题支持:部分主题可能不支持Markdown,需手动调整。

通过这些步骤,WordPress即可支持Markdown格式的文章发布。

Posted in 生活 | Leave a comment

内网穿透下的 wordpress 地址冲突问题与 https下的后台登陆问题

问题背景

当我们将个人博客搭建在 NAS 或软路由上,并通过 Cloudflare Zero Trust 或其他工具进行内网穿透以便公网访问时,可能会遇到以下两个问题:

  1. 内网穿透下的地址冲突
    使用内网穿透将本地的 WordPress 服务暴露到公网时,如果同时希望通过内网 IP 访问后台,会遇到 WordPress 主站地址冲突的问题。WordPress 无法确定是将内网 IP 还是公网域名作为主站地址。

  2. HTTPS 协议下无法登录管理后台
    使用 HTTPS 协议访问 WordPress 时,可能会遇到无法登录管理后台的问题。


解决方案

1. 内网穿透下的地址冲突

WordPress 有两个重要参数:WordPress 地址站点地址。通常情况下,这两个值是相同的。如果希望通过外网域名和内网 IP 同时访问,可以通过修改 wp-config.php 文件动态设置这两个参数。

wp-config.php 中添加以下代码:

$http_type = is_numeric(substr($_SERVER['HTTP_HOST'], 0, 1)) ? 'http://' : 'https://';
define('WP_SITEURL', $http_type . $_SERVER['HTTP_HOST']);
define('WP_HOME', $http_type . $_SERVER['HTTP_HOST']);

代码说明

  • 通过 is_numeric 判断访问地址的第一个字符是否为数字(即是否为 IP 地址)。
  • 如果是 IP 地址,使用 http://;如果是域名,使用 https://
  • 动态设置 WP_SITEURLWP_HOME,避免地址冲突。

2. HTTPS 登录管理后台

当使用 HTTPS 访问 WordPress 时,可能会遇到无法登录管理后台的问题。这是因为 WordPress 默认未强制启用 SSL。可以通过修改 wp-config.php 文件强制开启 SSL 访问。

wp-config.php 中添加以下代码:

$_SERVER['HTTPS'] = 'on';
define('FORCE_SSL_LOGIN', true);
define('FORCE_SSL_ADMIN', true);

代码说明

  • 强制将 $_SERVER['HTTPS'] 设置为 on,确保 WordPress 识别 HTTPS 协议。
  • 启用 FORCE_SSL_LOGINFORCE_SSL_ADMIN,强制后台使用 HTTPS 登录。

综合解决方案

如果既需要通过 HTTPS 登录后台,又需要保留内网 IP 访问的能力,可以将上述代码结合使用:

if (is_numeric(substr($_SERVER['HTTP_HOST'], 0, 1))) {
    $http_type = 'http://';
} else {
    $http_type = 'https://';
    $_SERVER['HTTPS'] = 'on';
    define('FORCE_SSL_LOGIN', true);
    define('FORCE_SSL_ADMIN', true);
}

define('WP_SITEURL', $http_type . $_SERVER['HTTP_HOST']);
define('WP_HOME', $http_type . $_SERVER['HTTP_HOST']);

代码说明

  • 如果是内网 IP 访问,使用 http://,不强制 HTTPS。
  • 如果是域名访问,使用 https://,并强制开启 HTTPS 登录。

总结

通过上述方法,可以解决内网穿透下的地址冲突问题,并确保 HTTPS 协议下能够正常登录 WordPress 管理后台。将代码添加到 wp-config.php 文件的最下方即可。

Posted in 网络相关 | Tagged , , | Leave a comment

Docker搭建WordPress绑定域名教程(二)

在上一节我们讲解了如何通过Docker快速搭建wordpress,这一节我们介绍下在Docker环境下,有哪些工具和程序可以帮助你轻松绑定域名并管理多个站点。以下是几种常用的解决方案:


1. Nginx Proxy Manager

Nginx Proxy Manager 是一个基于 Nginx 的反向代理管理工具,提供友好的 Web 界面来管理域名绑定、SSL 证书等。

安装步骤

  1. 创建 docker-compose.yml 文件:
    version: '3'
    services:
     app:
       image: 'jc21/nginx-proxy-manager:latest'
       restart: always
       ports:
         - '80:80'
         - '81:81'
         - '443:443'
       volumes:
         - ./data:/data
         - ./letsencrypt:/etc/letsencrypt
  2. 启动容器:
    docker-compose up -d
  3. 访问管理界面:
    • 打开浏览器,访问 http://your-server-ip:81
    • 默认登录信息:
  4. 在管理界面中添加域名和反向代理规则,绑定到你的 WordPress 容器。

2. Traefik

Traefik 是一个现代化的反向代理和负载均衡工具,专为容器化环境设计,支持自动发现 Docker 容器并绑定域名。

安装步骤

  1. 创建 docker-compose.yml 文件:

    version: '3'
    services:
     traefik:
       image: traefik:latest
       command:
         - --api.insecure=true
         - --providers.docker
         - --entrypoints.web.address=:80
       ports:
         - '80:80'
         - '8080:8080'
       volumes:
         - /var/run/docker.sock:/var/run/docker.sock
    
     wordpress:
       image: wordpress:latest
       environment:
         - WORDPRESS_DB_HOST=mysql
         - WORDPRESS_DB_USER=root
         - WORDPRESS_DB_PASSWORD=your_password
       labels:
         - "traefik.http.routers.wordpress.rule=Host(`yourdomain.com`)"
         - "traefik.http.routers.wordpress.entrypoints=web"
  2. 启动容器:
    docker-compose up -d
  3. 访问 Traefik 仪表板:
    • 打开浏览器,访问 http://your-server-ip:8080
  4. 访问 WordPress:
    • 打开浏览器,访问 http://yourdomain.com

3. Caddy

Caddy 是一个易于使用的 Web 服务器,支持自动 HTTPS 和反向代理。

安装步骤

  1. 创建 docker-compose.yml 文件:

    version: '3'
    services:
     caddy:
       image: caddy:latest
       ports:
         - '80:80'
         - '443:443'
       volumes:
         - ./Caddyfile:/etc/caddy/Caddyfile
         - ./caddy_data:/data
    
     wordpress:
       image: wordpress:latest
       environment:
         - WORDPRESS_DB_HOST=mysql
         - WORDPRESS_DB_USER=root
         - WORDPRESS_DB_PASSWORD=your_password
  2. 创建 Caddyfile 文件:
    yourdomain.com {
       reverse_proxy wordpress:80
    }
  3. 启动容器:
    docker-compose up -d
  4. 访问 WordPress:
    • 打开浏览器,访问 https://yourdomain.com(Caddy 会自动配置 HTTPS)。

4. Nginx + Let’s Encrypt(手动配置)

如果你更喜欢手动配置,可以使用 Nginx 和 Let’s Encrypt 结合 Docker 绑定域名。

安装步骤

  1. 创建 docker-compose.yml 文件:

    version: '3'
    services:
     nginx:
       image: nginx:latest
       ports:
         - '80:80'
         - '443:443'
       volumes:
         - ./nginx.conf:/etc/nginx/nginx.conf
         - ./certs:/etc/letsencrypt
    
     wordpress:
       image: wordpress:latest
       environment:
         - WORDPRESS_DB_HOST=mysql
         - WORDPRESS_DB_USER=root
         - WORDPRESS_DB_PASSWORD=your_password
  2. 创建 nginx.conf 文件:

    server {
       listen 80;
       server_name yourdomain.com;
    
       location / {
           proxy_pass http://wordpress:80;
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       }
    }
  3. 启动容器:
    docker-compose up -d
  4. 使用 Certbot 获取 SSL 证书:
    sudo certbot --nginx -d yourdomain.com

总结

  • Nginx Proxy Manager:适合需要 Web 界面管理的用户。
  • Traefik:适合动态容器环境,自动发现服务。
  • Caddy:简单易用,自动 HTTPS。
  • Nginx + Let’s Encrypt:适合需要完全手动配置的用户。

根据你的需求选择合适的工具即可轻松绑定域名。

Posted in 网络相关 | Tagged , , , | Leave a comment

Docker搭建WordPress并绑定域名教程(一)

这一节我们讲如何通过Docker搭建WordPress并绑定域名,步骤如下:


步骤1:配置域名DNS解析

  1. 登录你的域名注册商(如GoDaddy、阿里云等),进入DNS管理界面。
  2. 添加一条 A记录,将域名指向你的服务器公网IP。
    • 例如:@www 指向 123.123.123.123(你的服务器IP)。
  3. 等待DNS生效(通常几分钟到几小时),可通过 ping yourdomain.com 测试是否解析成功。

步骤2:确保Docker容器端口映射正确

  • 启动WordPress容器时,确保将容器的80/443端口映射到宿主机:
    docker run -d \
    --name wordpress \
    -p 80:80 \
    -p 443:443 \
    -e WORDPRESS_DB_HOST=mysql \
    -e WORDPRESS_DB_USER=root \
    -e WORDPRESS_DB_PASSWORD=your_password \
    wordpress:latest

    提示:如果使用其他端口(如8080),需通过反向代理转发(见步骤3)。


步骤3:配置反向代理(推荐Nginx)

  1. 安装Nginx
    sudo apt update && sudo apt install nginx
  2. 创建Nginx配置文件
    • /etc/nginx/sites-available/yourdomain.com 创建文件,内容如下:
      server {
       listen 80;
       server_name yourdomain.com www.yourdomain.com;
      
       location / {
           proxy_pass http://localhost:80;  # 如果WordPress容器端口映射到宿主机的80
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Forwarded-Proto $scheme;
       }
      }
  3. 启用配置并重启Nginx
    sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
    sudo nginx -t  # 测试配置
    sudo systemctl restart nginx

步骤4:更新WordPress站点地址

  1. 进入WordPress后台:访问 http://yourdomain.com/wp-admin
  2. 转到 设置 → 常规,修改以下两项为你的域名:
    • WordPress地址(URL)https://yourdomain.com
    • 站点地址(URL)https://yourdomain.com
  3. 保存更改。

步骤5:配置HTTPS(SSL证书)

  1. 使用Certbot自动获取证书
    sudo apt install certbot python3-certbot-nginx
    sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
  2. Certbot会自动修改Nginx配置,启用HTTPS并强制跳转。

步骤6:处理Docker专用网络(可选)

  • 如果使用Docker Compose且包含独立网络(如nginx-proxy),可在docker-compose.yml中添加环境变量:
    services:
    wordpress:
      environment:
        - VIRTUAL_HOST=yourdomain.com
        - LETSENCRYPT_HOST=yourdomain.com
        - [email protected]

常见问题排查

  • DNS未生效:使用 dig yourdomain.com 检查解析结果。
  • 端口冲突:确保宿主机80/443端口未被占用(sudo lsof -i :80)。
  • WordPress重定向错误:清除浏览器缓存或更新.htaccess文件。
  • 混合内容警告:确保站点URL为https://,并安装插件(如Really Simple SSL)。

完成以上步骤后,你的WordPress应能通过域名正常访问。如有问题,检查Docker日志(docker logs wordpress)和Nginx错误日志(/var/log/nginx/error.log)。

Posted in 网络相关 | Tagged , , , | Leave a comment

使用Cloudflare的zero trust内网穿透后,WordPress无法进入后台的解决方法

不少人在使用Cloudflare CDN后,Wordpress无法进入后台,主要是因为使用了Cloudflare的SSL。问deepseek这个问题好久,无法就那么几种方法,结果依然是“Sorry, you are not allowed to access this page”。彻底奔溃。

为解决这个问题,Cloudflare发布了一款Wordpress插件:

Flexible SSL for CloudFlare

使用也很简单,直接后台搜索这个插件,激活即可 。或者下载插件到plugins目录下,然后解压激活。

插件下载:https://wordpress.org/plugins/Cloudflare-flexible-ssl/

Posted in 网络相关 | Tagged , | Leave a comment

前列腺抗原是什么,有什么意义

前列腺抗原通常指的是前列腺特异性抗原(Prostate-Specific Antigen, PSA),它是一种由前列腺上皮细胞产生的蛋白质,主要存在于精液中,少量会进入血液。PSA的检测在男性健康(尤其是前列腺疾病)的筛查、诊断和监测中具有重要意义。


PSA的临床意义

  1. 前列腺癌的筛查与早期发现

    • PSA是前列腺癌的重要肿瘤标志物。血液中PSA水平升高可能提示前列腺癌风险,尤其是当数值明显高于正常范围时(通常正常值<4 ng/mL,但需结合年龄和个体差异)。
    • 早期前列腺癌可能无症状,PSA检测可帮助在症状出现前发现异常,从而尽早干预。
  2. 辅助诊断前列腺疾病

    • 前列腺癌:PSA升高可能提示癌症,但需结合直肠指检(DRE)、影像学(如MRI)和前列腺活检确诊。
    • 良性前列腺增生(BPH):良性前列腺肥大或炎症(如前列腺炎)也可能导致PSA轻度升高。
    • 前列腺炎:感染或炎症会暂时性升高PSA水平。
  3. 监测治疗效果与复发

    • 前列腺癌患者接受手术、放疗或激素治疗后,PSA水平会下降。
    • 治疗后PSA再次升高可能提示癌症复发或转移。
  4. 风险评估与预后判断

    • PSA水平越高,前列腺癌的恶性程度可能越高。
    • PSA检测还可结合其他指标(如PSA密度、PSA速度、游离PSA与总PSA比值)提高诊断准确性。

PSA的局限性

  1. 非特异性:PSA升高并非前列腺癌特有,良性前列腺疾病、尿路操作(如导尿)、骑自行车或射精后也可能导致短暂升高。
  2. 假阴性/假阳性风险:部分前列腺癌患者PSA可能正常(假阴性),而部分良性病变患者PSA升高(假阳性)。
  3. 过度诊断争议:PSA筛查可能导致过度活检和治疗(如对惰性癌的过度干预)。

建议

  • 筛查人群:一般建议50岁以上男性定期检测PSA;有前列腺癌家族史或非裔男性可提前至45岁。
  • 结果解读:需由医生结合临床症状、其他检查(如MRI、活检)综合判断,避免仅凭PSA单一指标下结论。
  • 动态监测:PSA短期内的快速上升(PSA速率)比单次绝对值更有意义。

总之,PSA是前列腺健康管理的重要工具,但需科学看待其意义和局限性,结合临床全面评估。如有异常,应及时就医进一步检查。

Posted in Resourse | Leave a comment

阿普唑仑(Alprazolam)和艾司唑仑

阿普唑仑(Alprazolam)和艾司唑仑(Estazolam)均属于苯二氮䓬类药物,但两者在药理特性、适应症及临床应用上存在一定差异。以下是主要区别:


1. 适应症

  • 阿普唑仑

    • 主要用途:焦虑症、恐慌症(尤其是急性焦虑发作)。
    • 特点:抗焦虑作用强,起效快(15-30分钟起效),对急性焦虑或恐慌发作效果显著。
  • 艾司唑仑

    • 主要用途:失眠(尤其是入睡困难或睡眠维持障碍)。
    • 特点:镇静催眠作用突出,适合短期失眠治疗。

2. 药效持续时间

  • 阿普唑仑:中短效药物,半衰期约 11-16小时,需每日多次服药。
  • 艾司唑仑:中长效药物,半衰期约 10-24小时,单次服药可维持整夜睡眠。

3. 副作用

  • 共同副作用:嗜睡、头晕、肌肉无力、记忆力下降等。
  • 差异
    • 阿普唑仑更易引起 情绪波动(如易怒)和 戒断反应(如突然停药可能引发反跳性焦虑)。
    • 艾司唑仑因作用时间长,次日残留效应(如困倦)可能更明显。

4. 成瘾性与依赖风险

  • 阿普唑仑:依赖性较高,长期使用后戒断症状(如震颤、抽搐)较严重。
  • 艾司唑仑:依赖风险相对较低,但仍需避免长期使用。

5. 代谢途径

  • 阿普唑仑:主要通过 肝脏CYP3A4酶 代谢,与葡萄柚、抗真菌药等联用可能增加血药浓度。
  • 艾司唑仑:经肝脏代谢,但受CYP3A4影响较小,药物相互作用风险较低。

总结

  • 焦虑/恐慌症:优先选择 阿普唑仑(需警惕依赖)。
  • 失眠:优先选择 艾司唑仑(注意次日嗜睡)。
  • 关键提醒:两者均需严格遵医嘱,避免长期或过量使用,停药时应逐渐减量。

如有具体症状或用药疑问,建议咨询专业医生,切勿自行调整用药方案。

Posted in Resourse | Leave a comment

WordPress所见即所得发布方法总结

根据错误提示,问题出在 <textarea> 元素上。具体原因是:

  1. <textarea> 被隐藏

    • TinyMCE 初始化后,会将原始的 <textarea> 隐藏(设置为 display: nonevisibility: hidden)。
    • 由于 <textarea> 被隐藏,浏览器无法对其进行验证(即使设置了 required 属性)。
  2. required 属性冲突

    • 你为 <textarea> 设置了 required 属性,但隐藏的表单控件无法通过浏览器的默认验证。

解决方法

方法 1:移除 required 属性

如果 TinyMCE 编辑器已经确保内容不为空,可以移除 <textarea>required 属性。

<textarea name="content" id="content" placeholder="在此输入内容..."></textarea>

方法 2:手动验证内容

在表单提交时,手动检查 TinyMCE 的内容是否为空。

document.querySelector('form').onsubmit = function() {
    var content = tinymce.get('content').getContent(); // 获取 TinyMCE 内容
    if (!content.trim()) {
        alert('内容不能为空!');
        return false; // 阻止表单提交
    }
    document.querySelector('textarea[name="content"]').value = content; // 同步到 textarea
};

方法 3:隐藏 <textarea> 但不影响验证

<textarea> 设置为透明且不可见,但仍然占据空间,以便通过浏览器验证。

<textarea name="content" id="content" placeholder="在此输入内容..." required
          style="opacity: 0; height: 0; width: 0; position: absolute;"></textarea>

方法 4:禁用浏览器默认验证

在表单中添加 novalidate 属性,禁用浏览器的默认验证,完全依赖 JavaScript 验证。

<form method="POST" action="" novalidate>

修复后的完整代码

以下是结合 方法 2方法 4 的修复代码:

<?php
// 加载 WordPress 环境
require_once('../wp-load.php');

// 检查是否提交了表单
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['content']) && isset($_POST['title'])) {
    // 检查 nonce 和用户权限
    if (!isset($_POST['markdown_publish_nonce']) || !wp_verify_nonce($_POST['markdown_publish_nonce'], 'markdown_publish_action')) {
        echo '<div class="error">安全验证失败,请重试。</div>';
    } elseif (!current_user_can('publish_posts')) {
        echo '<div class="error">你没有权限发布文章。</div>';
    } else {
        // 获取表单数据
        $title = sanitize_text_field($_POST['title']);
        $content = $_POST['content']; // TinyMCE 输出的 HTML 内容
        $category = isset($_POST['category']) ? intval($_POST['category']) : 0; // 分类 ID
        $tags = isset($_POST['tags']) ? sanitize_text_field($_POST['tags']) : ''; // 标签

        // 发布文章
        $post_id = wp_insert_post([
            'post_title'   => $title,
            'post_content' => $content,
            'post_status'  => 'publish', // 直接发布
            'post_author'  => get_current_user_id(), // 当前用户为作者
            'post_category' => [$category], // 分配分类
        ]);

        if ($post_id) {
            // 分配标签
            if (!empty($tags)) {
                wp_set_post_tags($post_id, $tags);
            }

            echo '<div class="success">文章发布成功!<a href="' . get_permalink($post_id) . '">查看文章</a></div>';
        } else {
            echo '<div class="error">文章发布失败,请重试。</div>';
        }
    }
}

// 获取所有分类
$categories = get_categories(['hide_empty' => false]);
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>所见即所得发布工具</title>
    <!-- 引入 TinyMCE -->
    <script src="https://cdn.tiny.cloud/1/你的API Key/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>
    <script>
        tinymce.init({
            selector: '#content', // 绑定到 textarea
            height: 500, // 编辑器高度
            menubar: false, // 隐藏菜单栏
            plugins: [
                'advlist autolink lists link image charmap print preview anchor',
                'searchreplace visualblocks code fullscreen',
                'insertdatetime media table paste code help wordcount'
            ],
            toolbar: 'undo redo | formatselect | bold italic backcolor | \
                       alignleft aligncenter alignright alignjustify | \
                       bullist numlist outdent indent | removeformat | help',
            init_instance_callback: function(editor) {
                console.log('TinyMCE 初始化完成'); // 检查初始化是否成功
            }
        });

        // 表单提交时同步 TinyMCE 内容
        document.querySelector('form').onsubmit = function() {
            var content = tinymce.get('content').getContent(); // 获取 TinyMCE 内容
            if (!content.trim()) {
                alert('内容不能为空!');
                return false; // 阻止表单提交
            }
            document.querySelector('textarea[name="content"]').value = content; // 同步到 textarea
        };
    </script>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }
        .publish-tool {
            max-width: 800px;
            margin: 20px auto;
            padding: 20px;
            border: 1px solid #ccc;
            background-color: #f9f9f9;
        }
        .publish-tool textarea {
            width: 100%;
            height: 200px;
            padding: 10px;
            font-size: 16px;
        }
        .publish-tool .buttons {
            margin-top: 10px;
        }
        .publish-tool .buttons button {
            padding: 10px 20px;
            font-size: 16px;
            margin-right: 10px;
            cursor: pointer;
        }
        .success {
            color: green;
            margin: 10px 0;
        }
        .error {
            color: red;
            margin: 10px 0;
        }
    </style>
    <script>
        // 重置表单
        function resetForm() {
            tinymce.get('content').setContent(''); // 清空 TinyMCE 内容
            document.querySelector('input[name="title"]').value = '';
            document.querySelector('select[name="category"]').selectedIndex = 0;
            document.querySelector('input[name="tags"]').value = '';
        }
    </script>
</head>
<body>
    <div class="publish-tool">
        <h1>所见即所得发布工具</h1>
        <form method="POST" action="" novalidate>
            <?php wp_nonce_field('markdown_publish_action', 'markdown_publish_nonce'); ?>
            <div>
                <label for="title">标题:</label>
                <input type="text" name="title" id="title" required>
            </div>
            <div>
                <label for="content">内容:</label>
                <textarea name="content" id="content" placeholder="在此输入内容..."></textarea>
            </div>
            <div>
                <label for="category">分类:</label>
                <select name="category" id="category">
                    <?php foreach ($categories as $cat): ?>
                        <option value="<?php echo $cat->term_id; ?>"><?php echo $cat->name; ?></option>
                    <?php endforeach; ?>
                </select>
            </div>
            <div>
                <label for="tags">标签(用逗号分隔):</label>
                <input type="text" name="tags" id="tags">
            </div>
            <div class="buttons">
                <button type="submit" name="publish">发布</button>
                <button type="button" onclick="resetForm()">重置</button>
            </div>
        </form>
    </div>
</body>
</html>

测试步骤

  1. 打开页面,确保 TinyMCE 编辑器正常加载。
  2. 输入标题和内容,选择分类和标签。
  3. 点击“发布”按钮,检查是否有成功或失败的提示信息。
  4. 如果内容为空,会弹出提示“内容不能为空!”并阻止表单提交。

如果还有其他问题,欢迎继续提问!

Posted in 网络相关 | Leave a comment

自动下载文章中的所有远程图片,并将它们保存到本地

错误信息表明 wp_generate_attachment_metadata 函数未定义。这是因为在 WordPress 中,wp_generate_attachment_metadata 函数位于 wp-admin/includes/image.php 文件中,而这个文件默认不会在插件或主题中自动加载。


解决方法

在调用 wp_generate_attachment_metadata 之前,需要手动引入 wp-admin/includes/image.php 文件。以下是修复后的代码:

php
复制
<?php
/*
Plugin Name: MY Auto Save Remote Image
Plugin URI: http://www.devsaab.com/wordpress/
Description: This plugin automatically downloads all remote images from a post and saves them locally.
Version: 1.4
Author: Prebhdev Singh
Disclaimer: No warranty or guarantee of any kind! Use this at your own risk.
*/

add_action('publish_post', 'fetch_images');

function fetch_images($post_ID) {
    // 检查是否正在自动保存
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }

    // 检查用户权限
    if (!current_user_can('edit_post', $post_ID)) {
        return;
    }

    // 引入 WordPress 图像处理函数
    require_once(ABSPATH . 'wp-admin/includes/image.php');

    // 获取文章内容
    $post = get_post($post_ID);
    $updated = $post->post_content;

    // 提取所有图片 URL
    if (preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches)) {
        $first_images = $matches[1];

        foreach ($first_images as $first_image) {
            // 检查图片域名是否与当前站点一致
            if (strpos($first_image, $_SERVER['HTTP_HOST']) === false) {
                // 处理 HTTPS
                $first_image = str_replace('http://', 'https://', $first_image);

                // 下载图片
                $get = wp_remote_get($first_image);
                if (!is_wp_error($get)) {
                    $type = wp_remote_retrieve_header($get, 'content-type');
                    if (strpos($type, 'image') === false) {
                        continue; // 如果不是图片,跳过
                    }

                    // 生成唯一文件名
                    $filename = wp_unique_filename(wp_upload_dir()['path'], rawurldecode(basename($first_image)));

                    // 保存图片
                    $mirror = wp_upload_bits($filename, '', wp_remote_retrieve_body($get));

                    if (!$mirror['error']) {
                        // 创建附件
                        $attachment = array(
                            'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
                            'post_mime_type' => $type
                        );
                        $attach_id = wp_insert_attachment($attachment, $mirror['file'], $post_ID);

                        if (!is_wp_error($attach_id)) {
                            // 生成附件元数据并更新
                            $attach_data = wp_generate_attachment_metadata($attach_id, $mirror['file']);
                            wp_update_attachment_metadata($attach_id, $attach_data);

                            // 替换文章中的图片 URL
                            $updated = str_replace($first_image, $mirror['url'], $updated);
                        }
                    } else {
                        error_log('Failed to save image: ' . $first_image);
                    }
                } else {
                    error_log('Failed to download image: ' . $first_image);
                }
            }
        }

        // 更新文章内容
        if ($updated !== $post->post_content) {
            wp_update_post(array('ID' => $post_ID, 'post_content' => $updated));
        }
    }
}
?>

关键修复点

  1. 引入 wp-admin/includes/image.php

    • 在函数开头添加以下代码:

      php
      复制
      require_once(ABSPATH . 'wp-admin/includes/image.php');
    • 这确保了 wp_generate_attachment_metadata 函数可用。

  2. 确保文件路径正确

    • ABSPATH 是 WordPress 根目录的绝对路径,确保路径拼接正确。


测试步骤

  1. 将修复后的代码保存为 my-auto-save-remote-image.php

  2. 上传到 WordPress 的 wp-content/plugins/ 目录。

  3. 在 WordPress 后台激活插件。

  4. 发布一篇包含远程图片的文章,检查插件是否正常工作。


注意事项

  1. 权限问题

    • 确保 WordPress 的上传目录(wp-content/uploads)有正确的写权限。

  2. HTTPS 支持

    • 如果远程图片使用 HTTPS,确保服务器支持 HTTPS 请求。

  3. 性能监控

    • 如果文章中有大量图片,可能会影响发布速度,建议监控服务器性能。

Posted in 网络相关 | Leave a comment