dynamedia / posts-plugin
帖子发布插件
Requires
- php: >=7.2
- composer/installers: ~1.0
- october/backend: >=2.1.19
- october/system: >=2.1.19
- rainlab/pages-plugin: ~1.0
- rainlab/translate-plugin: >=1.9.3 <2.0.0
- spatie/schema-org: ^3.4
This package is auto-updated.
Last update: 2024-09-29 05:50:05 UTC
README
此插件提供撰写帖子(博客文章、新闻文章等)的功能。为此,您将需要包含相关插件组件的几个CMS页面。
为了正确地将此插件集成到您的网站中,您可能希望能够显示帖子的内容,并有一种方式可以根据不同的标准列出帖子,例如按发布日期或相关类别、标签或作者。
在https://github.com/Dynamedia/oc-posts-demo-theme处提供了演示主题,这对于希望快速开始的开发者来说是一个有用的资源。此外,还可以访问https://playground.posts-plugin.dynamedia.uk上的实时交互式演示网站。
安装后
后端用户将创建一个“个人资料”,其中可以输入附加信息。每个用户将生成一个可配置的用户名,该用户名在前端使用,以避免暴露登录名。
配置
大多数插件配置可以在“后端设置”区域中的“Dynamedia帖子设置”部分找到。一些设置是绝对的,而另一些则允许您定义一个默认值,该默认值将被帖子或帖子组(类别、标签)继承或覆盖。
发布者选项卡
这些设置有助于搜索引擎优化,并且对于插件与主题一起生成正确输出是必需的。
-
发布者名称 - 应包含发布内容的组织或个人名称,例如 Dynamedia Limited。
-
发布者类型 - 下拉菜单选择个人或组织。
-
发布者URL - 发布者的URL。这可能或可能不是当前网站URL。
-
发布者Logo - 发布者的Logo。
帖子选项卡
本部分用于配置用于显示帖子内容的CMS页面。
-
帖子显示页面(带类别) - 选择包含displayPost组件的CMS页面。建议选择一个也附加了displayCategory组件的页面,尽管这不是必需的,如果您更喜欢/categories & /posts URL结构。
-
帖子显示页面(无类别) - 选择不遵循上述建议时的displayPost组件所在的CMS页面。您可以单独选择CMS页面来显示未分类的帖子,但建议不要这样做。
有关更多信息,请参阅本文档的组件部分。
类别选项卡
本部分用于配置用于显示类别内容和相关帖子列表的CMS页面。
-
类别显示页面 - 选择包含displayCategory组件的CMS页面。如上所述,建议在同一CMS页面中使用displayPost和displayCategory组件。
-
默认帖子排序顺序 - 选择类别中帖子的默认排序顺序。此值可以在每个单个类别的设置部分中覆盖。
-
列出子分类的文章 - 选择是否应包含子分类中的文章。此值可以在每个单独的分类设置部分中重写。
-
每页文章数 - 用于选择每页应显示的文章数量。此值可以在每个单独的分类设置部分中重写。此下拉菜单的值来自 config/config.php。
标签选项卡
本节用于配置用于显示标签内容和相关文章列表的CMS页面。
-
默认文章排序顺序 - 定义类别中文章的默认排序顺序。此值可以在每个单独的分类设置部分中重写。
-
每页文章数 - 用于选择每页应显示的文章数量。此值可以在每个单独的分类设置部分中重写。此下拉菜单的值来自 config/config.php。
用户选项卡
本节用于配置用于显示用户资料和相关文章列表的CMS页面。
-
默认文章排序顺序 - 定义用户文章的默认排序顺序。此值可以在每个单独的分类设置部分中重写。
-
每页文章数 - 用于选择每页应显示的文章数量。此下拉菜单的值来自 config/config.php。
CMS布局选项卡
该插件允许即时更改主题布局,因此您不必限制每个CMS页面(文章、分类、标签)仅使用一个布局文件。这为设计主题提供了极大的灵活性。一个示例用例是当设计一个涵盖多个不同主题的大型网站时。您可能希望不同部分有不同的外观。当然,本节中可用的选项将完全取决于主题中提供的布局数量。
-
默认文章布局 - 对于未指定单独布局的分类或文章,这是默认值。文章可以指定布局文件或从其主分类继承。
-
默认分类布局 - 对于未指定单独布局的分类,这是默认值。
-
默认标签布局 - 对于未指定单独布局的标签,这是默认值。
组件
该插件提供了几个组件。
displayPost
此组件用于显示文章的内容。该组件没有可配置选项,并且应存在于包含两个可用URL参数之一的CMS页面上。
这两个可用参数最终都会从文章别名获取文章,但提供了几个参数以帮助定义理想的URL结构。
:postsPostSlug 仅表示别名,例如 /my-post
:postsFullPath* 表示分类和文章,例如 /a-category/a-subcategory/my-post,尽管当与displayCategory组件一起使用时,这也可能匹配分类别名或没有分类的文章。
以下示例代码演示了如何实现此组件,作为具有完整分类路径作为URL一部分的独立CMS页面上的组件。
title = "Posts Page"
url = "/posts/:postsCategoryPath*/:postsPostSlug"
[displayPost]
==
{% component 'displayPost' %}
如果您想在不显示分类的情况下实现,可以这样做:
title = "Posts Page Without Category"
url = "/posts/:postsPostSlug"
[displayPost]
==
{% component 'displayPost' %}
displayPost将注入以下变量:
-
post - 文章对象
-
paginator - 用于多页文章的LengthAwarePaginator
displayCategory
此组件用于显示分类及其相关文章列表的内容。该组件没有可配置选项,并且应存在于包含两个可用URL参数之一的CMS页面上。
:postsCategorySlug 表示分类别名。
:postsCategoryPath* 表示路径中的分类部分,例如 /a-category 或 /a-category/a-sub-category
:postsFullPath* 表示分类和文章,例如 /a-category/a-subcategory/my-post,尽管当与displayCategory组件一起使用时,这也可能匹配分类别名或没有分类的文章。
以下示例代码演示了如何实现此组件,作为具有完整分类路径作为URL一部分的独立CMS页面上的组件。
title = "Category Display Page"
url = "/posts/category/:postsCategoryPath*"
[displayCategory]
includeSubcategories = 1
postsPerPage = 10
==
{% component 'displayCategory' %}
或者仅使用分类别名,但没有完整路径
title = "Category Display Page"
url = "/posts/category/:postsCategorySlug"
[displayCategory]
includeSubcategories = 1
postsPerPage = 10
==
{% component 'displayCategory' %}
displayCategory将注入以下变量:
-
category - 分类对象。
-
posts - 包含帖子项的 LengthAwarePaginator。
合并 displayPost 和 displayCategory。
建议为帖子显示页面和分类显示页面使用相同的URL。插件处理解决URL冲突时的逻辑,允许使用语义URL,甚至可以从项目根目录开始。
您可以通过在URL中使用 :postsFullPath* 参数来实现这一点。
在这种情况下,您可以为两个页面使用以下代码片段。
帖子显示页面。
title = "Post Display Page"
url = "/:postsFullPath*"
layout = "default"
meta_title = "Post Display Page"
is_hidden = 0
[displayPost]
==
{% component 'displayPost' %}
分类显示页面
title = "Category Display Page"
url = "/:postsFullPath*"
layout = "default"
meta_title = "Category Display Page"
is_hidden = 0
[displayCategory]
includeSubcategories = 1
postsPerPage = 11
noPostsMessage = "No posts found"
sortOrder = "published_at desc"
==
{% component 'displayCategory' %}
这将匹配,例如
https://example.org/my-uncategorized-post
https://example.org/a-category
https://example.org/a-category/my-categorized-post
但是,它不会匹配
https://example.org/my-static-page
当然,您不必从URL根目录实现,也可以轻松使用 url = '/posts/:postsFullPath*\'
注意:URL
上述组件都用于URL生成。当您创建了首选的结构并在插件设置中选择了相关页面时,帖子对象和分类对象将具有可用的url属性。您可以在 {{ post.url }} 和 {{ category.url }} 中访问它们。
如果您的分类结构发生变化,用户将始终被重定向到正确的URL。
例如,如果您有一个slug为 'my-interesting-post' 的帖子,且它没有分类,它的URL可能是 https://example.org/posts/my-interesting-post
您可以在以后添加一个名为 'my-stuff' 的分类,并选择添加该帖子,使其URL现在变为 https://example.org/posts/my-stuff/my-interesting-post
在这种情况下,https://example.org/posts/my-interesting-post 将重定向到 https://example.org/posts/my-stuff/my-interesting-post。
displayTag
此组件用于显示标签的内容及其相关帖子列表。该组件没有可配置的选项。
标签将通过 :postsTagSlug URL参数进行识别。
示例实现
title = "Tags"
url = "/tags/:postsTagSlug"
[displayTag]
postsPerPage = 10
==
{% component 'displayTag' %}
displayCategory将注入以下变量:
-
tag - 标签对象。
-
posts - 包含帖子项的 LengthAwarePaginator。
displayUser
此组件负责显示用户个人资料和该用户的帖子。
用户将通过 :postsUsername URL参数进行识别。
请注意,用户名 不是 后端登录名。用户名将由Profile模型为每个用户生成,但可以在用户管理设置中更改。
示例实现
title = "User Posts"
url = "/user/:postsUsername"
[displayUser]
==
{% component 'displayUser' %}
displayCategory将注入以下变量:
-
user - 后端用户对象。
-
posts - 包含帖子项的 LengthAwarePaginator。
searchPosts
此组件负责显示帖子的搜索结果。
搜索查询应通过 q URL参数传递,例如
https://example.org/search?q=keyword
此组件需要一些配置
-
postsLimit - 可以获取的帖子总数。
-
postsPerPage - 当此值大于 postsLimit 或 postsLimit 未设置时,结果将分页显示。
-
sortOrder - 下拉菜单,用于选择返回结果的顺序。
示例实现
title = "Search"
url = "/search"
[searchPosts]
postsPerPage = 10
==
{% component 'searchPosts' %}
searchPosts将注入以下变量
-
searchQuery - 搜索字符串。
-
posts - 包含帖子项的 LengthAwarePaginator。
listPosts
此组件负责显示自定义帖子列表。
此组件需要一些配置
-
categoryFilter - 选择分类的帖子。
-
includeSubcategories - 包含所选分类的子分类中的帖子。
-
tagFilter - 带有所选标签的帖子。
-
postIds - 仅返回具有给定ID的帖子,按指定顺序排列。
-
notPostIds - 排除具有给定ID的帖子。
-
notCategoryIds - 排除具有给定ID的分类中的帖子。
-
notTagIds - 排除具有与给定ID匹配的标签的帖子。
-
postsLimit - 可以获取的帖子总数。
-
postsPerPage - 当此值大于 postsLimit 或 postsLimit 未设置时,结果将分页显示。
-
sortOrder - 选择返回结果的顺序。
示例实现,可能适用于网站主页
title = "Home"
url = "/"
[listPosts featuredPosts]
postIds = "1,2"
postsLimit = 2
postsPerPage = 2
sortOrder = "published_at desc"
[listPosts latestPosts]
notPostIds = "1,2"
notCategoryIds = 4
notTagIds = 1
postsLimit = 5
postsPerPage = 5
sortOrder = "published_at desc"
==
<div class="content">
<div class="row">
<div class="col-12">
<h2 class="mt-4 mb-4">Featured Posts</h2>
{% component 'featuredPosts' %}
<h2 class="mt-4 mb-4">Latest posts</h2>
{% component 'latestPosts' %}
</div>
</div>
</div>
listPosts将注入以下变量
- posts - 包含帖子项的 LengthAwarePaginator。
对象的解剖结构
以下部分描述了由“帖子插件”生成的对象可用的属性
帖子
模型 Dynamedia\Posts\Post
表 dynamedia_posts_posts
帖子属性
* 追加属性
为了帮助开发,以下提供了示例dd转储,用于数组属性。
body属性
^ array:4 [▼
0 => array:2 [▼
"block" => array:5 [▼
"sId" => "first"
"image" => array:4 [▼
"alt" => ""
"class" => ""
"default" => ""
"image_style" => "inline-left"
]
"content" => "<p>Construct your posts using as many or as few blocks as you like!</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incidid ▶"
"heading" => "A content block"
"in_contents" => "1"
]
"_group" => "section"
]
1 => array:2 [▶]
2 => array:1 [▼
"_group" => "pagebreak"
]
3 => array:2 [▼
"block" => array:5 [▼
"sId" => "third"
"image" => array:4 [▶]
"content" => "<p>Posts can, if you want, be written over multiple pages. It's all handled internally so just add a pagebreak block. Easy!</p>"
"heading" => "New page content"
"in_contents" => "1"
]
"_group" => "section"
]
]
pages属性
这是从body派生出来的,通过分页符将body部分分开
^ array:2 [▼
0 => array:2 [▼
0 => array:3 [▼
"block" => array:5 [▼
"sId" => "first"
"image" => array:4 [▶]
"content" => "<p>Construct your posts using as many or as few blocks as you like!</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incidid ▶"
"heading" => "A content block"
"in_contents" => "1"
]
"_group" => "section"
"page" => 1
]
1 => array:3 [▶]
]
1 => array:1 [▼
0 => array:3 [▼
"block" => array:5 [▼
"sId" => "third"
"image" => array:4 [▶]
"content" => "<p>Posts can, if you want, be written over multiple pages. It's all handled internally so just add a pagebreak block. Easy!</p>"
"heading" => "New page content"
"in_contents" => "1"
]
"_group" => "section"
"page" => 2
]
]
]
images属性
这包含主要图像,与帖子正文图像分开。应使用| media twig过滤器来使用URL。
^ array:3 [▼
"list" => array:3 [▼
"alt" => "The List Image"
"class" => "optional-class"
"default" => "/list-image.png"
]
"banner" => array:3 [▼
"alt" => "The Banner Image"
"class" => "optional-class"
"default" => "/banner-image.png"
]
"social" => array:2 [▼
"twitter" => "/twitter-image.png"
"facebook" => "/facebook-image.png"
]
]
contents_list属性
在_contents设置为true的帖子部分
^ array:3 [▼
0 => array:4 [▼
"title" => "A content block"
"page" => 1
"url" => "http://octobercms.local/uncategorized/first-blog-post#first"
0 => "contents_list"
]
1 => array:4 [▼
"title" => "Another content block"
"page" => 1
"url" => "http://octobercms.local/uncategorized/first-blog-post#second"
0 => "contents_list"
]
2 => array:4 [▼
"title" => "New page content"
"page" => 2
"url" => "http://octobercms.local/uncategorized/first-blog-post?page=2#third"
0 => "contents_list"
]
]
帖子关系
分类
模型 Dynamedia\Posts\Category
表 dynamedia_posts_categories
分类属性
* 追加属性
分类关系
标签
模型 Dynamedia\Posts\Tag
表 dynamedia_posts_tags
标签属性
* 追加属性
标签关系
个人资料
模型 Dynamedia\Posts\Profile
表 dynamedia_posts_profiles
个人资料属性
* 追加属性
个人资料关系
注意:此文档将定期更新和改进。有关更多信息,请参阅https://posts-plugin.dynamedia.uk。