mirror of
https://github.com/silverstripe/silverstripe-blog
synced 2024-10-22 11:05:58 +02:00
Compare commits
69 Commits
3
...
4.2.0-beta
Author | SHA1 | Date | |
---|---|---|---|
|
37d2ccff76 | ||
|
85664ce91b | ||
|
5d9007d5d7 | ||
|
3b8092272b | ||
|
e8e40a808d | ||
|
63516905a4 | ||
|
a1858fad6c | ||
|
0d037571ac | ||
|
283ca6a664 | ||
|
b2f0d12dd6 | ||
|
0704d99992 | ||
|
1e982c8f31 | ||
|
33da9d042d | ||
|
e6228eae37 | ||
|
d6375c5048 | ||
|
1d901be802 | ||
|
c394361e14 | ||
|
926ce562f1 | ||
|
4a71f93f23 | ||
|
99d74f9c43 | ||
|
7d15e3cc68 | ||
|
2ef3981000 | ||
|
08e2bd38e7 | ||
|
99d1063361 | ||
|
ff9b019c2d | ||
|
e363b0e590 | ||
|
685ccf39a8 | ||
|
fe638a0ccb | ||
|
38bad2d658 | ||
|
f4ae122351 | ||
|
0f93f6a842 | ||
|
7964baa544 | ||
|
ca5dfb4ed3 | ||
|
81c661caf2 | ||
|
1f3878bc3f | ||
|
b9c535ac67 | ||
|
e9390c3525 | ||
|
29ca438a9f | ||
|
6f3b32264e | ||
|
bcbb40e08d | ||
|
7189427bf3 | ||
|
c93566f7a8 | ||
|
23fd31c105 | ||
|
1514d0b982 | ||
|
84b815d0a0 | ||
|
3f4b87489c | ||
|
7f86285552 | ||
|
f2388c6408 | ||
|
7cbeb90280 | ||
|
08cee006fc | ||
|
058e2aced6 | ||
|
d8be9212cd | ||
|
dbeefc15c7 | ||
|
0f8f0ac0cb | ||
|
05ed7e3be7 | ||
|
262b66dffd | ||
|
692c8fc390 | ||
|
008b2d4816 | ||
|
631fb53713 | ||
|
fb7ba28a24 | ||
|
85f8f32736 | ||
|
ffea8acb0e | ||
|
f01d421ee2 | ||
|
624444e136 | ||
|
9b49e1bfcc | ||
|
d24ea64be2 | ||
|
57b81dbbe3 | ||
|
0f1da8c938 | ||
|
29f0b39271 |
1
.github/ISSUE_TEMPLATE.md
vendored
Normal file
1
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
<!-- Blank templates are for use by maintainers only! If you aren't a maintainer, please go back and pick one of the issue templates. -->
|
72
.github/ISSUE_TEMPLATE/1_bug_report.yml
vendored
Normal file
72
.github/ISSUE_TEMPLATE/1_bug_report.yml
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
name: 🪳 Bug Report
|
||||||
|
description: Tell us if something isn't working the way it's supposed to
|
||||||
|
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
We strongly encourage you to [submit a pull request](https://docs.silverstripe.org/en/contributing/code/) which fixes the issue.
|
||||||
|
Bug reports which are accompanied with a pull request are a lot more likely to be resolved quickly.
|
||||||
|
- type: input
|
||||||
|
id: affected-versions
|
||||||
|
attributes:
|
||||||
|
label: Module version(s) affected
|
||||||
|
description: |
|
||||||
|
What version of _this module_ have you reproduced this bug on?
|
||||||
|
Run `composer info` to see the specific version of each module installed in your project.
|
||||||
|
If you don't have access to that, check inside the help menu in the bottom left of the CMS.
|
||||||
|
placeholder: x.y.z
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: A clear and concise description of the problem
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: how-to-reproduce
|
||||||
|
attributes:
|
||||||
|
label: How to reproduce
|
||||||
|
description: |
|
||||||
|
⚠️ This is the most important part of the report ⚠️
|
||||||
|
Without a way to easily reproduce your issue, there is little chance we will be able to help you and work on a fix.
|
||||||
|
- Please, take the time to show us some code and/or configuration that is needed for others to reproduce the problem easily.
|
||||||
|
- If the bug is too complex to reproduce with some short code samples, please reproduce it in a public repository and provide a link to the repository along with steps for setting up and reproducing the bug using that repository.
|
||||||
|
- If part of the bug includes an error or exception, please provide a full stack trace.
|
||||||
|
- If any user interaction is required to reproduce the bug, please add an ordered list of steps that are required to reproduce it.
|
||||||
|
- Be as clear as you can, but don't miss any steps out. Simply saying "create a page" is less useful than guiding us through the steps you're taking to create a page, for example.
|
||||||
|
placeholder: |
|
||||||
|
|
||||||
|
#### Code sample
|
||||||
|
```php
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Reproduction steps
|
||||||
|
1.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: possible-solution
|
||||||
|
attributes:
|
||||||
|
label: Possible Solution
|
||||||
|
description: |
|
||||||
|
*Optional: only if you have suggestions on a fix/reason for the bug*
|
||||||
|
Please consider [submitting a pull request](https://docs.silverstripe.org/en/contributing/code/) with your solution! It helps get faster feedback and greatly increases the chance of the bug being fixed.
|
||||||
|
- type: textarea
|
||||||
|
id: additional-context
|
||||||
|
attributes:
|
||||||
|
label: Additional Context
|
||||||
|
description: "*Optional: any other context about the problem: log messages, screenshots, etc.*"
|
||||||
|
- type: checkboxes
|
||||||
|
id: validations
|
||||||
|
attributes:
|
||||||
|
label: Validations
|
||||||
|
description: "Before submitting the issue, please make sure you do the following:"
|
||||||
|
options:
|
||||||
|
- label: Check that there isn't already an issue that reports the same bug
|
||||||
|
required: true
|
||||||
|
- label: Double check that your reproduction steps work in a fresh installation of [`silverstripe/installer`](https://github.com/silverstripe/silverstripe-installer) (with any code examples you've provided)
|
||||||
|
required: true
|
35
.github/ISSUE_TEMPLATE/2_feature_request.yml
vendored
Normal file
35
.github/ISSUE_TEMPLATE/2_feature_request.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
name: 🚀 Feature Request
|
||||||
|
description: Submit a feature request (but only if you're planning on implementing it)
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Please only submit feature requests if you plan on implementing the feature yourself.
|
||||||
|
See the [contributing code documentation](https://docs.silverstripe.org/en/contributing/code/#make-or-find-a-github-issue) for more guidelines about submitting feature requests.
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: A clear and concise description of the new feature, and why it belongs in core
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: more-info
|
||||||
|
attributes:
|
||||||
|
label: Additional context or points of discussion
|
||||||
|
description: |
|
||||||
|
*Optional: Any additional context, points of discussion, etc that might help validate and refine your idea*
|
||||||
|
- type: checkboxes
|
||||||
|
id: validations
|
||||||
|
attributes:
|
||||||
|
label: Validations
|
||||||
|
description: "Before submitting the issue, please confirm the following:"
|
||||||
|
options:
|
||||||
|
- label: You intend to implement the feature yourself
|
||||||
|
required: true
|
||||||
|
- label: You have read the [contributing guide](https://docs.silverstripe.org/en/contributing/code/)
|
||||||
|
required: true
|
||||||
|
- label: You strongly believe this feature should be in core, rather than being its own community module
|
||||||
|
required: true
|
||||||
|
- label: You have checked for existing issues or pull requests related to this feature (and didn't find any)
|
||||||
|
required: true
|
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
blank_issues_enabled: true
|
||||||
|
contact_links:
|
||||||
|
- name: Security Vulnerability
|
||||||
|
url: https://docs.silverstripe.org/en/contributing/issues_and_bugs/#reporting-security-issues
|
||||||
|
about: ⚠️ We do not use GitHub issues to track security vulnerability reports. Click "open" on the right to see how to report security vulnerabilities.
|
||||||
|
- name: Support Question
|
||||||
|
url: https://www.silverstripe.org/community/
|
||||||
|
about: We use GitHub issues only to discuss bugs and new features. For support questions, please use one of the support options available in our community channels.
|
39
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
39
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<!--
|
||||||
|
Thanks for contributing, you're awesome! ⭐
|
||||||
|
|
||||||
|
Please read https://docs.silverstripe.org/en/contributing/code/ if you haven't contributed to this project recently.
|
||||||
|
-->
|
||||||
|
## Description
|
||||||
|
<!--
|
||||||
|
Please describe expected and observed behaviour, and what you're fixing.
|
||||||
|
For visual fixes, please include tested browsers and screenshots.
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Manual testing steps
|
||||||
|
<!--
|
||||||
|
Include any manual testing steps here which a reviewer can perform to validate your pull request works correctly.
|
||||||
|
Note that this DOES NOT replace unit or end-to-end tests.
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Issues
|
||||||
|
<!--
|
||||||
|
List all issues here that this pull request fixes/resolves.
|
||||||
|
If there is no issue already, create a new one! You must link your pull request to at least one issue.
|
||||||
|
-->
|
||||||
|
- #
|
||||||
|
|
||||||
|
## Pull request checklist
|
||||||
|
<!--
|
||||||
|
PLEASE check each of these to ensure you have done everything you need to do!
|
||||||
|
If there's something in this list you need help with, please ask so that we can assist you.
|
||||||
|
-->
|
||||||
|
- [ ] The target branch is correct
|
||||||
|
- See [picking the right version](https://docs.silverstripe.org/en/contributing/code/#picking-the-right-version)
|
||||||
|
- [ ] All commits are relevant to the purpose of the PR (e.g. no debug statements, unrelated refactoring, or arbitrary linting)
|
||||||
|
- Small amounts of additional linting are usually okay, but if it makes it hard to concentrate on the relevant changes, ask for the unrelated changes to be reverted, and submitted as a separate PR.
|
||||||
|
- [ ] The commit messages follow our [commit message guidelines](https://docs.silverstripe.org/en/contributing/code/#commit-messages)
|
||||||
|
- [ ] The PR follows our [contribution guidelines](https://docs.silverstripe.org/en/contributing/code/)
|
||||||
|
- [ ] Code changes follow our [coding conventions](https://docs.silverstripe.org/en/contributing/coding_conventions/)
|
||||||
|
- [ ] This change is covered with tests (or tests aren't necessary for this change)
|
||||||
|
- [ ] Any relevant User Help/Developer documentation is updated; for impactful changes, information is added to the changelog for the intended release
|
||||||
|
- [ ] CI is green
|
6
.github/workflows/keepalive.yml
vendored
6
.github/workflows/keepalive.yml
vendored
@ -1,10 +1,10 @@
|
|||||||
name: Keepalive
|
name: Keepalive
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
# At 2:10 AM UTC, on day 11 of the month
|
||||||
# The 4th of every month at 10:50am UTC
|
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '50 10 4 * *'
|
- cron: '10 2 11 * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
keepalive:
|
keepalive:
|
||||||
|
17
.github/workflows/merge-up.yml
vendored
Normal file
17
.github/workflows/merge-up.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
name: Merge-up
|
||||||
|
|
||||||
|
on:
|
||||||
|
# At 12:20 PM UTC, only on Saturday
|
||||||
|
schedule:
|
||||||
|
- cron: '20 12 * * 6'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
merge-up:
|
||||||
|
name: Merge-up
|
||||||
|
# Only run cron on the silverstripe account
|
||||||
|
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Merge-up
|
||||||
|
uses: silverstripe/gha-merge-up@v1
|
2
.github/workflows/update-js.yml
vendored
2
.github/workflows/update-js.yml
vendored
@ -4,7 +4,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
# Run on a schedule of once per quarter
|
# Run on a schedule of once per quarter
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 1 */3 *'
|
- cron: '10 2 1 */3 *'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update-js:
|
update-js:
|
||||||
|
33
.upgrade.yml
33
.upgrade.yml
@ -1,33 +0,0 @@
|
|||||||
mappings:
|
|
||||||
GridFieldCategorisationConfig: SilverStripe\Blog\Admin\GridFieldCategorisationConfig
|
|
||||||
GridFieldFormAction: SilverStripe\Blog\Admin\GridFieldFormAction
|
|
||||||
GridFieldMergeAction: SilverStripe\Blog\Admin\GridFieldMergeAction
|
|
||||||
BlogCommentExtension: SilverStripe\Blog\Model\BlogCommentExtension
|
|
||||||
BlogFilter: SilverStripe\Blog\Model\BlogFilter
|
|
||||||
BlogFilter_GridField: SilverStripe\Blog\Model\BlogFilter\BlogFilterGridField
|
|
||||||
BlogMemberExtension: SilverStripe\Blog\Model\BlogMemberExtension
|
|
||||||
BlogPostFilter: SilverStripe\Blog\Model\BlogPostFilter
|
|
||||||
BlogPostNotifications: SilverStripe\Blog\Model\BlogPostNotifications
|
|
||||||
Blog: SilverStripe\Blog\Model\Blog
|
|
||||||
Blog_Controller: SilverStripe\Blog\Model\BlogController
|
|
||||||
BlogController: SilverStripe\Blog\Model\BlogController
|
|
||||||
BlogCategory: SilverStripe\Blog\Model\BlogCategory
|
|
||||||
BlogPost: SilverStripe\Blog\Model\BlogPost
|
|
||||||
BlogPost_Controller: SilverStripe\Blog\Model\BlogPostController
|
|
||||||
BlogPostController: SilverStripe\Blog\Model\BlogPostController
|
|
||||||
BlogTag: SilverStripe\Blog\Model\BlogTag
|
|
||||||
CategorisationObject: SilverStripe\Blog\Model\CategorisationObject
|
|
||||||
BlogAdminSidebar: SilverStripe\Blog\Forms\BlogAdminSidebar
|
|
||||||
GridFieldAddByDBField: SilverStripe\Blog\Forms\GridField\GridFieldAddByDBField
|
|
||||||
GridFieldBlogPostState: SilverStripe\Blog\Forms\GridField\GridFieldBlogPostState
|
|
||||||
GridFieldConfig_BlogPost: SilverStripe\Blog\Forms\GridField\GridFieldConfigBlogPost
|
|
||||||
BlogArchiveWidget: SilverStripe\Blog\Widgets\BlogArchiveWidget
|
|
||||||
BlogArchiveWidget_Controller: SilverStripe\Blog\Widgets\BlogArchiveWidgetController
|
|
||||||
BlogCategoriesWidget: SilverStripe\Blog\Widgets\BlogCategoriesWidget
|
|
||||||
BlogCategoriesWidget_Controller: SilverStripe\Blog\Widgets\BlogCategoriesWidgetController
|
|
||||||
BlogRecentPostsWidget: SilverStripe\Blog\Widgets\BlogRecentPostsWidget
|
|
||||||
BlogRecentPostsWidget_Controller: SilverStripe\Blog\Widgets\BlogRecentPostsWidgetController
|
|
||||||
BlogTagsCloudWidget: SilverStripe\Blog\Widgets\BlogTagsCloudWidget
|
|
||||||
BlogTagsCloudWidget_Controller: SilverStripe\Blog\Widgets\BlogTagsCloudWidgetController
|
|
||||||
BlogTagsWidget: SilverStripe\Blog\Widgets\BlogTagsWidget
|
|
||||||
BlogTagsWidget_Controller: SilverStripe\Blog\Widgets\BlogTagsWidgetController
|
|
20
README.md
20
README.md
@ -8,16 +8,6 @@
|
|||||||
* [User guide](docs/en/userguide/index.md)
|
* [User guide](docs/en/userguide/index.md)
|
||||||
* [Developer documentation](docs/en/index.md)
|
* [Developer documentation](docs/en/index.md)
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
* Silverstripe CMS 4.0+
|
|
||||||
* Silverstripe Lumberjack Module 2.0+
|
|
||||||
* Silverstripe Tag Field Module 2.0+
|
|
||||||
* Silverstripe Assets 1.0+
|
|
||||||
* Silverstripe Asset Admin Module 1.0+
|
|
||||||
|
|
||||||
Note: this version is compatible with Silverstripe 4. For Silverstripe 3, please see [the 2.x release line](https://github.com/silverstripe/silverstripe-blog/tree/2).
|
|
||||||
|
|
||||||
### Suggested Modules
|
### Suggested Modules
|
||||||
|
|
||||||
* Silverstripe Widgets Module
|
* Silverstripe Widgets Module
|
||||||
@ -28,13 +18,3 @@ Note: this version is compatible with Silverstripe 4. For Silverstripe 3, please
|
|||||||
```
|
```
|
||||||
composer require silverstripe/blog
|
composer require silverstripe/blog
|
||||||
```
|
```
|
||||||
|
|
||||||
## Upgrading
|
|
||||||
|
|
||||||
### Upgrading from 2.x to 3.x
|
|
||||||
|
|
||||||
Aside from the framework and CMS upgrades required the blog module should not require anything extra to be completed.
|
|
||||||
|
|
||||||
### Upgrading legacy blog to 2.x
|
|
||||||
|
|
||||||
If you're upgrading from blog version 1.0 to 2.x you will need to run the `BlogMigrationTask`. Run the task using `dev/tasks/BlogMigrationTask` either via the browser or sake CLI to migrate your legacy blog to the new version data structure.
|
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
Name: bloglegacy
|
|
||||||
---
|
|
||||||
SilverStripe\ORM\DatabaseAdmin:
|
|
||||||
classname_value_remapping:
|
|
||||||
Blog: SilverStripe\Blog\Model\Blog
|
|
||||||
BlogCategory: SilverStripe\Blog\Model\BlogCategory
|
|
||||||
BlogPost: SilverStripe\Blog\Model\BlogPost
|
|
||||||
BlogTag: SilverStripe\Blog\Model\BlogTag
|
|
||||||
BlogArchiveWidget: SilverStripe\Blog\Widgets\BlogArchiveWidget
|
|
||||||
BlogCategoriesWidget: SilverStripe\Blog\Widgets\BlogCategoriesWidget
|
|
||||||
BlogRecentPostsWidget: SilverStripe\Blog\Widgets\BlogRecentPostsWidget
|
|
||||||
BlogTagsCloudWidget: SilverStripe\Blog\Widgets\BlogTagsCloudWidget
|
|
||||||
BlogTagsWidget: SilverStripe\Blog\Widgets\BlogTagsWidget
|
|
6
babel.config.json
Normal file
6
babel.config.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
"@babel/preset-env",
|
||||||
|
"@babel/preset-react"
|
||||||
|
]
|
||||||
|
}
|
2
client/dist/js/main.bundle.js
vendored
2
client/dist/js/main.bundle.js
vendored
@ -1 +1 @@
|
|||||||
!function(t){function e(i){if(n[i])return n[i].exports;var o=n[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var n={};e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,i){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:i})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s="./client/src/main.js")}({"./client/src/bundles/cms.js":function(t,e,n){"use strict";var i=n(0);n.n(i).a.entwine("ss",function(t){t(".cms-content-fields > #Form_EditForm_error").entwine({onadd:function(){var e=t(".blog-admin-outer");1===e.length&&e.prepend(this)}}),t(".toggle-description").entwine({onadd:function(){var e=t(this);if(!e.hasClass("toggle-description-enabled")){e.addClass("toggle-description-enabled");var n=!1,i=e.closest(".field").find(".form-text");e.on("click",function(){i[n?"hide":"show"](),e.toggleClass("toggle-description-shown"),n=!n}),i.hide(),e.parent().addClass("toggle-description-correct-right"),e.parent().prev(".middleColumn").addClass("toggle-description-correct-middle"),e.parent().next(".description").addClass("toggle-description-correct-description")}}}),t(".MergeAction").entwine({onadd:function(){var e=t(this);e.on("click","select",function(){return!1}),e.children("button").each(function(e,n){var i=t(n),o=i.prev("select");i.before('<input type="hidden" name="'+i.attr("data-target")+'" value="'+o.val()+'" />')}),e.on("change","select",function(e){var n=t(e.target);n.next("input").val(n.val())}),e.children("button, select").hide(),e.on("click",".MergeActionReveal",function(e){var n=t(e.target);return n.parent().children("button, select").show(),n.hide(),!1})}}),t(".blog-admin-sidebar.cms-panel").entwine({MinInnerWidth:620,onadd:function(){var e=this;this._super(),this.updateLayout(),!this.hasClass("collapsed")&&t(".blog-admin-outer").width()<this.getMinInnerWidth()&&this.collapsePanel();var n=function(){e.updateLayout()};n.bind(this),window.onresize=n},togglePanel:function(t,e){this._super(t,e),this.updateLayout()},updateLayout:function(){t(this).css("height","100%");var e=t(this).outerHeight(),n=t(".cms-content-actions").eq(0).outerHeight();t(this).css("height",e-n+"px"),t(this).css("bottom",n+"px"),t(".cms-container").updateLayoutOptions({minContentWidth:820+this.width()})}})})},"./client/src/bundles/gridfieldaddbydbfield.js":function(t,e,n){"use strict";var i=n(0);n.n(i).a.entwine("ss",function(t){t(".add-existing-autocompleter input.text").entwine({onkeydown:function(e){13===e.which&&(t(this).parents(".add-existing-autocompleter").find('button[type="submit"]').click(),e.preventDefault())}})})},"./client/src/main.js":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),n("./client/src/bundles/cms.js"),n("./client/src/bundles/gridfieldaddbydbfield.js")},0:function(t,e){t.exports=jQuery}});
|
!function(){"use strict";var t={949:function(t,e,n){var i;((i=n(311))&&i.__esModule?i:{default:i}).default.entwine("ss",(t=>{t(".cms-content-fields > #Form_EditForm_error").entwine({onadd(){const e=t(".blog-admin-outer");1===e.length&&e.prepend(this)}}),t(".toggle-description").entwine({onadd(){const e=t(this);if(e.hasClass("toggle-description-enabled"))return;e.addClass("toggle-description-enabled");let n=!1;const i=e.closest(".field").find(".form-text");e.on("click",(()=>{i[n?"hide":"show"](),e.toggleClass("toggle-description-shown"),n=!n})),i.hide(),e.parent().addClass("toggle-description-correct-right"),e.parent().prev(".middleColumn").addClass("toggle-description-correct-middle"),e.parent().next(".description").addClass("toggle-description-correct-description")}}),t(".MergeAction").entwine({onadd(){const e=t(this);e.on("click","select",(()=>!1)),e.children("button").each(((e,n)=>{const i=t(n),s=i.prev("select");i.before(`<input type="hidden" name="${i.attr("data-target")}" value="${s.val()}" />`)})),e.on("change","select",(e=>{const n=t(e.target);n.next("input").val(n.val())})),e.children("button, select").hide(),e.on("click",".MergeActionReveal",(e=>{const n=t(e.target);return n.parent().children("button, select").show(),n.hide(),!1}))}}),t(".blog-admin-sidebar.cms-panel").entwine({MinInnerWidth:620,onadd(){this._super(),this.updateLayout(),!this.hasClass("collapsed")&&t(".blog-admin-outer").width()<this.getMinInnerWidth()&&this.collapsePanel();const e=()=>{this.updateLayout()};e.bind(this),window.onresize=e},togglePanel(t,e){this._super(t,e),this.updateLayout()},updateLayout(){t(this).css("height","100%");const e=t(this).outerHeight(),n=t(".cms-content-actions").eq(0).outerHeight();t(this).css("height",e-n+"px"),t(this).css("bottom",`${n}px`),t(".cms-container").updateLayoutOptions({minContentWidth:820+this.width()})}})}))},997:function(t,e,n){var i;((i=n(311))&&i.__esModule?i:{default:i}).default.entwine("ss",(t=>{t(".add-existing-autocompleter input.text").entwine({onkeydown(e){if(13===e.which){t(this).parents(".add-existing-autocompleter").find('button[type="submit"]').click(),e.preventDefault()}}})}))},311:function(t){t.exports=jQuery}},e={};function n(i){var s=e[i];if(void 0!==s)return s.exports;var o=e[i]={exports:{}};return t[i](o,o.exports,n),o.exports}n(949),n(997)}();
|
2
client/dist/styles/main.css
vendored
2
client/dist/styles/main.css
vendored
@ -1 +1 @@
|
|||||||
.no-sidebar .content-container.size3of4{width:75%}.blog-entry .post-image img{width:98.75%}.blog-sidebar .WidgetHolder ul{margin-left:0}.blog-sidebar .WidgetHolder ul li,ul.blogTagCloud{list-style-type:none}ul.blogTagCloud{clear:both}ul.blogTagCloud li{float:left;display:inline;padding-right:8px}ul.blogTagCloud li a span{float:left;line-height:30px;text-align:center;padding:0}ul.blogTagCloud .tagCount10{font-size:26pt}ul.blogTagCloud .tagCount9{font-size:24pt}ul.blogTagCloud .tagCount8{font-size:22pt}ul.blogTagCloud .tagCount7{font-size:20pt}ul.blogTagCloud .tagCount6{font-size:18pt}ul.blogTagCloud .tagCount5{font-size:16pt}ul.blogTagCloud .tagCount4{font-size:14pt}ul.blogTagCloud .tagCount3{font-size:12pt}ul.blogTagCloud .tagCount2{font-size:10pt}ul.blogTagCloud .tagCount1{font-size:8pt}#FeaturedImage .middleColumn{clear:none;float:left}.has-panel .cms-content-tools.blog-admin-sidebar{width:280px;border-right:0;border-left:1px solid #c0c0c2;position:absolute!important;right:0;top:0;height:100%}.has-panel .cms-content-tools.blog-admin-sidebar .cms-panel-toggle a{text-align:left;margin:0}.has-panel .cms-content-tools.blog-admin-sidebar .cms-panel-toggle.south{border-top:1px solid #aaa}.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer{width:100%;padding-right:280px;position:absolute;height:100%;overflow-y:hidden;overflow-x:hidden;-webkit-box-sizing:border-box;box-sizing:border-box}.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer>.ss-tabset{position:relative;overflow:auto;height:100%;width:100%}.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer>.ss-tabset #Title label{float:none}.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer>.ss-tabset #Title .middleColumn,.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer>.ss-tabset #Title input{width:100%;max-width:100%;margin-left:0}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field+.field{margin-top:10px}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.urlsegment .preview{padding-top:0;line-height:25px}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.urlsegment .edit{float:right}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.datetime>.middleColumn>.date{width:60%}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.datetime>.middleColumn>.time{width:36%;float:right}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.datetime>.middleColumn .middleColumn,.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.datetime>.middleColumn input{width:100%}.has-panel .cms-content-tools.blog-admin-sidebar.collapsed~.blog-admin-outer{padding-right:41px}.has-panel .cms-content-tools.blog-admin-sidebar.collapsed~.blog-admin-outer #Root_Main{margin-right:15px}.has-panel .cms-content-tools.blog-admin-sidebar.cms-content-tools .cms-panel-content{width:auto}.toggle-description{display:inline-block;font-size:1.2rem;width:20px;height:20px;margin-top:1px;cursor:pointer}.middleColumn.toggle-description-correct-middle{margin-left:0;float:left;width:416px}.tab-content .field p.toggle-description-correct-right{display:inline-block;margin-left:0;padding-left:0;clear:none;float:left}.description.toggle-description-correct-description{width:416px;padding:12px 0}.custom-summary .ui-accordion-content,.custom-summary .ui-accordion-content .field{padding:0}.custom-summary .ui-icon-triangle-1-e{background-position:-16px -128px}.cms table.ss-gridfield-table tr td.MergeAction{width:225px}.cms table.ss-gridfield-table tr td.MergeAction a{display:block;height:100%;width:100%}.cms table.ss-gridfield-table tr td.MergeAction select{width:150px}.blog-cms-categorisation .toolbar--content{margin-top:0}.blog-cms-categorisation .MergeActionReveal:after{content:"@";font-family:silverstripe;display:inline-block;position:relative;margin-left:10px;top:3px}.blog-cms-categorisation .blog-merge-action{margin-top:5px}
|
.no-sidebar .content-container.size3of4{width:75%}.blog-entry .post-image img{width:98.75%}.blog-sidebar .WidgetHolder ul{margin-left:0}.blog-sidebar .WidgetHolder ul li{list-style-type:none}ul.blogTagCloud{list-style-type:none;clear:both}ul.blogTagCloud li{float:left;display:inline;padding-right:8px}ul.blogTagCloud li a span{float:left;line-height:30px;text-align:center;padding:0}ul.blogTagCloud .tagCount10{font-size:26pt}ul.blogTagCloud .tagCount9{font-size:24pt}ul.blogTagCloud .tagCount8{font-size:22pt}ul.blogTagCloud .tagCount7{font-size:20pt}ul.blogTagCloud .tagCount6{font-size:18pt}ul.blogTagCloud .tagCount5{font-size:16pt}ul.blogTagCloud .tagCount4{font-size:14pt}ul.blogTagCloud .tagCount3{font-size:12pt}ul.blogTagCloud .tagCount2{font-size:10pt}ul.blogTagCloud .tagCount1{font-size:8pt}#FeaturedImage .middleColumn{clear:none;float:left}.has-panel .cms-content-tools.blog-admin-sidebar{width:280px;border-right:0;border-left:1px solid #c0c0c2;position:absolute !important;right:0;top:0;height:100%}.has-panel .cms-content-tools.blog-admin-sidebar .cms-panel-toggle a{text-align:left;margin:0}.has-panel .cms-content-tools.blog-admin-sidebar .cms-panel-toggle.south{border-top:1px solid #aaa}.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer{width:100%;padding-right:280px;position:absolute;height:100%;overflow-y:hidden;overflow-x:hidden;box-sizing:border-box}.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer>.ss-tabset{position:relative;overflow:auto;height:100%;width:100%}.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer>.ss-tabset #Title label{float:none}.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer>.ss-tabset #Title .middleColumn,.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer>.ss-tabset #Title input{width:100%;max-width:100%;margin-left:0}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field+.field{margin-top:10px}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.urlsegment .preview{padding-top:0;line-height:25px}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.urlsegment .edit{float:right}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.datetime>.middleColumn>.date{width:60%}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.datetime>.middleColumn>.time{width:36%;float:right}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.datetime>.middleColumn .middleColumn,.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.datetime>.middleColumn input{width:100%}.has-panel .cms-content-tools.blog-admin-sidebar.collapsed~.blog-admin-outer{padding-right:41px}.has-panel .cms-content-tools.blog-admin-sidebar.collapsed~.blog-admin-outer #Root_Main{margin-right:15px}.has-panel .cms-content-tools.blog-admin-sidebar.cms-content-tools .cms-panel-content{width:auto}.toggle-description{display:inline-block;font-size:1.2rem;width:20px;height:20px;margin-top:1px;cursor:pointer}.middleColumn.toggle-description-correct-middle{margin-left:0;float:left;width:416px}.tab-content .field p.toggle-description-correct-right{display:inline-block;margin-left:0;padding-left:0;clear:none;float:left}.description.toggle-description-correct-description{width:416px;padding:12px 0}.custom-summary .ui-accordion-content,.custom-summary .ui-accordion-content .field{padding:0}.cms table.ss-gridfield-table tr td.MergeAction{width:225px}.cms table.ss-gridfield-table tr td.MergeAction a{display:block;height:100%;width:100%}.cms table.ss-gridfield-table tr td.MergeAction select{width:150px}.blog-cms-categorisation .toolbar--content{margin-top:0}.blog-cms-categorisation .MergeActionReveal:after{content:"@";font-family:silverstripe;display:inline-block;position:relative;margin-left:10px;top:3px}.blog-cms-categorisation .blog-merge-action{margin-top:5px}
|
||||||
|
@ -2,141 +2,141 @@
|
|||||||
import jQuery from 'jquery';
|
import jQuery from 'jquery';
|
||||||
|
|
||||||
jQuery.entwine('ss', ($) => {
|
jQuery.entwine('ss', ($) => {
|
||||||
/**
|
/**
|
||||||
* The page success/error message sits outside of the html block
|
* The page success/error message sits outside of the html block
|
||||||
* containing the sidebar and cms fields. This means it overflows
|
* containing the sidebar and cms fields. This means it overflows
|
||||||
* underneath the sidebar.
|
* underneath the sidebar.
|
||||||
*
|
*
|
||||||
* @see https://github.com/silverstripe/silverstripe-blog/issues/210
|
* @see https://github.com/silverstripe/silverstripe-blog/issues/210
|
||||||
*/
|
*/
|
||||||
$('.cms-content-fields > #Form_EditForm_error').entwine({
|
$('.cms-content-fields > #Form_EditForm_error').entwine({
|
||||||
onadd() {
|
onadd() {
|
||||||
const $target = $('.blog-admin-outer');
|
const $target = $('.blog-admin-outer');
|
||||||
if ($target.length === 1) {
|
if ($target.length === 1) {
|
||||||
$target.prepend(this);
|
$target.prepend(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register expandable help text functions with fields.
|
* Register expandable help text functions with fields.
|
||||||
*/
|
*/
|
||||||
$('.toggle-description').entwine({
|
$('.toggle-description').entwine({
|
||||||
onadd() {
|
onadd() {
|
||||||
const $this = $(this);
|
const $this = $(this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevent multiple events being added.
|
* Prevent multiple events being added.
|
||||||
*/
|
*/
|
||||||
if ($this.hasClass('toggle-description-enabled')) {
|
if ($this.hasClass('toggle-description-enabled')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this.addClass('toggle-description-enabled');
|
$this.addClass('toggle-description-enabled');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle next description when button is clicked.
|
* Toggle next description when button is clicked.
|
||||||
*/
|
*/
|
||||||
let shown = false;
|
let shown = false;
|
||||||
const $helpInfo = $this.closest('.field').find('.form-text');
|
const $helpInfo = $this.closest('.field').find('.form-text');
|
||||||
|
|
||||||
$this.on('click', () => {
|
$this.on('click', () => {
|
||||||
$helpInfo[shown ? 'hide' : 'show']();
|
$helpInfo[shown ? 'hide' : 'show']();
|
||||||
$this.toggleClass('toggle-description-shown');
|
$this.toggleClass('toggle-description-shown');
|
||||||
shown = !shown;
|
shown = !shown;
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hide next description by default.
|
* Hide next description by default.
|
||||||
*/
|
*/
|
||||||
$helpInfo.hide();
|
$helpInfo.hide();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add classes to correct inherited layout issues in a small context.
|
* Add classes to correct inherited layout issues in a small context.
|
||||||
*/
|
*/
|
||||||
$this.parent().addClass('toggle-description-correct-right');
|
$this.parent().addClass('toggle-description-correct-right');
|
||||||
$this.parent().prev('.middleColumn').addClass('toggle-description-correct-middle');
|
$this.parent().prev('.middleColumn').addClass('toggle-description-correct-middle');
|
||||||
$this.parent().next('.description').addClass('toggle-description-correct-description');
|
$this.parent().next('.description').addClass('toggle-description-correct-description');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom merge actions for tags and categories
|
* Custom merge actions for tags and categories
|
||||||
*/
|
*/
|
||||||
$('.MergeAction').entwine({
|
$('.MergeAction').entwine({
|
||||||
onadd() {
|
onadd() {
|
||||||
const $this = $(this);
|
const $this = $(this);
|
||||||
|
|
||||||
$this.on('click', 'select', () => false);
|
$this.on('click', 'select', () => false);
|
||||||
|
|
||||||
$this.children('button').each((i, button) => {
|
$this.children('button').each((i, button) => {
|
||||||
const $button = $(button);
|
const $button = $(button);
|
||||||
const $select = $button.prev('select');
|
const $select = $button.prev('select');
|
||||||
|
|
||||||
$button.before(`<input type="hidden" name="${$button.attr('data-target')}" value="${$select.val()}" />`);
|
$button.before(`<input type="hidden" name="${$button.attr('data-target')}" value="${$select.val()}" />`);
|
||||||
});
|
});
|
||||||
|
|
||||||
$this.on('change', 'select', (e) => {
|
$this.on('change', 'select', (e) => {
|
||||||
const $target = $(e.target);
|
const $target = $(e.target);
|
||||||
|
|
||||||
$target.next('input').val($target.val());
|
$target.next('input').val($target.val());
|
||||||
});
|
});
|
||||||
|
|
||||||
$this.children('button, select').hide();
|
$this.children('button, select').hide();
|
||||||
|
|
||||||
$this.on('click', '.MergeActionReveal', (e) => {
|
$this.on('click', '.MergeActionReveal', (e) => {
|
||||||
const $target = $(e.target);
|
const $target = $(e.target);
|
||||||
|
|
||||||
$target.parent().children('button, select').show();
|
$target.parent().children('button, select').show();
|
||||||
$target.hide();
|
$target.hide();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Customise the cms-panel behaviour for blog sidebar
|
* Customise the cms-panel behaviour for blog sidebar
|
||||||
*
|
*
|
||||||
* see LeftAndMain.Panel.js for base behaviour
|
* see LeftAndMain.Panel.js for base behaviour
|
||||||
*/
|
*/
|
||||||
$('.blog-admin-sidebar.cms-panel').entwine({
|
$('.blog-admin-sidebar.cms-panel').entwine({
|
||||||
MinInnerWidth: 620,
|
MinInnerWidth: 620,
|
||||||
onadd() {
|
onadd() {
|
||||||
this._super();
|
this._super();
|
||||||
this.updateLayout();
|
this.updateLayout();
|
||||||
|
|
||||||
// Contract panel if it's open and the left hand column is smaller than the minimum
|
// Contract panel if it's open and the left hand column is smaller than the minimum
|
||||||
if (!this.hasClass('collapsed') && ($('.blog-admin-outer').width() < this.getMinInnerWidth())) {
|
if (!this.hasClass('collapsed') && ($('.blog-admin-outer').width() < this.getMinInnerWidth())) {
|
||||||
this.collapsePanel();
|
this.collapsePanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
const onresize = () => {
|
const onresize = () => {
|
||||||
this.updateLayout();
|
this.updateLayout();
|
||||||
};
|
};
|
||||||
onresize.bind(this);
|
onresize.bind(this);
|
||||||
|
|
||||||
window.onresize = onresize;
|
window.onresize = onresize;
|
||||||
},
|
},
|
||||||
togglePanel(bool, silent) {
|
togglePanel(bool, silent) {
|
||||||
this._super(bool, silent);
|
this._super(bool, silent);
|
||||||
this.updateLayout();
|
this.updateLayout();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Adjust minimum width of content to account for extra panel
|
* Adjust minimum width of content to account for extra panel
|
||||||
*
|
*
|
||||||
* @returns {undefined}
|
* @returns {undefined}
|
||||||
*/
|
*/
|
||||||
updateLayout() {
|
updateLayout() {
|
||||||
$(this).css('height', '100%');
|
$(this).css('height', '100%');
|
||||||
const currentHeight = $(this).outerHeight();
|
const currentHeight = $(this).outerHeight();
|
||||||
const bottomHeight = $('.cms-content-actions').eq(0).outerHeight();
|
const bottomHeight = $('.cms-content-actions').eq(0).outerHeight();
|
||||||
$(this).css('height', `${currentHeight - bottomHeight}px`);
|
$(this).css('height', `${currentHeight - bottomHeight}px`);
|
||||||
$(this).css('bottom', `${bottomHeight}px`);
|
$(this).css('bottom', `${bottomHeight}px`);
|
||||||
|
|
||||||
$('.cms-container').updateLayoutOptions({
|
$('.cms-container').updateLayoutOptions({
|
||||||
minContentWidth: 820 + this.width()
|
minContentWidth: 820 + this.width()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import jQuery from 'jquery';
|
import jQuery from 'jquery';
|
||||||
|
|
||||||
jQuery.entwine('ss', ($) => {
|
jQuery.entwine('ss', ($) => {
|
||||||
/**
|
/**
|
||||||
* Prevent the CMS hijacking the return key
|
* Prevent the CMS hijacking the return key
|
||||||
*/
|
*/
|
||||||
$('.add-existing-autocompleter input.text').entwine({
|
$('.add-existing-autocompleter input.text').entwine({
|
||||||
onkeydown(e) {
|
onkeydown(e) {
|
||||||
if (e.which === 13) {
|
if (e.which === 13) {
|
||||||
const $parent = $(this).parents('.add-existing-autocompleter');
|
const $parent = $(this).parents('.add-existing-autocompleter');
|
||||||
$parent.find('button[type="submit"]').click();
|
$parent.find('button[type="submit"]').click();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -142,11 +142,6 @@
|
|||||||
.ui-accordion-content .field {
|
.ui-accordion-content .field {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change the caret to a plus icon
|
|
||||||
.ui-icon-triangle-1-e {
|
|
||||||
background-position: -16px -128px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cms table.ss-gridfield-table {
|
.cms table.ss-gridfield-table {
|
||||||
|
@ -8,19 +8,21 @@
|
|||||||
],
|
],
|
||||||
"type": "silverstripe-vendormodule",
|
"type": "silverstripe-vendormodule",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.4 || ^8.0",
|
"php": "^8.1",
|
||||||
"silverstripe/cms": "^4.0",
|
"silverstripe/cms": "^5",
|
||||||
"silverstripe/lumberjack": "^2.0",
|
"silverstripe/lumberjack": "^3.0",
|
||||||
"silverstripe/tagfield": "^2.0",
|
"silverstripe/tagfield": "^3.0",
|
||||||
"silverstripe/assets": "^1.0",
|
"silverstripe/assets": "^2.0",
|
||||||
"silverstripe/asset-admin": "^1.0"
|
"silverstripe/asset-admin": "^2.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"silverstripe/recipe-testing": "^2",
|
"silverstripe/recipe-testing": "^3",
|
||||||
"squizlabs/php_codesniffer": "^3.0",
|
"squizlabs/php_codesniffer": "^3",
|
||||||
"silverstripe/widgets": "^2",
|
"silverstripe/widgets": "^3",
|
||||||
"silverstripe/comments": "^3.7",
|
"silverstripe/comments": "^4",
|
||||||
"silverstripe/content-widget": "^2"
|
"silverstripe/content-widget": "^3",
|
||||||
|
"silverstripe/standards": "^1",
|
||||||
|
"phpstan/extension-installer": "^1.3"
|
||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"expose": [
|
"expose": [
|
||||||
@ -55,4 +57,4 @@
|
|||||||
},
|
},
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
"prefer-stable": true
|
"prefer-stable": true
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ en:
|
|||||||
Add: 'Add {name}'
|
Add: 'Add {name}'
|
||||||
AddFail: 'Unable to save {class} to the database.'
|
AddFail: 'Unable to save {class} to the database.'
|
||||||
ButtonName: '{name}'
|
ButtonName: '{name}'
|
||||||
PermissionFail: 'You don''t have permission to create a {class}.'
|
PermissionFail: "You don't have permission to create a {class}."
|
||||||
SilverStripe\Blog\Forms\GridField\GridFieldBlogPostState:
|
SilverStripe\Blog\Forms\GridField\GridFieldBlogPostState:
|
||||||
Draft: 'Saved as Draft on {date}'
|
Draft: 'Saved as Draft on {date}'
|
||||||
Modified: Modified
|
Modified: Modified
|
||||||
@ -47,7 +47,7 @@ en:
|
|||||||
PostedIn: 'Posted in'
|
PostedIn: 'Posted in'
|
||||||
PostsByUser: 'Posts by {firstname} {surname} for {title}'
|
PostsByUser: 'Posts by {firstname} {surname} for {title}'
|
||||||
PostsPerPage: 'Posts Per Page'
|
PostsPerPage: 'Posts Per Page'
|
||||||
ReadMoreAbout: 'Read more about ''{title}''...'
|
ReadMoreAbout: "Read more about '{title}'..."
|
||||||
SINGULARNAME: Blog
|
SINGULARNAME: Blog
|
||||||
Tag: Tag
|
Tag: Tag
|
||||||
Tagged: Tagged
|
Tagged: Tagged
|
||||||
@ -85,7 +85,7 @@ en:
|
|||||||
SilverStripe\Blog\Model\BlogPost:
|
SilverStripe\Blog\Model\BlogPost:
|
||||||
AUTHOR: Author
|
AUTHOR: Author
|
||||||
AdditionalCredits: 'Additional Credits'
|
AdditionalCredits: 'Additional Credits'
|
||||||
AdditionalCredits_Description: 'If some authors of this post don''t have CMS access, enter their name(s) here. You can separate multiple names with a comma.'
|
AdditionalCredits_Description: "If some authors of this post don't have CMS access, enter their name(s) here. You can separate multiple names with a comma."
|
||||||
Authors: Authors
|
Authors: Authors
|
||||||
CUSTOMSUMMARY: 'Add A Custom Summary'
|
CUSTOMSUMMARY: 'Add A Custom Summary'
|
||||||
Categories: Categories
|
Categories: Categories
|
||||||
|
20
package.json
20
package.json
@ -1,9 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "silverstripe-blog",
|
"name": "silverstripe-blog",
|
||||||
"version": "3.0.0",
|
|
||||||
"description": "A fresh take on blogging in Silverstripe set out to tackle the issue of a cluttered Site Tree",
|
"description": "A fresh take on blogging in Silverstripe set out to tackle the issue of a cluttered Site Tree",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yarn && yarn lint && NODE_ENV=production webpack -p --bail --progress",
|
"build": "yarn && yarn lint && rm -rf client/dist/* && NODE_ENV=production webpack --mode production --bail --progress",
|
||||||
"dev": "NODE_ENV=development webpack --progress",
|
"dev": "NODE_ENV=development webpack --progress",
|
||||||
"watch": "NODE_ENV=development webpack --watch --progress",
|
"watch": "NODE_ENV=development webpack --watch --progress",
|
||||||
"css": "WEBPACK_CHILD=css npm run build",
|
"css": "WEBPACK_CHILD=css npm run build",
|
||||||
@ -28,11 +27,16 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/silverstripe/silverstripe-blog#readme",
|
"homepage": "https://github.com/silverstripe/silverstripe-blog#readme",
|
||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"peerDependencies": {
|
|
||||||
"jquery": "^3"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@silverstripe/eslint-config": "^0.0.5",
|
"@silverstripe/eslint-config": "^1.1.0",
|
||||||
"@silverstripe/webpack-config": "^1.3"
|
"@silverstripe/webpack-config": "^2.0.0",
|
||||||
}
|
"webpack": "^5.74.0",
|
||||||
|
"webpack-cli": "^5.0.0"
|
||||||
|
},
|
||||||
|
"resolutions": {
|
||||||
|
"colors": "1.4.0"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"defaults"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
3
phpstan.neon.dist
Normal file
3
phpstan.neon.dist
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
parameters:
|
||||||
|
paths:
|
||||||
|
- src
|
@ -226,7 +226,6 @@ class GridFieldAddByDBField implements GridField_ActionProvider, GridField_HTMLP
|
|||||||
'add',
|
'add',
|
||||||
'add'
|
'add'
|
||||||
);
|
);
|
||||||
$addAction->setAttribute('data-icon', 'add');
|
|
||||||
$addAction->addExtraClass('btn btn-primary');
|
$addAction->addExtraClass('btn btn-primary');
|
||||||
|
|
||||||
$forTemplate = ArrayData::create([]);
|
$forTemplate = ArrayData::create([]);
|
||||||
|
@ -31,11 +31,11 @@ use SilverStripe\View\Requirements;
|
|||||||
/**
|
/**
|
||||||
* Blog Holder
|
* Blog Holder
|
||||||
*
|
*
|
||||||
* @method HasManyList Tags() List of tags in this blog
|
* @method HasManyList<BlogCategory> Categories()
|
||||||
* @method HasManyList Categories() List of categories in this blog
|
* @method ManyManyList<Member> Contributors()
|
||||||
* @method ManyManyList Editors() List of editors
|
* @method ManyManyList<Member> Editors()
|
||||||
* @method ManyManyList Writers() List of writers
|
* @method HasManyList<BlogTag> Tags()
|
||||||
* @method ManyManyList Contributors() List of contributors
|
* @method ManyManyList<Member> Writers()
|
||||||
*/
|
*/
|
||||||
class Blog extends Page implements PermissionProvider
|
class Blog extends Page implements PermissionProvider
|
||||||
{
|
{
|
||||||
@ -533,7 +533,7 @@ class Blog extends Page implements PermissionProvider
|
|||||||
* @param null|int $month
|
* @param null|int $month
|
||||||
* @param null|int $day
|
* @param null|int $day
|
||||||
*
|
*
|
||||||
* @return DataList
|
* @return DataList<BlogPost>
|
||||||
*/
|
*/
|
||||||
public function getArchivedBlogPosts($year, $month = null, $day = null)
|
public function getArchivedBlogPosts($year, $month = null, $day = null)
|
||||||
{
|
{
|
||||||
@ -574,7 +574,7 @@ class Blog extends Page implements PermissionProvider
|
|||||||
/**
|
/**
|
||||||
* Return blog posts.
|
* Return blog posts.
|
||||||
*
|
*
|
||||||
* @return DataList of BlogPost objects
|
* @return DataList<BlogPost> of BlogPost objects
|
||||||
*/
|
*/
|
||||||
public function getBlogPosts()
|
public function getBlogPosts()
|
||||||
{
|
{
|
||||||
|
@ -7,12 +7,10 @@ use SilverStripe\ORM\DataObject;
|
|||||||
/**
|
/**
|
||||||
* A blog category for generalising blog posts.
|
* A blog category for generalising blog posts.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @method Blog Blog()
|
|
||||||
*
|
|
||||||
* @property string $Title
|
* @property string $Title
|
||||||
* @property string $URLSegment
|
* @property string $URLSegment
|
||||||
* @property int $BlogID
|
* @property int $BlogID
|
||||||
|
* @method Blog Blog()
|
||||||
*/
|
*/
|
||||||
class BlogCategory extends DataObject implements CategorisationObject
|
class BlogCategory extends DataObject implements CategorisationObject
|
||||||
{
|
{
|
||||||
@ -33,6 +31,8 @@ class BlogCategory extends DataObject implements CategorisationObject
|
|||||||
*/
|
*/
|
||||||
private static $table_name = 'BlogCategory';
|
private static $table_name = 'BlogCategory';
|
||||||
|
|
||||||
|
private static bool $allow_urlsegment_multibyte = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
|
@ -2,10 +2,13 @@
|
|||||||
|
|
||||||
namespace SilverStripe\Blog\Model;
|
namespace SilverStripe\Blog\Model;
|
||||||
|
|
||||||
|
use SilverStripe\Comments\Model\Comment;
|
||||||
use SilverStripe\ORM\DataExtension;
|
use SilverStripe\ORM\DataExtension;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds Blog specific behaviour to Comment.
|
* Adds Blog specific behaviour to Comment.
|
||||||
|
*
|
||||||
|
* @extends DataExtension<Comment>
|
||||||
*/
|
*/
|
||||||
class BlogCommentExtension extends DataExtension
|
class BlogCommentExtension extends DataExtension
|
||||||
{
|
{
|
||||||
|
@ -11,9 +11,15 @@ use SilverStripe\ORM\DataList;
|
|||||||
use SilverStripe\ORM\FieldType\DBDatetime;
|
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||||
use SilverStripe\ORM\PaginatedList;
|
use SilverStripe\ORM\PaginatedList;
|
||||||
use SilverStripe\Security\Member;
|
use SilverStripe\Security\Member;
|
||||||
|
use SilverStripe\Blog\Model\BlogTag;
|
||||||
|
use SilverStripe\Blog\Model\BlogCategory;
|
||||||
use SilverStripe\View\Parsers\URLSegmentFilter;
|
use SilverStripe\View\Parsers\URLSegmentFilter;
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
|
use SilverStripe\ORM\SS_List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends PageController<Blog>
|
||||||
|
*/
|
||||||
class BlogController extends PageController
|
class BlogController extends PageController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -56,7 +62,7 @@ class BlogController extends PageController
|
|||||||
/**
|
/**
|
||||||
* The current Blog Post DataList query.
|
* The current Blog Post DataList query.
|
||||||
*
|
*
|
||||||
* @var DataList
|
* @var DataList<BlogPost>
|
||||||
*/
|
*/
|
||||||
protected $blogPosts;
|
protected $blogPosts;
|
||||||
|
|
||||||
@ -65,9 +71,6 @@ class BlogController extends PageController
|
|||||||
*/
|
*/
|
||||||
public function index(HTTPRequest $request)
|
public function index(HTTPRequest $request)
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var Blog $dataRecord
|
|
||||||
*/
|
|
||||||
$dataRecord = $this->dataRecord;
|
$dataRecord = $this->dataRecord;
|
||||||
|
|
||||||
$this->blogPosts = $dataRecord->getBlogPosts();
|
$this->blogPosts = $dataRecord->getBlogPosts();
|
||||||
@ -126,7 +129,7 @@ class BlogController extends PageController
|
|||||||
/**
|
/**
|
||||||
* Get posts related to the current Member profile.
|
* Get posts related to the current Member profile.
|
||||||
*
|
*
|
||||||
* @return null|DataList
|
* @return null|DataList<BlogPost>
|
||||||
*/
|
*/
|
||||||
public function getCurrentProfilePosts()
|
public function getCurrentProfilePosts()
|
||||||
{
|
{
|
||||||
@ -268,6 +271,7 @@ class BlogController extends PageController
|
|||||||
$tag = $this->request->param('Tag');
|
$tag = $this->request->param('Tag');
|
||||||
if ($tag) {
|
if ($tag) {
|
||||||
$filter = URLSegmentFilter::create();
|
$filter = URLSegmentFilter::create();
|
||||||
|
$filter->setAllowMultibyte(BlogTag::config()->get('allow_urlsegment_multibyte'));
|
||||||
// url encode unless it's multibyte (already pre-encoded in the database)
|
// url encode unless it's multibyte (already pre-encoded in the database)
|
||||||
// see https://github.com/silverstripe/silverstripe-cms/pull/2384
|
// see https://github.com/silverstripe/silverstripe-cms/pull/2384
|
||||||
if (!$filter->getAllowMultibyte()) {
|
if (!$filter->getAllowMultibyte()) {
|
||||||
@ -318,6 +322,7 @@ class BlogController extends PageController
|
|||||||
$category = $this->request->param('Category');
|
$category = $this->request->param('Category');
|
||||||
if ($category) {
|
if ($category) {
|
||||||
$filter = URLSegmentFilter::create();
|
$filter = URLSegmentFilter::create();
|
||||||
|
$filter->setAllowMultibyte(BlogCategory::config()->get('allow_urlsegment_multibyte'));
|
||||||
// url encode unless it's multibyte (already pre-encoded in the database)
|
// url encode unless it's multibyte (already pre-encoded in the database)
|
||||||
// see https://github.com/silverstripe/silverstripe-cms/pull/2384
|
// see https://github.com/silverstripe/silverstripe-cms/pull/2384
|
||||||
if (!$filter->getAllowMultibyte()) {
|
if (!$filter->getAllowMultibyte()) {
|
||||||
@ -439,7 +444,7 @@ class BlogController extends PageController
|
|||||||
/**
|
/**
|
||||||
* Returns a list of paginated blog posts based on the BlogPost dataList.
|
* Returns a list of paginated blog posts based on the BlogPost dataList.
|
||||||
*
|
*
|
||||||
* @return PaginatedList
|
* @return PaginatedList<SS_List, BlogPost>
|
||||||
*/
|
*/
|
||||||
public function PaginatedList()
|
public function PaginatedList()
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,6 @@ use SilverStripe\Versioned\Versioned;
|
|||||||
/**
|
/**
|
||||||
* This class is responsible for filtering the SiteTree when necessary and also overlaps into
|
* This class is responsible for filtering the SiteTree when necessary and also overlaps into
|
||||||
* filtering only published posts.
|
* filtering only published posts.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class BlogFilter extends Lumberjack
|
class BlogFilter extends Lumberjack
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,7 @@ use SilverStripe\Forms\GridField\GridFieldAddNewButton;
|
|||||||
use SilverStripe\Forms\Tab;
|
use SilverStripe\Forms\Tab;
|
||||||
use SilverStripe\Forms\TextareaField;
|
use SilverStripe\Forms\TextareaField;
|
||||||
use SilverStripe\ORM\DataExtension;
|
use SilverStripe\ORM\DataExtension;
|
||||||
|
use SilverStripe\ORM\ManyManyList;
|
||||||
use SilverStripe\Security\Member;
|
use SilverStripe\Security\Member;
|
||||||
use SilverStripe\View\Parsers\URLSegmentFilter;
|
use SilverStripe\View\Parsers\URLSegmentFilter;
|
||||||
use SilverStripe\View\Requirements;
|
use SilverStripe\View\Requirements;
|
||||||
@ -17,6 +18,10 @@ use SilverStripe\View\Requirements;
|
|||||||
/**
|
/**
|
||||||
* This class is responsible for add Blog specific behaviour to Members.
|
* This class is responsible for add Blog specific behaviour to Members.
|
||||||
*
|
*
|
||||||
|
* @method ManyManyList<BlogPost> BlogPosts()
|
||||||
|
* @method Image BlogProfileImage()
|
||||||
|
*
|
||||||
|
* @extends DataExtension<Member>
|
||||||
*/
|
*/
|
||||||
class BlogMemberExtension extends DataExtension
|
class BlogMemberExtension extends DataExtension
|
||||||
{
|
{
|
||||||
|
@ -21,7 +21,7 @@ trait BlogObject
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param int|array|null $id Optional ID(s) for parent of this relation, if not the current record
|
* @param int|array|null $id Optional ID(s) for parent of this relation, if not the current record
|
||||||
* @return DataList
|
* @return DataList<BlogPost>
|
||||||
*/
|
*/
|
||||||
public function BlogPosts($id = null)
|
public function BlogPosts($id = null)
|
||||||
{
|
{
|
||||||
@ -181,12 +181,7 @@ trait BlogObject
|
|||||||
{
|
{
|
||||||
$increment = (int) $increment;
|
$increment = (int) $increment;
|
||||||
$filter = URLSegmentFilter::create();
|
$filter = URLSegmentFilter::create();
|
||||||
|
$filter->setAllowMultibyte($this->config()->get('allow_urlsegment_multibyte') ?? true);
|
||||||
// Setting this to on. Because of the UI flow, it would be quite a lot of work
|
|
||||||
// to support turning this off. (ie. the add by title flow would not work).
|
|
||||||
// If this becomes a problem we can approach it then.
|
|
||||||
// @see https://github.com/silverstripe/silverstripe-blog/issues/376
|
|
||||||
$filter->setAllowMultibyte(true);
|
|
||||||
|
|
||||||
$this->URLSegment = $filter->filter($this->Title);
|
$this->URLSegment = $filter->filter($this->Title);
|
||||||
|
|
||||||
|
@ -31,17 +31,15 @@ use SilverStripe\View\Requirements;
|
|||||||
/**
|
/**
|
||||||
* An individual blog post.
|
* An individual blog post.
|
||||||
*
|
*
|
||||||
* @method ManyManyList Categories()
|
|
||||||
* @method ManyManyList Tags()
|
|
||||||
* @method ManyManyList Authors()
|
|
||||||
* @method Blog Parent()
|
|
||||||
* @method Image FeaturedImage()
|
|
||||||
*
|
|
||||||
* @property string $PublishDate
|
* @property string $PublishDate
|
||||||
* @property string $AuthorNames
|
* @property string $AuthorNames
|
||||||
* @property string $Summary
|
* @property string $Summary
|
||||||
* @property int $ParentID
|
* @property int $ParentID
|
||||||
* @property int $FeaturedImageID
|
* @property int $FeaturedImageID
|
||||||
|
* @method ManyManyList<Member> Authors()
|
||||||
|
* @method ManyManyList<BlogCategory> Categories()
|
||||||
|
* @method Image FeaturedImage()
|
||||||
|
* @method ManyManyList<BlogTag> Tags()
|
||||||
*/
|
*/
|
||||||
class BlogPost extends Page
|
class BlogPost extends Page
|
||||||
{
|
{
|
||||||
@ -334,8 +332,6 @@ class BlogPost extends Page
|
|||||||
? $parent->Tags()
|
? $parent->Tags()
|
||||||
: BlogTag::get();
|
: BlogTag::get();
|
||||||
|
|
||||||
// @todo: Reimplement the sidebar
|
|
||||||
// $options = BlogAdminSidebar::create(
|
|
||||||
$fields->addFieldsToTab(
|
$fields->addFieldsToTab(
|
||||||
'Root.PostOptions',
|
'Root.PostOptions',
|
||||||
[
|
[
|
||||||
@ -360,9 +356,6 @@ class BlogPost extends Page
|
|||||||
$authorNames
|
$authorNames
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
// )->setTitle('Post Options');
|
|
||||||
// $options->setName('blog-admin-sidebar');
|
|
||||||
// $fields->insertBefore($options, 'Root');
|
|
||||||
|
|
||||||
$fields->fieldByName('Root.PostOptions')
|
$fields->fieldByName('Root.PostOptions')
|
||||||
->setTitle(_t(__CLASS__ . '.PostOptions', 'Post Options'));
|
->setTitle(_t(__CLASS__ . '.PostOptions', 'Post Options'));
|
||||||
|
@ -4,6 +4,9 @@ namespace SilverStripe\Blog\Model;
|
|||||||
|
|
||||||
use PageController;
|
use PageController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends PageController<BlogPost>
|
||||||
|
*/
|
||||||
class BlogPostController extends PageController
|
class BlogPostController extends PageController
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ use SilverStripe\Forms\CheckboxField;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a checkbox field for featured blog posts widget.
|
* Adds a checkbox field for featured blog posts widget.
|
||||||
|
*
|
||||||
|
* @extends DataExtension<BlogPost>
|
||||||
*/
|
*/
|
||||||
class BlogPostFeaturedExtension extends DataExtension
|
class BlogPostFeaturedExtension extends DataExtension
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@ use SilverStripe\Versioned\Versioned;
|
|||||||
* This is responsible for filtering only published posts to users who do not have permission to
|
* This is responsible for filtering only published posts to users who do not have permission to
|
||||||
* view non-published posts.
|
* view non-published posts.
|
||||||
*
|
*
|
||||||
|
* @extends DataExtension<BlogPost>
|
||||||
*/
|
*/
|
||||||
class BlogPostFilter extends DataExtension
|
class BlogPostFilter extends DataExtension
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,8 @@ use SilverStripe\Security\Member;
|
|||||||
* Customise blog post to support comment notifications.
|
* Customise blog post to support comment notifications.
|
||||||
*
|
*
|
||||||
* Extends {@see BlogPost} with extensions to {@see CommentNotifiable}.
|
* Extends {@see BlogPost} with extensions to {@see CommentNotifiable}.
|
||||||
|
*
|
||||||
|
* @extends DataExtension<BlogPost>
|
||||||
*/
|
*/
|
||||||
class BlogPostNotifications extends DataExtension
|
class BlogPostNotifications extends DataExtension
|
||||||
{
|
{
|
||||||
|
@ -7,17 +7,17 @@ use SilverStripe\ORM\DataObject;
|
|||||||
/**
|
/**
|
||||||
* A blog tag for keyword descriptions of a blog post.
|
* A blog tag for keyword descriptions of a blog post.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @method Blog Blog()
|
|
||||||
*
|
|
||||||
* @property string $Title
|
* @property string $Title
|
||||||
* @property string $URLSegment
|
* @property string $URLSegment
|
||||||
* @property int $BlogID
|
* @property int $BlogID
|
||||||
|
* @method Blog Blog()
|
||||||
*/
|
*/
|
||||||
class BlogTag extends DataObject implements CategorisationObject
|
class BlogTag extends DataObject implements CategorisationObject
|
||||||
{
|
{
|
||||||
use BlogObject;
|
use BlogObject;
|
||||||
|
|
||||||
|
private static bool $allow_urlsegment_multibyte = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use an exception code so that attempted writes can continue on
|
* Use an exception code so that attempted writes can continue on
|
||||||
* duplicate errors.
|
* duplicate errors.
|
||||||
|
@ -108,7 +108,7 @@ class BlogArchiveWidget extends Widget
|
|||||||
/**
|
/**
|
||||||
* Returns a list of months where blog posts are present.
|
* Returns a list of months where blog posts are present.
|
||||||
*
|
*
|
||||||
* @return ArrayList
|
* @return ArrayList<ArrayData>
|
||||||
*/
|
*/
|
||||||
public function getArchive()
|
public function getArchive()
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace SilverStripe\Blog\Widgets;
|
namespace SilverStripe\Blog\Widgets;
|
||||||
|
|
||||||
use SilverStripe\Blog\Model\Blog;
|
use SilverStripe\Blog\Model\Blog;
|
||||||
|
use SilverStripe\Blog\Model\BlogCategory;
|
||||||
use SilverStripe\Core\Convert;
|
use SilverStripe\Core\Convert;
|
||||||
use SilverStripe\Forms\DropdownField;
|
use SilverStripe\Forms\DropdownField;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
@ -106,7 +107,7 @@ class BlogCategoriesWidget extends Widget
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return DataList
|
* @return DataList<BlogCategory>
|
||||||
*/
|
*/
|
||||||
public function getCategories()
|
public function getCategories()
|
||||||
{
|
{
|
||||||
|
@ -84,7 +84,7 @@ class BlogFeaturedPostsWidget extends Widget
|
|||||||
return $blog->getBlogPosts()
|
return $blog->getBlogPosts()
|
||||||
->filter('ID:not', Director::get_current_page()->ID)
|
->filter('ID:not', Director::get_current_page()->ID)
|
||||||
->filter('FeaturedInWidget', true)
|
->filter('FeaturedInWidget', true)
|
||||||
->sort('RAND()')
|
->shuffle()
|
||||||
->limit($this->NumberOfPosts);
|
->limit($this->NumberOfPosts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ use SilverStripe\ORM\ArrayList;
|
|||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
use SilverStripe\ORM\DB;
|
use SilverStripe\ORM\DB;
|
||||||
use SilverStripe\Widgets\Model\Widget;
|
use SilverStripe\Widgets\Model\Widget;
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
|
||||||
if (!class_exists(Widget::class)) {
|
if (!class_exists(Widget::class)) {
|
||||||
return;
|
return;
|
||||||
@ -98,7 +99,7 @@ class BlogTagsCloudWidget extends Widget
|
|||||||
foreach ($records as $record) {
|
foreach ($records as $record) {
|
||||||
$tag = DataObject::create();
|
$tag = DataObject::create();
|
||||||
$tag->TagName = $record['Title'];
|
$tag->TagName = $record['Title'];
|
||||||
$link = $bloglink.'tag/'.$record['URLSegment'];
|
$link = Controller::join_links($bloglink, 'tag', $record['URLSegment']);
|
||||||
$tag->Link = $link;
|
$tag->Link = $link;
|
||||||
if ($record['TagCount'] > $maxTagCount) {
|
if ($record['TagCount'] > $maxTagCount) {
|
||||||
$maxTagCount = $record['TagCount'];
|
$maxTagCount = $record['TagCount'];
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace SilverStripe\Blog\Widgets;
|
namespace SilverStripe\Blog\Widgets;
|
||||||
|
|
||||||
use SilverStripe\Blog\Model\Blog;
|
use SilverStripe\Blog\Model\Blog;
|
||||||
|
use SilverStripe\Blog\Model\BlogTag;
|
||||||
use SilverStripe\Core\Convert;
|
use SilverStripe\Core\Convert;
|
||||||
use SilverStripe\Forms\DropdownField;
|
use SilverStripe\Forms\DropdownField;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
@ -106,7 +107,7 @@ class BlogTagsWidget extends Widget
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return DataList
|
* @return DataList<BlogTag>
|
||||||
*/
|
*/
|
||||||
public function getTags()
|
public function getTags()
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,7 @@ Feature: Create a blog
|
|||||||
And I press the "Log in as someone else" button
|
And I press the "Log in as someone else" button
|
||||||
|
|
||||||
Scenario: Create a blog post
|
Scenario: Create a blog post
|
||||||
|
|
||||||
Given I am logged in as a member of "EDITOR" group
|
Given I am logged in as a member of "EDITOR" group
|
||||||
# Create a new blog post called "New Post"
|
# Create a new blog post called "New Post"
|
||||||
When I go to "/admin/pages"
|
When I go to "/admin/pages"
|
||||||
@ -65,8 +65,8 @@ Feature: Create a blog
|
|||||||
|
|
||||||
# Add categories and tags
|
# Add categories and tags
|
||||||
And I click the "Post Options" CMS tab
|
And I click the "Post Options" CMS tab
|
||||||
And I add "My Category" to the "Categories" tag field
|
And I add "My Category" to the "#Form_EditForm_Categories_Holder" tag field
|
||||||
And I add "My Tag" to the "Tags" tag field
|
And I add "My Tag" to the "#Form_EditForm_Tags_Holder" tag field
|
||||||
|
|
||||||
# Publish the blog post and logout
|
# Publish the blog post and logout
|
||||||
And I press the "Publish" button
|
And I press the "Publish" button
|
||||||
|
@ -11,8 +11,6 @@ class BlogFunctionalTest extends FunctionalTest
|
|||||||
{
|
{
|
||||||
protected static $fixture_file = 'BlogFunctionalTest.yml';
|
protected static $fixture_file = 'BlogFunctionalTest.yml';
|
||||||
|
|
||||||
protected static $use_draft_site = true;
|
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
Config::modify()->set(URLSegmentFilter::class, 'default_allow_multibyte', true);
|
Config::modify()->set(URLSegmentFilter::class, 'default_allow_multibyte', true);
|
||||||
@ -23,14 +21,16 @@ class BlogFunctionalTest extends FunctionalTest
|
|||||||
|
|
||||||
public function testBlogWithMultibyteUrl()
|
public function testBlogWithMultibyteUrl()
|
||||||
{
|
{
|
||||||
$result = $this->get(rawurlencode('آبید'));
|
$this->logInWithPermission('VIEW_DRAFT_CONTENT');
|
||||||
|
$result = $this->get(rawurlencode('آبید') . '?stage=Stage');
|
||||||
|
|
||||||
$this->assertEquals(200, $result->getStatusCode());
|
$this->assertEquals(200, $result->getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMemberProfileWithMultibyteUrlAndName()
|
public function testMemberProfileWithMultibyteUrlAndName()
|
||||||
{
|
{
|
||||||
$result = $this->get(rawurlencode('آبید') . '/profile/' . rawurlencode('عبّاس-آبان'));
|
$this->logInWithPermission('VIEW_DRAFT_CONTENT');
|
||||||
|
$result = $this->get(rawurlencode('آبید') . '/profile/' . rawurlencode('عبّاس-آبان') . '?stage=Stage');
|
||||||
|
|
||||||
$this->assertEquals(200, $result->getStatusCode());
|
$this->assertEquals(200, $result->getStatusCode());
|
||||||
$this->assertStringContainsString('My Blog Post', $result->getBody());
|
$this->assertStringContainsString('My Blog Post', $result->getBody());
|
||||||
@ -38,7 +38,8 @@ class BlogFunctionalTest extends FunctionalTest
|
|||||||
|
|
||||||
public function testMemberProfileWithMultibyteUrlAndEnglishName()
|
public function testMemberProfileWithMultibyteUrlAndEnglishName()
|
||||||
{
|
{
|
||||||
$result = $this->get(rawurlencode('آبید') . '/profile/bob-jones');
|
$this->logInWithPermission('VIEW_DRAFT_CONTENT');
|
||||||
|
$result = $this->get(rawurlencode('آبید') . '/profile/bob-jones' . '?stage=Stage');
|
||||||
|
|
||||||
$this->assertEquals(200, $result->getStatusCode());
|
$this->assertEquals(200, $result->getStatusCode());
|
||||||
$this->assertStringContainsString('My Blog Post', $result->getBody());
|
$this->assertStringContainsString('My Blog Post', $result->getBody());
|
||||||
|
@ -11,8 +11,6 @@ class BlogControllerFunctionalTest extends FunctionalTest
|
|||||||
{
|
{
|
||||||
protected static $fixture_file = 'BlogControllerFunctionalTest.yml';
|
protected static $fixture_file = 'BlogControllerFunctionalTest.yml';
|
||||||
|
|
||||||
protected static $use_draft_site = true;
|
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
Config::modify()->set(URLSegmentFilter::class, 'default_allow_multibyte', true);
|
Config::modify()->set(URLSegmentFilter::class, 'default_allow_multibyte', true);
|
||||||
@ -23,7 +21,8 @@ class BlogControllerFunctionalTest extends FunctionalTest
|
|||||||
|
|
||||||
public function testGetCategoriesWithMultibyteUrl()
|
public function testGetCategoriesWithMultibyteUrl()
|
||||||
{
|
{
|
||||||
$result = $this->get('my-blog/category/' . rawurlencode('آبید'));
|
$this->logInWithPermission('VIEW_DRAFT_CONTENT');
|
||||||
|
$result = $this->get('my-blog/category/' . rawurlencode('آبید') . '?stage=Stage');
|
||||||
|
|
||||||
$this->assertEquals(200, $result->getStatusCode());
|
$this->assertEquals(200, $result->getStatusCode());
|
||||||
$this->assertStringContainsString('آبید', $result->getBody());
|
$this->assertStringContainsString('آبید', $result->getBody());
|
||||||
@ -31,7 +30,8 @@ class BlogControllerFunctionalTest extends FunctionalTest
|
|||||||
|
|
||||||
public function testGetTagsWithMultibyteUrl()
|
public function testGetTagsWithMultibyteUrl()
|
||||||
{
|
{
|
||||||
$result = $this->get('my-blog/tag/' . rawurlencode('برتراند'));
|
$this->logInWithPermission('VIEW_DRAFT_CONTENT');
|
||||||
|
$result = $this->get('my-blog/tag/' . rawurlencode('برتراند') . '?stage=Stage');
|
||||||
|
|
||||||
$this->assertEquals(200, $result->getStatusCode());
|
$this->assertEquals(200, $result->getStatusCode());
|
||||||
$this->assertStringContainsString('برتراند', $result->getBody());
|
$this->assertStringContainsString('برتراند', $result->getBody());
|
||||||
|
@ -1,55 +1,31 @@
|
|||||||
const Path = require('path');
|
const Path = require('path');
|
||||||
const webpack = require('webpack');
|
const { JavascriptWebpackConfig, CssWebpackConfig } = require('@silverstripe/webpack-config');
|
||||||
// Import the core config
|
|
||||||
const webpackConfig = require('@silverstripe/webpack-config');
|
|
||||||
const {
|
|
||||||
resolveJS,
|
|
||||||
externalJS,
|
|
||||||
moduleJS,
|
|
||||||
pluginJS,
|
|
||||||
moduleCSS,
|
|
||||||
pluginCSS,
|
|
||||||
} = webpackConfig;
|
|
||||||
|
|
||||||
const ENV = process.env.NODE_ENV;
|
const ENV = process.env.NODE_ENV;
|
||||||
const PATHS = {
|
const PATHS = {
|
||||||
ROOT: Path.resolve(),
|
ROOT: Path.resolve(),
|
||||||
MODULES: 'node_modules',
|
|
||||||
FILES_PATH: '../',
|
|
||||||
THIRDPARTY: 'thirdparty',
|
|
||||||
SRC: Path.resolve('client/src'),
|
SRC: Path.resolve('client/src'),
|
||||||
DIST: Path.resolve('client/dist'),
|
DIST: Path.resolve('client/dist'),
|
||||||
};
|
};
|
||||||
|
|
||||||
const config = [
|
const config = [
|
||||||
{
|
// Main JS bundle
|
||||||
name: 'bundle',
|
new JavascriptWebpackConfig('js', PATHS, 'silverstripe/blog')
|
||||||
entry: {
|
.setEntry({
|
||||||
main: `${PATHS.SRC}/main.js`
|
main: `${PATHS.SRC}/main.js`
|
||||||
},
|
})
|
||||||
output: {
|
.mergeConfig({
|
||||||
path: PATHS.DIST,
|
output: {
|
||||||
filename: 'js/[name].bundle.js',
|
filename: 'js/[name].bundle.js',
|
||||||
},
|
},
|
||||||
devtool: (ENV !== 'production') ? 'source-map' : '',
|
})
|
||||||
resolve: resolveJS(ENV, PATHS),
|
.getConfig(),
|
||||||
externals: externalJS(ENV, PATHS),
|
// sass to css
|
||||||
module: moduleJS(ENV, PATHS),
|
new CssWebpackConfig('css', PATHS)
|
||||||
plugins: pluginJS(ENV, PATHS),
|
.setEntry({
|
||||||
},
|
main: `${PATHS.SRC}/main.scss`
|
||||||
{
|
})
|
||||||
name: 'bundle',
|
.getConfig(),
|
||||||
entry: {
|
|
||||||
main: `${PATHS.SRC}/main.scss`
|
|
||||||
},
|
|
||||||
output: {
|
|
||||||
path: PATHS.DIST,
|
|
||||||
filename: 'styles/[name].css'
|
|
||||||
},
|
|
||||||
devtool: (ENV !== 'production') ? 'source-map' : '',
|
|
||||||
module: moduleCSS(ENV, PATHS),
|
|
||||||
plugins: pluginCSS(ENV, PATHS),
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports = config;
|
module.exports = config;
|
||||||
|
Loading…
Reference in New Issue
Block a user