20 | <% end_if %>
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: 'BUG '
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 | - Maintenance on this module is a shared effort of those who use it
3 | - To contribute improvements to the code, ensure you raise a pull request and discuss with the module maintainers
4 | - Please follow the SilverStripe [code contribution guidelines](https://docs.silverstripe.org/en/contributing/code/) and [Module Standard](https://docs.silverstripe.org/en/developer_guides/extending/modules/#module-standard)
5 | - Supply documentation that followS the [GitHub Flavored Markdown](https://help.github.com/articles/markdown-basics/) conventions
6 | - When having discussions about this module in issues or pull request please adhere to the [SilverStripe Community Code of Conduct](https://docs.silverstripe.org/en/contributing/code_of_conduct/)
7 |
8 |
9 | ## Contributor license agreement
10 | By supplying code to this module in patches, tickets and pull requests, you agree to assign copyright
11 | of that code to Dynamic, on the condition that these code changes are released under the
12 | same BSD license as the original module. We ask for this so that the ownership in the license is clear
13 | and unambiguous. By releasing this code under a permissive license such as BSD, this copyright assignment
14 | won't prevent you from using the code in any way you see fit.
--------------------------------------------------------------------------------
/phpstan-baseline.neon:
--------------------------------------------------------------------------------
1 | parameters:
2 | ignoreErrors:
3 | -
4 | message: "#^Call to an undefined static method SilverStripe\\\\Blog\\\\Model\\\\BlogPost\\:\\:get\\(\\)\\.$#"
5 | count: 1
6 | path: src/Elements/ElementBlogOverview.php
7 |
8 | -
9 | message: "#^Call to an undefined static method SilverStripe\\\\Blog\\\\Model\\\\Blog\\:\\:get\\(\\)\\.$#"
10 | count: 2
11 | path: src/Elements/ElementBlogPosts.php
12 |
13 | -
14 | message: "#^Call to an undefined static method SilverStripe\\\\Blog\\\\Model\\\\BlogPost\\:\\:get\\(\\)\\.$#"
15 | count: 1
16 | path: src/Elements/ElementBlogPosts.php
17 |
18 | -
19 | message: "#^Class Page not found\\.$#"
20 | count: 1
21 | path: tests/Elements/ElementBlogOverviewFunctionalTest.php
22 |
23 | -
24 | message: "#^Instantiated class PageController not found\\.$#"
25 | count: 1
26 | path: tests/Elements/ElementBlogOverviewFunctionalTest.php
27 |
28 | -
29 | message: "#^Class Page not found\\.$#"
30 | count: 1
31 | path: tests/Elements/ElementBlogOverviewTest.php
32 |
33 | -
34 | message: "#^Call to an undefined static method SilverStripe\\\\Blog\\\\Model\\\\BlogPost\\:\\:get\\(\\)\\.$#"
35 | count: 2
36 | path: tests/Elements/ElementBlogPostsTest.php
37 |
38 | -
39 | message: "#^Call to an undefined static method SilverStripe\\\\Blog\\\\Model\\\\BlogPost\\:\\:get\\(\\)\\.$#"
40 | count: 1
41 | path: tests/Fake/Page.php
42 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017, Dynamic, Inc.
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5 |
6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 |
8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 |
10 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11 |
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13 |
--------------------------------------------------------------------------------
/templates/Dynamic/Elements/Blog/Elements/ElementBlogOverview.ss:
--------------------------------------------------------------------------------
1 |
2 | <% if $ShowTitle %>
3 |
<%t SilverStripe\\Blog\\Model\\Blog.NoPosts 'There are no posts' %>
33 | <% end_if %>
34 |
35 |
36 | <% if $ShowPagination && $PaginatedList.Exists %>
37 |
42 | <% end_if %>
43 |
44 | <% if $ShowWidgets && $SideBarView %>
45 |
48 | <% end_if %>
49 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dynamic/silverstripe-elemental-blog",
3 | "description": "Show recent posts from a featured blog.",
4 | "license": "BSD-3-Clause",
5 | "type": "silverstripe-vendormodule",
6 | "keywords": [
7 | "silverstripe",
8 | "blog",
9 | "element",
10 | "block"
11 | ],
12 | "authors": [
13 | {
14 | "name": "Dynamic",
15 | "email": "dev@dynamicagency.com",
16 | "homepage": "https://www.dynamicagency.com"
17 | }
18 | ],
19 | "funding": [
20 | {
21 | "type": "github",
22 | "url": "https://github.com/sponsors/dynamic"
23 | }
24 | ],
25 | "require": {
26 | "php": "^8.3",
27 | "dnadesign/silverstripe-elemental": "^6.0",
28 | "sheadawson/silverstripe-dependentdropdownfield": "^4.0",
29 | "silverstripe/blog": "^5.0"
30 | },
31 | "require-dev": {
32 | "silverstripe/recipe-testing": "^4",
33 | "squizlabs/php_codesniffer": "^3.0",
34 | "silverstripe/standards": "^1"
35 | },
36 | "minimum-stability": "dev",
37 | "prefer-stable": true,
38 | "autoload": {
39 | "psr-4": {
40 | "Dynamic\\Elements\\Blog\\": "src/",
41 | "Dynamic\\Elements\\Blog\\Tests\\": "tests/"
42 | }
43 | },
44 | "config": {
45 | "allow-plugins": {
46 | "composer/installers": true,
47 | "silverstripe/vendor-plugin": true,
48 | "silverstripe/recipe-plugin": true
49 | },
50 | "process-timeout": 600
51 | },
52 | "scripts": {
53 | "lint": "vendor/bin/phpcs src/ tests/",
54 | "lint-clean": "vendor/bin/phpcbf src/ tests/"
55 | },
56 | "extra": {
57 | "branch-alias": {
58 | "dev-master": "4.0.x-dev"
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/Elements/ElementBlogPagination.php:
--------------------------------------------------------------------------------
1 | 'Int',
43 | 'Content' => 'HTMLText',
44 | ];
45 |
46 | /**
47 | * @var array
48 | */
49 | private static array $has_one = [
50 | 'Blog' => Blog::class,
51 | 'Category' => BlogCategory::class,
52 | ];
53 |
54 | /**
55 | * @var array
56 | */
57 | private static array $defaults = [
58 | 'Limit' => 3,
59 | ];
60 |
61 | /**
62 | * @return FieldList
63 | */
64 | public function getCMSFields()
65 | {
66 | $this->beforeUpdateCMSFields(function (FieldList $fields) {
67 | $fields->dataFieldByName('Content')
68 | ->setRows(8);
69 |
70 | $fields->dataFieldByName('Limit')
71 | ->setTitle(_t(__CLASS__ . 'LimitLabel', 'Posts to show'));
72 |
73 | if (class_exists(Blog::class)) {
74 | $fields->insertBefore(
75 | 'Limit',
76 | $fields->dataFieldByName('BlogID')
77 | ->setTitle(_t(__CLASS__ . 'BlogLabel', 'Featured Blog'))
78 | ->setEmptyString('')
79 | );
80 |
81 | $dataSource = function ($val) {
82 | if ($val) {
83 | $blog = Blog::get()->byID($val);
84 | if ($blog) {
85 | return $blog->Categories()->map('ID', 'Title');
86 | }
87 | return [];
88 | }
89 | return [];
90 | };
91 |
92 | $fields->insertAfter(
93 | 'BlogID',
94 | DependentDropdownField::create('CategoryID', _t(
95 | __CLASS__ . 'CategoryLabel',
96 | 'Category'
97 | ), $dataSource)
98 | ->setDepends($fields->dataFieldByName('BlogID'))
99 | ->setHasEmptyDefault(true)
100 | ->setEmptyString('')
101 | );
102 | }
103 | });
104 |
105 | return parent::getCMSFields();
106 | }
107 |
108 | /**
109 | * @return ArrayList|DataList
110 | */
111 | public function getPostsList()
112 | {
113 | /** @var ArrayList $posts */
114 | $posts = ArrayList::create();
115 |
116 | if ($this->BlogID && $this->CategoryID && $category = BlogCategory::get()->byID($this->CategoryID)) {
117 | $posts = $category->BlogPosts();
118 | } elseif ($this->BlogID && $blog = Blog::get()->byID($this->BlogID)) {
119 | $posts = $blog->getBlogPosts();
120 | } else {
121 | $posts = BlogPost::get()->sort('PublishDate DESC');
122 | }
123 |
124 | $this->extend('updateGetPostsList', $posts);
125 |
126 | return $posts->limit($this->Limit);
127 | }
128 |
129 |
130 | /**
131 | * @return DBHTMLText
132 | */
133 | public function getSummary()
134 | {
135 | $count = $this->getPostsList()->count();
136 | $label = _t(
137 | BlogPost::class . '.PLURALS',
138 | 'A Blog Post|{count} Blog Posts',
139 | [ 'count' => $count ]
140 | );
141 | return DBField::create_field('HTMLText', $label)->Summary(20);
142 | }
143 |
144 | /**
145 | * @return array
146 | */
147 | protected function provideBlockSchema()
148 | {
149 | $blockSchema = parent::provideBlockSchema();
150 | $blockSchema['content'] = $this->getSummary();
151 | return $blockSchema;
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SilverStripe Elemental Blog
2 |
3 | Recent Blog Posts Element for the SilverStripe Elemental module.
4 |
5 | 
6 | [](https://github.com/sponsors/dynamic)
7 |
8 | [](https://packagist.org/packages/dynamic/silverstripe-elemental-blog)
9 | [](https://packagist.org/packages/dynamic/silverstripe-elemental-blog)
10 | [](https://packagist.org/packages/dynamic/silverstripe-elemental-blog)
11 | [](https://packagist.org/packages/dynamic/silverstripe-elemental-blog)
12 |
13 | ## Requirements
14 |
15 | * SilverStripe ^6
16 | * PHP ^8.1
17 | * silverstripe/blog: ^5.0
18 | * dnadesign/silverstripe-elemental: ^6.0
19 |
20 | ## Installation
21 |
22 | `composer require dynamic/silverstripe-elemental-blog`
23 |
24 | ## Upgrading from version 3.0
25 |
26 | SilverStripe Elemental Blog 4.0 is compatible with SilverStripe 6. Key changes:
27 |
28 | - Updated to SilverStripe CMS 6
29 | - Requires PHP 8.1 or higher
30 | - Updated `silverstripe/blog` to ^5.0 (SS6 compatible)
31 | - Updated `dnadesign/silverstripe-elemental` to ^6.0 (SS6 compatible)
32 | - **Removed widget support** - The SilverStripe widget module is no longer supported in SS6
33 | - `ElementBlogWidgets` block has been removed
34 | - Widget-related configuration options have been removed
35 | - If you were using widget functionality, you will need to migrate to alternative solutions
36 |
37 | For more information about SilverStripe 6, see the [SilverStripe 6 Upgrade Guide](https://docs.silverstripe.org/en/6/upgrading/).
38 |
39 | ## License
40 | See [License](license.md)
41 |
42 | ## Usage
43 |
44 | There are three blocks available for you to use. It is likely that you will not want all of them to be available to
45 | content authors, so it is recommended that you review what the purpose of each block is, and then add the ones you don't
46 | need to `disallowed_elements`.
47 |
48 | The three blocks are:
49 |
50 | * [ElementBlogPosts](#elementblogposts)
51 | * [ElementBlogOverview](#elementblogoverview)
52 | * [ElementBlogPagination](#elementblogpagination)
53 |
54 | ### ElementBlogPosts
55 |
56 | A block to show a list of recent posts by a featured blog. Ideal for home pages or dashboards.
57 |
58 | ### ElementBlogOverview
59 |
60 | The purpose of this block is to replicate the output that was originally being given by the Blog module's `Layout`
61 | template.
62 |
63 | **Including:**
64 |
65 | - Title (including Category/Archive/etc titles)
66 | - Content
67 | - Blog Posts
68 | - Pagination
69 |
70 | 
71 |
72 | You will likely want to override the very basic default template that has been provided, you can do so by overriding the
73 | template found with the namespace `Dynamic\Elements\Blog\Elements\ElementBlogOverview.ss`.
74 |
75 | #### Controlling pagination & widgets for this block
76 |
77 | **Pagination config:**
78 |
79 | * `pagination_field_default`: `1` (pagination is enabled by default)
80 | * `show_pagination_field`: `true` (content authors have the ability to turn pagination on or off)
81 |
82 | With the default configuration, when an author creates a new Overview block, they will be presented with a checkbox
83 | to "Show pagination" (which will be ticked by default). If you do **not** want your authors to be able to disable
84 | pagination, then you can update the `show_pagination_field` config to `false`.
85 |
86 | ```yaml
87 | Dynamic\Elements\Blog\Elements\ElementBlogOverview:
88 | show_pagination_field: false
89 | ```
90 |
91 | If you would like pagination to be turned **off** by default, then you can update the `pagination_field_default` to `0`.
92 |
93 | ```yaml
94 | Dynamic\Elements\Blog\Elements\ElementBlogOverview:
95 | pagination_field_default: 0
96 | ```
97 |
98 | #### Using this block on Page types other than `Blog`
99 |
100 | **Please consider:** While the Overview block does support you using it on other page types, it is primarily designed to
101 | be used on Blog page types. This is because it is `Blog` and `BlogController` that provide the relevant info to this
102 | block.
103 |
104 | Please consider whether you want this block to be available to other page types, and if you don't, you might want to
105 | add this block to `disallowed_elements` on your other page types. EG:
106 |
107 | ```yaml
108 | App\Model\Page\MyPage:
109 | disallowed_elements:
110 | - Dynamic\Elements\Blog\Elements\ElementBlogOverview
111 | ```
112 |
113 | If you do wish this block to be available on other page types, then please review the contents on the class to see how
114 | you can dictate what data should be provided to this block.
115 |
116 | ## ElementBlogPagination
117 |
118 | You might decide that you would like Pagination to be displayed quite separately to the Overview block. This can be
119 | achieved by using `ElementBlogPagination` as a separate block.
120 |
121 | **Please consider:** Like the Overview Block, please consider removing this block from any/all Page types that you do
122 | not want it available on. EG, if you don't want to use it at all, you can disallow it for all pages by default:
123 |
124 | ```yaml
125 | Page:
126 | disallowed_elements:
127 | - Dynamic\Elements\Blog\Elements\ElementBlogPagination
128 | ```
129 |
130 | 
131 |
132 | ## Getting more elements
133 |
134 | See [Elemental modules by Dynamic](https://github.com/orgs/dynamic/repositories?q=elemental&type=all&language=&sort=)
135 |
136 | ## Configuration
137 |
138 | See [SilverStripe Elemental Configuration](https://github.com/dnadesign/silverstripe-elemental#configuration)
139 |
140 | ## Maintainers
141 | * [Dynamic](http://www.dynamicagency.com) ()
142 |
143 | ## Bugtracker
144 | Bugs are tracked in the issues section of this repository. Before submitting an issue please read over
145 | existing issues to ensure yours is unique.
146 |
147 | If the issue does look like a new bug:
148 |
149 | - Create a new issue
150 | - Describe the steps required to reproduce your issue, and the expected outcome. Unit tests, screenshots
151 | and screencasts can help here.
152 | - Describe your environment as detailed as possible: SilverStripe version, Browser, PHP version,
153 | Operating System, any installed SilverStripe modules.
154 |
155 | Please report security issues to the module maintainers directly. Please don't file security issues in the bugtracker.
156 |
157 | ## Development and contribution
158 | If you would like to make contributions to the module please ensure you raise a pull request and discuss with the module maintainers.
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | ## What's Changed
4 | * Docs: Update documentation for Overview block by @chrispenny in https://github.com/dynamic/silverstripe-elemental-blog/pull/40
5 | * MNT: Require PHP ^7.4 or ^8 by @chrispenny in https://github.com/dynamic/silverstripe-elemental-blog/pull/41
6 | * REFACTOR Elemental 5 by @jsirish in https://github.com/dynamic/silverstripe-elemental-blog/pull/43
7 | * REFACTOR update element names by @jsirish in https://github.com/dynamic/silverstripe-elemental-blog/pull/45
8 | * README updates by @jsirish in https://github.com/dynamic/silverstripe-elemental-blog/pull/44
9 |
10 |
11 | **Full Changelog**: https://github.com/dynamic/silverstripe-elemental-blog/compare/2.3.0...3.0.0
12 |
13 | ## What's Changed
14 | * Add new blocks supporting Pagination and Widgets by @chrispenny in #28
15 | ### New Contributors
16 | @chrispenny made their first contribution in #28
17 |
18 | Full Changelog: https://github.com/dynamic/silverstripe-elemental-blog/compare/2.2.0...2.3.0
19 |
20 | ## [2.2.0](https://github.com/dynamic/silverstripe-elemental-blog/tree/2.2.0) (2022-07-15)
21 |
22 | ## What's Changed
23 | * UPDATE workflows ci by @muskie9 in https://github.com/dynamic/silverstripe-elemental-blog/pull/32
24 | * REFACTOR allow PHP 8 and phpunit 9 by @jsirish in https://github.com/dynamic/silverstripe-elemental-blog/pull/31
25 | * BUGFIX Composer - update info by @jsirish in https://github.com/dynamic/silverstripe-elemental-blog/pull/34
26 | * CI remove travis and scrutinizer by @jsirish in https://github.com/dynamic/silverstripe-elemental-blog/pull/35
27 | * ENHANCEMENT Bootstrap template by @jsirish in https://github.com/dynamic/silverstripe-elemental-blog/pull/37
28 |
29 |
30 | **Full Changelog**: https://github.com/dynamic/silverstripe-elemental-blog/compare/2.1.3...2.2.0
31 | ## [2.1.2](https://github.com/dynamic/silverstripe-elemental-blog/tree/2.1.2) (2019-07-29)
32 | [Full Changelog](https://github.com/dynamic/silverstripe-elemental-blog/compare/1.0.2...2.1.2)
33 |
34 | **Merged pull requests:**
35 |
36 | - UPDATE repository updates [\#25](https://github.com/dynamic/silverstripe-elemental-blog/pull/25) ([muskie9](https://github.com/muskie9))
37 | - Better handle edge cases where ElementBlogPosts targets a missing blog page [\#23](https://github.com/dynamic/silverstripe-elemental-blog/pull/23) ([maxime-rainville](https://github.com/maxime-rainville))
38 |
39 | ## [1.0.2](https://github.com/dynamic/silverstripe-elemental-blog/tree/1.0.2) (2019-05-15)
40 | [Full Changelog](https://github.com/dynamic/silverstripe-elemental-blog/compare/2.1.1...1.0.2)
41 |
42 | **Fixed bugs:**
43 |
44 | - BUG check if blog query returns blog before additional queries/filters [\#21](https://github.com/dynamic/silverstripe-elemental-blog/issues/21)
45 |
46 | **Merged pull requests:**
47 |
48 | - BUGFIX ensure blog query returns blog before additional queries/filters [\#22](https://github.com/dynamic/silverstripe-elemental-blog/pull/22) ([muskie9](https://github.com/muskie9))
49 | - Change ElementBlogPosts $icon static [\#20](https://github.com/dynamic/silverstripe-elemental-blog/pull/20) ([LABCAT](https://github.com/LABCAT))
50 |
51 | ## [2.1.1](https://github.com/dynamic/silverstripe-elemental-blog/tree/2.1.1) (2019-03-21)
52 | [Full Changelog](https://github.com/dynamic/silverstripe-elemental-blog/compare/2.1.0...2.1.1)
53 |
54 | **Closed issues:**
55 |
56 | - REQUIREMENTS remove @dev references for composer requirements [\#18](https://github.com/dynamic/silverstripe-elemental-blog/issues/18)
57 |
58 | **Merged pull requests:**
59 |
60 | - UPDATE requirements to not include @dev [\#19](https://github.com/dynamic/silverstripe-elemental-blog/pull/19) ([muskie9](https://github.com/muskie9))
61 | - create lang file, update labels [\#17](https://github.com/dynamic/silverstripe-elemental-blog/pull/17) ([jsirish](https://github.com/jsirish))
62 |
63 | ## [2.1.0](https://github.com/dynamic/silverstripe-elemental-blog/tree/2.1.0) (2019-02-14)
64 | [Full Changelog](https://github.com/dynamic/silverstripe-elemental-blog/compare/2.0.1...2.1.0)
65 |
66 | **Merged pull requests:**
67 |
68 | - Removed implied recipe dependency [\#16](https://github.com/dynamic/silverstripe-elemental-blog/pull/16) ([chillu](https://github.com/chillu))
69 |
70 | ## [2.0.1](https://github.com/dynamic/silverstripe-elemental-blog/tree/2.0.1) (2019-01-18)
71 | [Full Changelog](https://github.com/dynamic/silverstripe-elemental-blog/compare/2.0.0...2.0.1)
72 |
73 | **Fixed bugs:**
74 |
75 | - disable validation in favor of fallback [\#15](https://github.com/dynamic/silverstripe-elemental-blog/pull/15) ([jsirish](https://github.com/jsirish))
76 |
77 | ## [2.0.0](https://github.com/dynamic/silverstripe-elemental-blog/tree/2.0.0) (2019-01-17)
78 | [Full Changelog](https://github.com/dynamic/silverstripe-elemental-blog/compare/1.0.1...2.0.0)
79 |
80 | **Merged pull requests:**
81 |
82 | - update branch alias, composer requirements, readme [\#14](https://github.com/dynamic/silverstripe-elemental-blog/pull/14) ([jsirish](https://github.com/jsirish))
83 | - remove branch alias, update requirements [\#13](https://github.com/dynamic/silverstripe-elemental-blog/pull/13) ([jsirish](https://github.com/jsirish))
84 | - Update for Elemental 4.0.0 [\#12](https://github.com/dynamic/silverstripe-elemental-blog/pull/12) ([obj63mc](https://github.com/obj63mc))
85 |
86 | ## [1.0.1](https://github.com/dynamic/silverstripe-elemental-blog/tree/1.0.1) (2018-08-28)
87 | [Full Changelog](https://github.com/dynamic/silverstripe-elemental-blog/compare/1.0.0...1.0.1)
88 |
89 | **Merged pull requests:**
90 |
91 | - elemental requirements [\#11](https://github.com/dynamic/silverstripe-elemental-blog/pull/11) ([jsirish](https://github.com/jsirish))
92 |
93 | ## [1.0.0](https://github.com/dynamic/silverstripe-elemental-blog/tree/1.0.0) (2018-07-30)
94 | **Implemented enhancements:**
95 |
96 | - ENHANCEMENT Category filter option [\#9](https://github.com/dynamic/silverstripe-elemental-blog/issues/9)
97 | - Getter for pulling content [\#2](https://github.com/dynamic/silverstripe-elemental-blog/issues/2)
98 |
99 | **Fixed bugs:**
100 |
101 | - Getter for pulling content [\#2](https://github.com/dynamic/silverstripe-elemental-blog/issues/2)
102 |
103 | **Closed issues:**
104 |
105 | - template needs to be namespaced [\#6](https://github.com/dynamic/silverstripe-elemental-blog/issues/6)
106 |
107 | **Merged pull requests:**
108 |
109 | - Added ability to have a specific category show [\#10](https://github.com/dynamic/silverstripe-elemental-blog/pull/10) ([mak001](https://github.com/mak001))
110 | - Updated namespacing to reflect other modules [\#8](https://github.com/dynamic/silverstripe-elemental-blog/pull/8) ([mak001](https://github.com/mak001))
111 | - composer - update requirements to @dev [\#5](https://github.com/dynamic/silverstripe-elemental-blog/pull/5) ([jsirish](https://github.com/jsirish))
112 | - README - update badges [\#4](https://github.com/dynamic/silverstripe-elemental-blog/pull/4) ([jsirish](https://github.com/jsirish))
113 | - bugfix - getPostsList\(\) - check if BlogID is set [\#3](https://github.com/dynamic/silverstripe-elemental-blog/pull/3) ([jsirish](https://github.com/jsirish))
114 | - rename module to silverstripe-elemental-blog [\#1](https://github.com/dynamic/silverstripe-elemental-blog/pull/1) ([jsirish](https://github.com/jsirish))
115 |
116 |
117 |
118 | \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
119 |
--------------------------------------------------------------------------------
/src/Elements/ElementBlogOverview.php:
--------------------------------------------------------------------------------
1 | 'HTMLText',
29 | 'ShowPagination' => 'Boolean(0)',
30 | ];
31 |
32 | private static string $icon = 'font-icon-p-articles';
33 |
34 | private static string $table_name = 'ElementBlogOverview';
35 |
36 | private static string $singular_name = 'Blog Overview';
37 |
38 | private static string $plural_name = 'Blog Overview Blocks';
39 |
40 | private static string $description = 'Block displaying Blog Posts with pagination';
41 |
42 | /**
43 | * We use this default_title for the Block name in the CMS. Feel free to update it via config
44 | */
45 | private static string $default_title = 'Blog Overview';
46 |
47 | /**
48 | * The main purpose of this Block is to replace the standard Blog Layout functionality (including pagination,
49 | * filters, and widgets). In order to do that out of the box, this Block must be used on a Blog page (as it is the
50 | * Blog page and BlogController that provides the feedback we require)
51 | *
52 | * By default, this Block will return null in all the areas where it expects to find a Blog/BlogController if it
53 | * does not. However, if you enable this Block to be used elsewhere, there are extension points/etc available for
54 | * you to return/update the DataList/Paginated list in other ways
55 | */
56 | private static bool $allow_use_outside_of_blog = false;
57 |
58 | /**
59 | * Depending on your config, there is potentially no reason for a content author to enter this Block to make any
60 | * edits, if that is the case for you, then it likely makes sense that you just set a title for them by default
61 | */
62 | private static bool $set_default_title = false;
63 |
64 | /**
65 | * You can set this to false if you would prefer that we do not display the default Title field that Elemental
66 | * provides to users
67 | */
68 | private static bool $show_title_field = true;
69 |
70 | /**
71 | * You can set this to false if you would prefer that we do not display the HTMLEditor/$Content field to users
72 | */
73 | private static bool $show_content_field = true;
74 |
75 | /**
76 | * By default, we show the "Show Pagination" field in the CMS (since it is part of the default supported features).
77 | * You may, however, prefer that content authors display pagination for the Blog using the specific
78 | * `PaginationBlock`, and if that's the case, you'll likely want to set this to false via config, as it will no
79 | * longer be relevant for your content authors
80 | */
81 | private static bool $show_pagination_field = true;
82 |
83 | /**
84 | * Default value for ShowPagination. If set, this block will also output the pagination for your Blog. You can
85 | * update this value via config
86 | */
87 | private static int $pagination_field_default = 1;
88 |
89 | /**
90 | * This can be updated via config if (for whatever reason) you do not wish to show this message field in the CMS
91 | */
92 | private static bool $show_info_message_field = true;
93 |
94 | /**
95 | * Default value used for the message field in the CMS
96 | */
97 | private static string $info_message_field_default = 'This block automatically displays Blog Posts and pagination';
98 |
99 | /**
100 | * Cached value for BlogPosts from the Blog page
101 | *
102 | * @var DataList|BlogPost[]|null
103 | */
104 | private $blogPosts;
105 |
106 | /**
107 | * Cached value for the PaginatedList from BlogController
108 | *
109 | * @var PaginatedList|null
110 | */
111 | private $paginatedList;
112 |
113 | /**
114 | * Cached value for our CacheKey. It's not all that cheap to generate it, so, we should only do it once per
115 | * request
116 | *
117 | * @var string|null
118 | */
119 | private $cacheKey;
120 |
121 | /**
122 | * @codeCoverageIgnore
123 | * @return FieldList
124 | */
125 | public function getCMSFields(): FieldList
126 | {
127 | $fields = parent::getCMSFields();
128 |
129 | // Removing scaffold fields so that they can be added more explicitly (and allowing for update via extension
130 | // points)
131 | $fields->removeByName([
132 | 'Content',
133 | 'ShowPagination',
134 | ]);
135 |
136 | // Check whether we want to display the default Title field
137 | if (!static::config()->get('show_content_field')) {
138 | $fields->removeByName('Title');
139 | }
140 |
141 | // Check whether we want to display our Content WYSIWYG field
142 | if (static::config()->get('show_content_field')) {
143 | $contentField = HTMLEditorField::create('Content');
144 |
145 | // An opportunity for you to update this field before it is added (EG: you might want to add a description)
146 | $this->invokeWithExtensions('updateContentField', $contentField);
147 |
148 | $fields->addFieldToTab(
149 | 'Root.Main',
150 | $contentField
151 | );
152 | }
153 |
154 | // Check whether we want to allow the author to determine whether or not the Block outputs with pagination
155 | if (static::config()->get('show_pagination_field')) {
156 | $showPaginationField = CheckboxField::create('ShowPagination');
157 |
158 | // An opportunity for you to update this field before it is added (EG: you might want to add a description)
159 | $this->invokeWithExtensions('updateShowPaginationField', $showPaginationField);
160 |
161 | $fields->addFieldToTab(
162 | 'Root.Main',
163 | $showPaginationField
164 | );
165 | }
166 |
167 | // Check whether want to display this message
168 | if (static::config()->get('show_info_message_field')) {
169 | $messageField = LiteralField::create(
170 | 'BlockInfoMessage',
171 | sprintf(
172 | '
%s
',
173 | static::config()->get('info_message_field_default')
174 | )
175 | );
176 |
177 | // An opportunity for you to update this field before it is added
178 | $this->invokeWithExtensions('updateMessageField', $messageField);
179 |
180 | $fields->addFieldToTab(
181 | 'Root.Main',
182 | $messageField
183 | );
184 | }
185 |
186 | return $fields;
187 | }
188 |
189 | public function populateDefaults(): void
190 | {
191 | parent::populateDefaults();
192 |
193 | // Set the Title by default, if you have specified for us to
194 | if (static::config()->get('set_default_title')) {
195 | $this->Title = static::config()->get('default_title');
196 | }
197 |
198 | // Always set the default for these fields
199 | $this->ShowPagination = static::config()->get('pagination_field_default');
200 | }
201 |
202 | /**
203 | * We'll allow the passing of a Controller for a couple of reasons:
204 | * 1) Provides a new way for you to dictate how a PaginatedList might be provided
205 | * 2) Makes testing much easier...
206 | *
207 | * @param Controller|null $controller
208 | * @return PaginatedList|null
209 | * @throws ValidationException
210 | */
211 | public function getPaginatedList(?Controller $controller = null): ?PaginatedList
212 | {
213 | // Return our cached value, if one exists
214 | if ($this->paginatedList !== null) {
215 | return $this->paginatedList;
216 | }
217 |
218 | if ($controller === null) {
219 | /** @var BlogController $controller */
220 | $controller = Controller::curr();
221 | }
222 |
223 | // Ideally, we want to fetch the PaginatedList from the BlogController, but, if this Block is not being used on
224 | // a Blog page, then that will not be (immediately) possible. You have three options:
225 | // 1) You can implement a method `PaginatedList` on your Controller, and provide it with the appropriate data
226 | // 2) You can use the `updatePaginatedList` extension point to apply your filters/limits to the PaginatedList
227 | // that will be provided to it
228 | // 3) Maybe you should be using ElementBlogPosts Block instead
229 |
230 | // The active Controller is what we expect, so we can simply return the PaginatedList from there. Early exit for
231 | // increased readability
232 | if ($controller instanceof BlogController) {
233 | // Store this PaginatedList as our cached value and provide an extension point
234 | $this->setPaginatedList($controller->PaginatedList());
235 |
236 | return $this->paginatedList;
237 | }
238 |
239 | // You have specified that this Block *cannot* be used outside of the Blog, so that also means that we
240 | // expect a Controller to have been present
241 | if (!static::config()->get('allow_use_outside_of_blog')) {
242 | return null;
243 | }
244 |
245 | if ($controller !== null && $controller->hasMethod('PaginatedList')) {
246 | // If you know that you're going to be using this Block on another Page type, then you can implement the
247 | // getBlogPostPaginatedList() method there, and we'll use that
248 | $paginatedList = $controller->PaginatedList();
249 | } else {
250 | // Since you have specified that this Block *can* be used outside of the Blog, we'll create a PaginatedList
251 | // containing all BlogPosts in the DB, and you can then manipulate that List as you wish through the
252 | // extension point
253 | $paginatedList = PaginatedList::create($this->getBlogPosts());
254 | }
255 |
256 | // Store this PaginatedList as our cached value and provide an extension point
257 | $this->setPaginatedList($paginatedList);
258 |
259 | return $this->paginatedList;
260 | }
261 |
262 | /**
263 | * @return DataList
264 | * @throws ValidationException
265 | */
266 | public function getBlogPosts(): ?DataList
267 | {
268 | // Return our cached value, if one exists
269 | if ($this->blogPosts !== null) {
270 | return $this->blogPosts;
271 | }
272 |
273 | /** @var Blog $page */
274 | $page = $this->getPage();
275 |
276 | // Ideally, we want to fetch the BlogPosts that were specifically posted under a Parent Blog page, but, if this
277 | // Block is not being used on a Blog page, then that is not possible. Instead, we will just return all Blog
278 | // Posts in the DB. You can then update this DataList (maybe with additional filters/limits/etc) by using the
279 | // `updateBlogPosts` extension point
280 | if ($page instanceof Blog) {
281 | // Store this DataList as our cached value and provide an extension point
282 | $this->setBlogPosts($page->getBlogPosts());
283 |
284 | return $this->blogPosts;
285 | }
286 |
287 | // You have specified that this Block *cannot* be used outside of the Blog, so that also means that we
288 | // expect a parent Page to have been present and of type Blog
289 | if (!static::config()->get('allow_use_outside_of_blog')) {
290 | return null;
291 | }
292 |
293 | if ($page !== null && $page->hasMethod('getBlogPosts')) {
294 | // If you know that you're going to be using this Block on another Page type, then you can implement the
295 | // getBlogPosts() method there, and we'll use that
296 | $blogPosts = $page->getBlogPosts();
297 | } else {
298 | // Since you have specified that this Block *can* be used outside of the Blog, we'll create a DataList
299 | // containing all BlogPosts in the DB, and you can then manipulate that List as you wish through the
300 | // extension point
301 | $blogPosts = BlogPost::get();
302 | }
303 |
304 | // Store this DataList as our cached value and provide an extension point
305 | $this->setBlogPosts($blogPosts);
306 |
307 | return $this->blogPosts;
308 | }
309 |
310 | /**
311 | * @param PaginatedList|null $paginatedList
312 | */
313 | protected function setPaginatedList(?PaginatedList $paginatedList): void
314 | {
315 | // Provided is an opportunity for you to update this PaginatedList
316 | $this->invokeWithExtensions('updatePaginatedList', $paginatedList);
317 |
318 | // Store this List as our cached value
319 | $this->paginatedList = $paginatedList;
320 | }
321 |
322 | /**
323 | * @param DataList|null $blogPosts
324 | */
325 | protected function setBlogPosts(?DataList $blogPosts): void
326 | {
327 | // Provided is an opportunity for you to update this DataList
328 | $this->invokeWithExtensions('updateBlogPosts', $blogPosts);
329 |
330 | // Store this DataList as our cached value
331 | $this->blogPosts = $blogPosts;
332 | }
333 | }
334 |
--------------------------------------------------------------------------------