Wordpress 网址卡片插件 (二)

解决的问题

2025年,用ChatGPT 重新写了网址卡片插件,解决了部分问题:

  • 如果文章放几个加载很慢的网址时,打开文章会很慢,;
  • 卡片样式不好看

解决方法是第一次打开文章时,把卡片URL相关信息写入数据库中;修改css样式文件

更新代码后还存在的问题

下面就是最新的custom-card-plugin插件代码(不过还是有很多问题,没解决);

目前的问题:

  • 文章第一个网站卡片,标题和描述一直loading;
  • 卡片样式还是存在很多不协调的问题
  • 整个卡片不能点击跳转,只能点击查看详情
  • 每个卡片大小不统一

custom-plugin.php代码

<?php
/**
 * Plugin Name: Custom Card Plugin
 * Description: wordpress 的网站卡片插件。
 * Version: 1.0
 * Author: chenghoufeng/https://www.saiita.com.cn
 */

// 防止直接访问
if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}

// 激活插件时创建数据表
function custom_card_create_db_table() {
    global $wpdb;

    $table_name = $wpdb->prefix . 'custom_card_cache';  // 表名:wp_custom_card_cache

    // 设置字符集
    $charset_collate = $wpdb->get_charset_collate();

    // SQL 查询:创建表
    $sql = "CREATE TABLE $table_name (
        id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
        url VARCHAR(255) NOT NULL,
        title VARCHAR(255) NOT NULL,
        description TEXT,
        image VARCHAR(255),
        cache_time DATETIME DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        UNIQUE KEY url (url)
    ) $charset_collate;";

    // 如果表不存在,则创建表
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);
}

// 插件激活时创建数据表
register_activation_hook(__FILE__, 'custom_card_create_db_table');

// 注册短代码 [custom_card]
function custom_card_shortcode($atts) {
    // 获取 URL 参数
    $atts = shortcode_atts(array(
        'url' => '',  // 默认情况下,url 为空
    ), $atts, 'custom_card');

    // 确保 URL 不为空
    if (empty($atts['url'])) {
        return '<p>请输入有效的 URL。</p>';
    }

    // 调用函数从 URL 获取数据并生成 HTML 卡片
    return custom_card_fetch_data($atts['url']);
}
add_shortcode('custom_card', 'custom_card_shortcode');

// 获取网页数据并生成卡片,带缓存机制
function custom_card_fetch_data($url) {
    global $wpdb;
    $table_name = $wpdb->prefix . 'custom_card_cache';

    // 检查数据库中是否已经缓存了该 URL 的数据
    $cached_data = $wpdb->get_row(
        $wpdb->prepare("SELECT * FROM $table_name WHERE url = %s ORDER BY cache_time DESC LIMIT 1", $url)
    );

    // 如果有缓存数据,且缓存未过期(例如 1 天内缓存有效)
    if ($cached_data && (strtotime($cached_data->cache_time) > strtotime('-1 day'))) {
        // 返回缓存的数据
        return custom_card_generate_html($cached_data->title, $cached_data->description, $cached_data->image, $url);
    }

    // 如果没有缓存数据,或缓存已过期,则抓取新的网页数据
    $response = wp_remote_get($url);

    if (is_wp_error($response)) {
        return '<p>无法获取内容,请检查 URL 是否有效。</p>';
    }

    // 获取网页的 body 内容
    $body = wp_remote_retrieve_body($response);

    // 从网页中提取所需的内容
    $title = custom_card_extract_title($body);
    $description = custom_card_extract_description($body);
    $image = custom_card_extract_image($body);

    // 如果没有提取到标题或描述,则返回错误信息
    if (empty($title) || empty($description)) {
        return '<p>未能正确提取网页内容。</p>';
    }

    // 将抓取的数据插入到数据库中(或更新缓存)
    $wpdb->replace(
        $table_name, 
        array(
            'url' => $url,
            'title' => $title,
            'description' => $description,
            'image' => $image,
            'cache_time' => current_time('mysql'),
        ),
        array('%s', '%s', '%s', '%s', '%s')  // 参数格式
    );

    // 生成并返回卡片 HTML
    return custom_card_generate_html($title, $description, $image, $url);
}

// 提取网页的标题
function custom_card_extract_title($html) {
    preg_match('/<title>(.*?)<\/title>/', $html, $matches);
    return $matches[1] ?? ''; // 如果没有找到标题,则返回空字符串
}

// 提取网页的描述(通常为 meta 标签中的内容)
function custom_card_extract_description($html) {
    preg_match('/<meta name="description" content="(.*?)"/', $html, $matches);
    return $matches[1] ?? ''; // 如果没有找到描述,则返回空字符串
}

// 提取网页的图片(通常为 og:image 标签中的内容)
function custom_card_extract_image($html) {
    preg_match('/<meta property="og:image" content="(.*?)"/', $html, $matches);
    return $matches[1] ?? ''; // 如果没有找到图片,则返回空字符串
}

// 生成卡片的 HTML 代码
function custom_card_generate_html($title, $description, $image, $url) {
    $card_html = '<div class="custom-card">';
    
    // 图片部分
    if ($image) {
        $card_html .= '<img src="' . esc_url($image) . '" alt="' . esc_attr($title) . '" class="custom-card-image">';
    }

    // 内容部分
    $card_html .= '<div class="custom-card-content">';
    $card_html .= '<h3 class="custom-card-title">' . esc_html($title) . '</h3>';
    $card_html .= '<p class="custom-card-description">' . esc_html($description) . '</p>';
    $card_html .= '<a href="' . esc_url($url) . '" target="_blank" class="custom-card-link">查看详情</a>';
    $card_html .= '</div></div>';

    return $card_html;
}

// 加载插件样式
function custom_card_enqueue_styles() {
    wp_enqueue_style('custom-card-style', plugin_dir_url(__FILE__) . 'style.css');
}
add_action('wp_enqueue_scripts', 'custom_card_enqueue_styles');

// 加载插件脚本
function custom_card_enqueue_scripts() {
    wp_enqueue_script('custom-card-script', plugin_dir_url(__FILE__) . 'script.js', array('jquery'), '1.0', true);
}
add_action('wp_enqueue_scripts', 'custom_card_enqueue_scripts');

script.js代码

document.addEventListener('DOMContentLoaded', function () {
// 获取所有的卡片元素
const cards = document.querySelectorAll('.custom-card');

// 遍历每个卡片并添加点击事件
cards.forEach(card => {
    card.addEventListener('click', function () {
        // 当点击卡片时,打开卡片链接
        const link = this.querySelector('a.custom-card-link');
        if (link) {
            window.open(link.href, '_blank');
        }
    });
});

// 懒加载图片
const lazyImages = document.querySelectorAll('.custom-card-image[data-src]');
const imageObserver = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const image = entry.target;
            image.src = image.dataset.src;
            image.removeAttribute('data-src'); // 移除 data-src 属性,避免重复加载
            observer.unobserve(image); // 停止观察
        }
    });
}, {
    threshold: 0.1 // 当图片进入视窗的 10% 时开始加载
});

lazyImages.forEach(image => {
    imageObserver.observe(image);
});

});

script.css代码

/* 卡片容器样式 */
.custom-card {
    display: flex;
    border: 1px solid #ddd;
    border-radius: 8px;
    overflow: hidden;
    margin: 20px 0;
    background-color: #fff;
    transition: transform 0.3s ease-in-out;
}

/* 图片样式 */
.custom-card-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    margin-right: 15px;
}

/* 内容部分样式 */
.custom-card-content {
    padding: 10px;
    flex: 1;
}

.custom-card-title {
    font-size: 18px;
    font-weight: bold;
    margin-bottom: 10px;
}

.custom-card-description {
    font-size: 14px;
    color: #555;
}

.custom-card-link {
    display: inline-block;
    margin-top: 10px;
    color: #0073aa;
    text-decoration: none;
}

.custom-card-link:hover {
    text-decoration: underline;
}

/* 卡片悬浮效果 */
.custom-card:hover {
    transform: translateY(-5px);
}


手机观看扫描下方微信小程序二维码


知识共享许可协议本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。

相关推荐

暂无评论

目录展开