johnfmorton / craft-entry-editor-links
为您的条目作者创建条目编辑链接,兼容静态缓存网站。
Requires
- php: >=8.0.2
- craftcms/cms: ^4.4.7.1|^5.0
Requires (Dev)
- craftcms/ecs: dev-main
- craftcms/phpstan: dev-main
README
条目编辑链接 是 Craft CMS 的插件,版本 4 或版本 5。它帮助在您站点的前端页面为条目作者创建“编辑此条目”链接。它设计用于与静态缓存网站很好地协同工作,如使用 FastCGI Cache 的网站。
查看概述部分获取更多信息。
下面的截图展示了我登录到 Craft CMS 时我的博客看起来是什么样子。铅笔图标是一个链接,可以让我快速跳转到控制面板中的条目编辑页面。
要求
此插件需要 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
属性。
插件功能
该插件执行以下两项操作:
- 它提供了一个端点,该端点期望一个条目 ID,并返回一个包含条目编辑 URL 的 JSON 对象。
- 它还提供了一个 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;
}