johnfmorton/craft-entry-editor-links

为您的条目作者创建条目编辑链接,兼容静态缓存网站。

5.0.0 2024-03-28 18:41 UTC

This package is auto-updated.

Last update: 2024-09-28 19:58:25 UTC


README

条目编辑链接 是 Craft CMS 的插件,版本 4 或版本 5。它帮助在您站点的前端页面为条目作者创建“编辑此条目”链接。它设计用于与静态缓存网站很好地协同工作,如使用 FastCGI Cache 的网站。

查看概述部分获取更多信息。

下面的截图展示了我登录到 Craft CMS 时我的博客看起来是什么样子。铅笔图标是一个链接,可以让我快速跳转到控制面板中的条目编辑页面。

screenshot.png

要求

此插件需要 Craft CMS 4.4.7.1 或更高版本,以及 PHP 8.0.2 或更高版本。它也与 Craft CMS 5.x 兼容。

安装

您可以从插件商店或使用 Composer 安装此插件。

从插件商店

转到项目控制面板中的插件商店,搜索“entry-editor-links”,然后点击“安装”。

使用 Composer

打开您的终端并运行以下命令

# go to the project directory
cd /path/to/my-project.test

# tell Composer to load the plugin
composer require johnfmorton/craft-entry-editor-links

# tell Craft to install the plugin
./craft plugin/install entry-editor-links

概述

此插件帮助在 Craft CMS 控制面板内部生成条目编辑页面的链接。虽然使用 getCpEditUrl 函数在 Twig 模板中创建此功能很容易,但使用此函数在静态缓存页面上可能会将条目的编辑 URL 暴露给没有编辑条目权限的用户。

此插件通过创建一个 API 端点来解决这个问题,该端点返回条目的编辑 URL,仅限于拥有编辑条目权限的已登录 Craft 用户。然后您可以使用 JavaScript 在 DOM 中渲染编辑链接。下面的使用插件部分提供了完成此操作的示例 JavaScript 代码。

编辑按钮应在网站的页面上渲染,而不是在控制面板内的预览窗格中显示条目时。此插件提供了一个 Twig 函数,isFrontEndPageView(),可以用来确定页面是否正在网站上渲染。这允许您仅在网站的页面上渲染 data-edit-link 属性。

插件功能

该插件执行以下两项操作:

  1. 它提供了一个端点,该端点期望一个条目 ID,并返回一个包含条目编辑 URL 的 JSON 对象。
  2. 它还提供了一个 Twig 函数,isFrontEndPageView(),以确定页面是否正在网站上渲染。这是为了防止在用户在控制面板中编辑条目并打开预览窗格时,或者使用预览令牌在网站上渲染条目时显示编辑链接。

使用插件

第一步是在模板中的元素上渲染 data-edit-link 属性,以显示您希望能够编辑的条目的条目 ID。

通过将属性包裹在检查页面是否在网站上渲染的 isFrontEndPageView 条件中来完成此操作。

{% if isFrontEndPageView() %}data-edit-link="{{ entry.id }}"{% endif %}

例如,如果您有一个条目列表,您可以将 data-edit-link 属性添加到每个条目周围的元素。您可以将此数据属性放在每个条目周围的 article 元素上。

<article {% if isFrontEndPageView() and (entry is defined) %} data-edit-link="{{ entry.id }}"{% endif %}>
    <h2>{{ entry.title }}</h2>
    <p>{{ entry.body }}</p>
</article>

然后,在页面加载后,查找任何data-edit-link属性的实例,并通过查询插件的API端点来获取条目的编辑URL。如果用户已登录并且有编辑条目的权限,插件将返回条目的编辑URL。然后您可以在条目的DOM中添加一个指向编辑页面的链接。

以下是一个使用JavaScript实现此功能的简单示例。您可以将其添加到您网站前端加载的JavaScript文件中。您可能需要自定义编辑链接的样式和文本,以匹配您网站的设计。

window.addEventListener('load', () => {
    // get all the elements with a data-attribute of 'edit-link'
    const editLinks = document.querySelectorAll('[data-edit-link]');
    // loop through the divs
    editLinks.forEach((editLink) => {
        // get the id from the data attribute
        const id = editLink.getAttribute('data-edit-link');
        // confirm the id is a number
        if (id && parseInt(id)) {
            // make a request to the plugin's API endpoint
            fetch('/actions/entry-editor-links/entry-processor/cp-link?id=' + id)
                .then((response) => {
                    // if the response is ok, return the json
                    if (response.ok) {
                        return response.json();
                    }
                    // otherwise, return an empty object
                    return null;
                })
                .then((data) => {
                    // data object will look like this: : { success: true, message: URL } or : { success: false, message: error message }
                    // if the data has success==true and a message, add a link to the edit page
                    if (data.success && data.message) {
                        // create an anchor element
                        const link = document.createElement('a');
                        // set the href attribute
                        link.setAttribute('href', data.message);
                        // set the text
                        link.innerText = 'Edit 📝';
                        // add some styles to the edit button
                        link.style.backgroundColor = '#f1f1f1';
                        link.style.color = '#333';
                        link.style.borderRadius = '5px';
                        link.style.border = '1px solid #ccc';
                        link.style.textDecoration = 'none';
                        link.style.boxShadow = '0 0 10px rgba(0,0,0,0.1)';
                        link.style.zIndex = '9999';
                        link.style.fontFamily = 'Arial, sans-serif';
                        link.style.fontSize = '14px';
                        // open the link in a new tab
                        link.setAttribute('target', '_blank');
                        // append the link to the div
                        editLink.appendChild(link);
                    }
                })
                .catch((error) => {
                    // log any errors
                    console.error(error);
                }
            );
        }
    })
});

使用FastCGI缓存插件

如果您使用FastCGI缓存,需要添加一条规则以防止插件的API端点被缓存。这是因为插件API端点返回的数据取决于用户是否已登录并且是否有权限编辑条目。如果端点被缓存,则编辑链接将显示给没有编辑权限的用户。

以下是Apache和Nginx服务器中可能看起来像的规则示例。您的服务器可能需要不同的规则,但这应该能为您提供如何排除^/actions/entry-editor-links URL不被缓存的方法。

使用Apache服务器的.htaccess文件

# Don't cache the Entry Editor Links API endpoint
# Uses the mod_headers Apache module
<IfModule mod_headers.c>
    <LocationMatch "^/actions/entry-editor-links">
        Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0"
    </LocationMatch>
</IfModule>

使用Nginx服务器的nginx.conf文件

# Don't cache the Entry Editor Links API endpoint
location ~ ^/actions/entry-editor-links {
    set $nocache 1;
}