├── .github
├── FUNDING.yml
└── workflows
│ ├── ci.yml
│ ├── ci_pipe.yml
│ └── pr.yml
├── .gitignore
├── .infection.json
├── .php_cs.cache
├── .php_cs.php
├── .phpstan.neon
├── .shopware-extension.yml
├── AGENTS.md
├── CHANGELOG_de-DE.md
├── CHANGELOG_en-GB.md
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── bin
└── fix-cs.sh
├── composer-ci.json
├── composer.json
├── docker-compose.yml
├── easy-coding-standard.php
├── makefile
├── phpunit.autoload.php
├── phpunit.xml
├── src
├── Content
│ ├── Blog
│ │ ├── Aggregate
│ │ │ ├── BlogCategoryMappingDefinition.php
│ │ │ └── BlogEntriesTagMappingDefinition.php
│ │ ├── BlogEntitiesIndexer.php
│ │ ├── BlogEntriesCollection.php
│ │ ├── BlogEntriesDefinition.php
│ │ ├── BlogEntriesEntity.php
│ │ ├── BlogEntriesIndexingMessage.php
│ │ ├── BlogEntriesTranslation
│ │ │ ├── BlogEntriesTranslationCollection.php
│ │ │ ├── BlogEntriesTranslationDefinition.php
│ │ │ └── BlogEntriesTranslationEntity.php
│ │ ├── BlogListingFilterBuildEvent.php
│ │ ├── BlogSeoUrlListener.php
│ │ ├── BlogSeoUrlRoute.php
│ │ ├── DataResolver
│ │ │ ├── BlogCategoriesCmsElementResolver.php
│ │ │ ├── BlogCmsElementResolver.php
│ │ │ ├── BlogDetailCmsElementResolver.php
│ │ │ ├── BlogNewestListingCmsElementResolver.php
│ │ │ └── BlogSingleSelectDataResolver.php
│ │ ├── Events
│ │ │ ├── BlogIndexerEvent.php
│ │ │ ├── BlogMainFilterEvent.php
│ │ │ ├── CategoriesCriteriaEvent.php
│ │ │ └── NewestListingCriteriaEvent.php
│ │ └── Subscriber
│ │ │ └── BlogSubscriber.php
│ ├── BlogAuthor
│ │ ├── BlogAuthorCollection.php
│ │ ├── BlogAuthorDefinition.php
│ │ ├── BlogAuthorEntity.php
│ │ └── BlogAuthorTranslation
│ │ │ ├── BlogAuthorTranslationCollection.php
│ │ │ ├── BlogAuthorTranslationDefinition.php
│ │ │ └── BlogAuthorTranslationEntity.php
│ ├── BlogCategory
│ │ ├── BlogCategoryCollection.php
│ │ ├── BlogCategoryDefinition.php
│ │ ├── BlogCategoryEntity.php
│ │ ├── BlogCategoryIndexer.php
│ │ └── BlogCategoryTranslation
│ │ │ ├── BlogCategoryTranslationCollection.php
│ │ │ ├── BlogCategoryTranslationDefinition.php
│ │ │ └── BlogCategoryTranslationEntity.php
│ ├── Cms
│ │ └── DataResolver
│ │ │ └── WerklCmsSlotsDataResolver.php
│ ├── Extension
│ │ ├── LanguageExtension.php
│ │ ├── MediaExtension.php
│ │ └── SalutationExtension.php
│ └── SalesChannel
│ │ └── Suggest
│ │ └── ProductSuggestDecorated.php
├── Controller
│ ├── BlogController.php
│ ├── BlogRssController.php
│ ├── BlogSearchController.php
│ ├── CachedBlogController.php
│ ├── CachedBlogRssController.php
│ ├── CachedBlogSearchController.php
│ └── StoreApi
│ │ ├── AbstractBlogController.php
│ │ ├── BlogController.php
│ │ └── BlogControllerResponse.php
├── Core
│ └── Content
│ │ └── Sitemap
│ │ └── Provider
│ │ └── BlogUrlProvider.php
├── Migration
│ ├── Migration1559416986BlogEntries.php
│ ├── Migration1602739765AddTeaserImageColumnToBlogEntries.php
│ ├── Migration1604519670CreateWerklBlogCategoryTable.php
│ ├── Migration1604520733DefaultBlogCategorySeeder.php
│ ├── Migration1605031477CreateWerklBlogAuthorTable.php
│ ├── Migration1612160298CreatePubslihedDateColumn.php
│ ├── Migration1621260479AddVersionIdToBlogCategoryTable.php
│ ├── Migration1626760242AddCustomFieldToBlogTranslation.php
│ ├── Migration1647338771WerklBlogEntriesUpdate.php
│ ├── Migration1649322718CreateCmsPageForBlogEntries.php
│ ├── Migration1649580844AddParentVersionId.php
│ ├── Migration1702998914SetSalutationIdAuthorToNullable.php
│ ├── Migration1736010505Tags.php
│ └── Migration1744229687TranslatableTeaserImage.php
├── Page
│ ├── Blog
│ │ ├── BlogPage.php
│ │ ├── BlogPageCriteriaEvent.php
│ │ ├── BlogPageLoadedEvent.php
│ │ └── BlogPageLoader.php
│ └── Search
│ │ ├── BlogSearchPage.php
│ │ └── BlogSearchPageLoader.php
├── Resources
│ ├── app
│ │ ├── administration
│ │ │ ├── .eslintrc.json
│ │ │ ├── babel.config.json
│ │ │ ├── build
│ │ │ │ └── webpack.config.js
│ │ │ ├── package-lock.json
│ │ │ ├── package.json
│ │ │ └── src
│ │ │ │ ├── init
│ │ │ │ └── cms-page-type.init.js
│ │ │ │ ├── main.js
│ │ │ │ └── module
│ │ │ │ └── blog-module
│ │ │ │ ├── blocks
│ │ │ │ ├── categories
│ │ │ │ │ ├── component
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── werkl-cms-block-blog.html.twig
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── preview
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-cms-preview-blog-categories.html.twig
│ │ │ │ │ │ └── werkl-cms-preview-blog-categories.scss
│ │ │ │ ├── detail
│ │ │ │ │ ├── component
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── werkl-cms-block-blog-detail.html.twig
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── preview
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-cms-preview-blog-detail.html.twig
│ │ │ │ │ │ └── werkl-cms-preview-blog-detail.scss
│ │ │ │ ├── index.js
│ │ │ │ ├── listing
│ │ │ │ │ ├── component
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── werkl-cms-block-blog.html.twig
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── preview
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-cms-preview-blog-listing.html.twig
│ │ │ │ │ │ └── werkl-cms-preview-blog-listing.scss
│ │ │ │ ├── newest-listing
│ │ │ │ │ ├── component
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── werkl-cms-block-newest-listing.html.twig
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── preview
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-cms-preview-newest-listing.html.twig
│ │ │ │ │ │ └── werkl-cms-preview-newest-listing.scss
│ │ │ │ └── single-entry
│ │ │ │ │ ├── component
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── werkl-cms-block-blog-single-entry.html.twig
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── preview
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── werkl-cms-preview-blog-single-entry.html.twig
│ │ │ │ │ └── werkl-cms-preview-blog-single-entry.scss
│ │ │ │ ├── component
│ │ │ │ ├── blog-category-tree-field
│ │ │ │ │ └── index.js
│ │ │ │ ├── blog-category-tree
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── werkl-blog-category-tree.html.twig
│ │ │ │ ├── blog-extension-component-sections
│ │ │ │ │ ├── blog-extension-component-sections.html.twig
│ │ │ │ │ └── index.js
│ │ │ │ ├── blog-tree-item
│ │ │ │ │ ├── blog-tree-item.html.twig
│ │ │ │ │ └── index.js
│ │ │ │ ├── blog-vertical-tabs
│ │ │ │ │ ├── blog-vertical-tabs.html.twig
│ │ │ │ │ └── index.js
│ │ │ │ └── index.js
│ │ │ │ ├── constant
│ │ │ │ └── open-blogware.constant.js
│ │ │ │ ├── elements
│ │ │ │ ├── blog-categories
│ │ │ │ │ ├── component
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── sw-cms-el-categories.html.twig
│ │ │ │ │ │ └── sw-cms-el-categories.scss
│ │ │ │ │ ├── config
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── sw-cms-el-config-categories.html.twig
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── preview
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── sw-cms-el-preview-categories.html.twig
│ │ │ │ │ │ └── sw-cms-el-preview-categories.scss
│ │ │ │ ├── blog-detail
│ │ │ │ │ ├── component
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-blog-element-blog-detail.html.twig
│ │ │ │ │ │ └── werkl-blog-element-blog-detail.scss
│ │ │ │ │ ├── config
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── sw-cms-el-config-blog-detail.html.twig
│ │ │ │ │ │ └── sw-cms-el-config-blog-detail.scss
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── preview
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-blog-element-preview.html.twig
│ │ │ │ │ │ └── werkl-blog-element-preview.scss
│ │ │ │ ├── blog-newest-listing
│ │ │ │ │ ├── component
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-cms-el-newest-listing.html.twig
│ │ │ │ │ │ └── werkl-cms-el-newest-listing.scss
│ │ │ │ │ ├── config
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-cms-el-config-newest-listing.html.twig
│ │ │ │ │ │ └── werkl-cms-el-config-newest-listing.scss
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── preview
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-cms-el-preview-newest-listing.html.twig
│ │ │ │ │ │ └── werkl-cms-el-preview-newest-listing.scss
│ │ │ │ ├── blog-single-select
│ │ │ │ │ ├── component
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── sw-cms-el-blog-single-select.html.twig
│ │ │ │ │ │ └── sw-cms-el-blog-single-select.scss
│ │ │ │ │ ├── config
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── sw-cms-el-config-blog-single-select.html.twig
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── preview
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── sw-cms-el-preview-blog-single-select.html.twig
│ │ │ │ │ │ └── sw-cms-el-preview-blog-single-select.scss
│ │ │ │ ├── blog
│ │ │ │ │ ├── component
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── sw-cms-el-blog.html.twig
│ │ │ │ │ │ └── sw-cms-el-blog.scss
│ │ │ │ │ ├── config
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── sw-cms-el-config-blog.html.twig
│ │ │ │ │ │ └── sw-cms-el-config-blog.scss
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── preview
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── sw-cms-el-preview-blog.html.twig
│ │ │ │ │ │ └── sw-cms-el-preview-blog.scss
│ │ │ │ └── index.js
│ │ │ │ ├── error-config.json
│ │ │ │ ├── extension
│ │ │ │ ├── component
│ │ │ │ │ └── cms
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-cms-sidebar
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-cms-sidebar.html.twig
│ │ │ │ │ │ └── werkl-cms-sidebar.scss
│ │ │ │ │ │ └── werkl-cms-slot
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-cms-slot.html.twig
│ │ │ │ │ │ └── werkl-cms-slot.scss
│ │ │ │ ├── index.js
│ │ │ │ └── sw-cms
│ │ │ │ │ ├── component
│ │ │ │ │ └── sw-cms-sidebar
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── sw-cms-sidebar.html.twig
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── page
│ │ │ │ │ └── sw-cms-list
│ │ │ │ │ │ └── index.js
│ │ │ │ │ └── snippet
│ │ │ │ │ ├── de-DE.json
│ │ │ │ │ └── en-GB.json
│ │ │ │ ├── helper
│ │ │ │ └── shopware-version.helper.js
│ │ │ │ ├── index.js
│ │ │ │ ├── page
│ │ │ │ ├── index.js
│ │ │ │ ├── werkl-blog-author
│ │ │ │ │ ├── acl
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── werkl-blog-author-create
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── werkl-blog-author-detail
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-blog-author-detail.html.twig
│ │ │ │ │ │ └── werkl-blog-author-detail.scss
│ │ │ │ │ └── werkl-blog-author-list
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── werkl-blog-author-list.html.twig
│ │ │ │ │ │ └── werkl-blog-author-list.scss
│ │ │ │ ├── werkl-blog-create
│ │ │ │ │ └── index.js
│ │ │ │ ├── werkl-blog-detail
│ │ │ │ │ ├── acl
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── werkl-blog-detail.html.twig
│ │ │ │ └── werkl-blog-list
│ │ │ │ │ ├── acl
│ │ │ │ │ └── index.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── werkl-blog-list.scss
│ │ │ │ │ └── werkl-blog-list.twig
│ │ │ │ └── snippet
│ │ │ │ ├── de-DE.json
│ │ │ │ └── en-GB.json
│ │ └── storefront
│ │ │ └── src
│ │ │ └── scss
│ │ │ ├── base.scss
│ │ │ └── layout
│ │ │ └── header
│ │ │ └── _search-suggest.scss
│ ├── config
│ │ ├── config.xml
│ │ ├── plugin.png
│ │ ├── routes.xml
│ │ ├── routes
│ │ │ └── storefront.xml
│ │ └── services.xml
│ ├── public
│ │ ├── administration
│ │ │ └── js
│ │ │ │ └── werkl-open-blogware.js
│ │ └── static
│ │ │ ├── css
│ │ │ ├── 134.css
│ │ │ ├── 156.css
│ │ │ ├── 16.css
│ │ │ ├── 18.css
│ │ │ ├── 384.css
│ │ │ ├── 403.css
│ │ │ ├── 425.css
│ │ │ ├── 44.css
│ │ │ ├── 462.css
│ │ │ ├── 470.css
│ │ │ ├── 485.css
│ │ │ ├── 528.css
│ │ │ ├── 549.css
│ │ │ ├── 618.css
│ │ │ ├── 656.css
│ │ │ ├── 70.css
│ │ │ ├── 725.css
│ │ │ ├── 75.css
│ │ │ ├── 788.css
│ │ │ ├── 859.css
│ │ │ ├── 925.css
│ │ │ ├── 940.css
│ │ │ └── 965.css
│ │ │ └── js
│ │ │ ├── 046f86b8c54d44503ccc.js
│ │ │ ├── 0cac1ae2b237a54b9a41.js
│ │ │ ├── 280b68c7d1e5037917db.js
│ │ │ ├── 31e758e2ea9d04f41446.js
│ │ │ ├── 33c36fd5d76856f33f76.js
│ │ │ ├── 369933b2aab52e07a724.js
│ │ │ ├── 424dc6d6d4e89dc84e40.js
│ │ │ ├── 4a38dd497688ee75a124.js
│ │ │ ├── 4c6e82e67679d63a7a6f.js
│ │ │ ├── 592d239c99b85801ad8d.js
│ │ │ ├── 5ef3c68e64f9eeacfb51.js
│ │ │ ├── 728c35d301e5c3ebbd19.js
│ │ │ ├── 78d3ae20c78baefc1fc0.js
│ │ │ ├── 816e6ead401278aac5c0.js
│ │ │ ├── 8647d6fcf498155d9ccc.js
│ │ │ ├── 8b2b6c5bb0a41393003a.js
│ │ │ ├── 8b4aa1d2f98e1bed6d50.js
│ │ │ ├── 915ebe549e746152b355.js
│ │ │ ├── 94c20f9caef696e0136f.js
│ │ │ ├── 9f6b67d1842fb22e2f89.js
│ │ │ ├── a425c54987986cd4842a.js
│ │ │ ├── a6b24c82491b2d6f873e.js
│ │ │ ├── b5b1227c870757fb6c15.js
│ │ │ ├── b89d94e938ef620cefda.js
│ │ │ ├── ba9211ae5cb1d9e05a45.js
│ │ │ ├── baa196a2bd193a4a577c.js
│ │ │ ├── c44c3ea8ca1f550a4b37.js
│ │ │ ├── ca06e9e52b00474374b8.js
│ │ │ ├── cea856d98329a9dd25f4.js
│ │ │ ├── cee2fafb3c215193d171.js
│ │ │ ├── cf416c17430c96401b8b.js
│ │ │ ├── d3b8f578386315abdd6d.js
│ │ │ ├── e000ae4cb18f39cd2e4c.js
│ │ │ ├── e3d6829db89e813d1cc3.js
│ │ │ ├── e94a84b6264cd6dfcb7f.js
│ │ │ ├── ec3c4260240b6a3b8ef7.js
│ │ │ ├── f5d4ebc931a30e2014fa.js
│ │ │ ├── f925b3b0896cef9ced50.js
│ │ │ ├── fbe93fc23dd1cbadee55.js
│ │ │ └── fceb9e682485d5fab032.js
│ ├── snippet
│ │ ├── de_DE
│ │ │ └── storefront.de-DE.json
│ │ └── en_GB
│ │ │ └── storefront.en-GB.json
│ └── views
│ │ └── storefront
│ │ ├── block
│ │ ├── cms-block-blog-categories.html.twig
│ │ ├── cms-block-blog-detail.html.twig
│ │ ├── cms-block-blog-listing.html.twig
│ │ ├── cms-block-blog-newest-listing.html.twig
│ │ └── cms-block-blog-single-entry.html.twig
│ │ ├── component
│ │ ├── blog
│ │ │ ├── _partials
│ │ │ │ ├── _block_author.html.twig
│ │ │ │ └── _block_category.html.twig
│ │ │ ├── card
│ │ │ │ └── box.html.twig
│ │ │ ├── listing.html.twig
│ │ │ └── newest-listing.html.twig
│ │ └── listing
│ │ │ ├── blog-filter-panel.html.twig
│ │ │ └── filter
│ │ │ ├── blog-filter-multi-select-list-item.html.twig
│ │ │ └── blog-filter-multi-select.html.twig
│ │ ├── element
│ │ ├── cms-element-blog-categories.html.twig
│ │ ├── cms-element-blog-detail.html.twig
│ │ ├── cms-element-blog-newest-listing.html.twig
│ │ ├── cms-element-blog-single-select.html.twig
│ │ └── cms-element-blog.html.twig
│ │ ├── layout
│ │ ├── header
│ │ │ ├── blog-suggest-tab-content.html.twig
│ │ │ ├── search-suggest.html.twig
│ │ │ └── search.html.twig
│ │ └── meta.html.twig
│ │ └── page
│ │ ├── blog-search
│ │ ├── index.html.twig
│ │ └── search-pagelet.html.twig
│ │ └── rss.html.twig
├── Storefront
│ └── Framework
│ │ └── Seo
│ │ └── SeoUrlRoute
│ │ └── SeoUrlUpdateListener.php
├── Subscriber
│ └── BlogCacheInvalidSubscriber.php
├── Util
│ ├── Lifecycle.php
│ └── Update.php
└── WerklOpenBlogware.php
└── tests
├── Cypress
├── .gitignore
├── README.md
├── cypress.config.example.js
├── cypress
│ ├── config
│ │ └── dev.json
│ ├── fixtures
│ │ └── example.json
│ ├── integration
│ │ └── administration
│ │ │ ├── cms.spec.js
│ │ │ └── edit.spec.js
│ ├── plugins
│ │ └── index.js
│ └── support
│ │ ├── actions
│ │ └── admin
│ │ │ └── BlogDetailAction.js
│ │ ├── commands.js
│ │ ├── index.js
│ │ ├── repositories
│ │ └── admin
│ │ │ ├── blog
│ │ │ ├── BlogDetailsRepository.js
│ │ │ └── BlogFormRepository.js
│ │ │ └── general
│ │ │ ├── CmsPageRepository.js
│ │ │ └── DatePickerRepository.js
│ │ └── services
│ │ └── shopware
│ │ └── Shopware.js
├── makefile
├── package-lock.json
└── package.json
└── PHPUnit
├── Content
├── Blog
│ └── Events
│ │ └── BlogMainFilterEventTest.php
└── Cms
│ └── DataResolver
│ └── SasCmsSlotsDataResolverTest.php
├── Core
└── Content
│ └── Sitemap
│ └── Provider
│ └── BlogUrlProviderTest.php
├── Fakes
└── FakeEntityRepository.php
├── Page
├── Blog
│ ├── BlogPageCriteriaEventTest.php
│ ├── BlogPageLoadedEventTest.php
│ └── BlogPageLoaderTest.php
└── Search
│ └── BlogSearchPageLoaderTest.php
├── Traits
└── ContextTrait.php
└── Util
├── LifecycleTest.php
└── UpdateTest.php
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [7underlines]
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### OSX
2 | .DS_Store
3 | .AppleDouble
4 | .LSOverride
5 |
6 | coverage
7 | src/Resources/app/administration/coverage
8 | src/Resources/app/administration/node_modules
9 |
10 | ## other stuff
11 | /.vscode
12 | /.idea
13 | /vendor
14 | composer.lock
15 |
16 | src/Resources/app/administration/node_modules
17 |
18 | src/Resources/app/storefront/dist/
19 | src/Resources/app/storefront/node_modules
20 |
21 | src/Resources/public/administration/css/
22 | src/Resources/public/administration/js/
--------------------------------------------------------------------------------
/.infection.json:
--------------------------------------------------------------------------------
1 | {
2 | "bootstrap": "./phpunit.autoload.php",
3 | "minMsi": 10,
4 | "minCoveredMsi": 10,
5 | "source": {
6 | "directories": [
7 | "src"
8 | ],
9 | "excludes": [
10 | "/\\Definition\\.php/",
11 | "/\\Entity\\.php/",
12 | "/\\Collection\\.php/",
13 | "Resources",
14 | "Migration"
15 | ]
16 | },
17 | "mutators": {
18 | "@default": true
19 | },
20 | "$schema": "vendor/infection/infection/resources/schema.json"
21 | }
22 |
--------------------------------------------------------------------------------
/.php_cs.php:
--------------------------------------------------------------------------------
1 | in('src')
6 | ->exclude('vendor')
7 | ->exclude(['Resources']);
8 |
9 | return PhpCsFixer\Config::create()
10 | ->setRules([
11 | '@PSR2' => true,
12 | 'single_quote' => true,
13 | 'function_typehint_space' => true,
14 | 'hash_to_slash_comment' => true,
15 | 'method_separation' => true,
16 | 'no_blank_lines_after_phpdoc' => true,
17 | 'no_unused_imports' => true,
18 | 'no_useless_else' => true,
19 | 'phpdoc_align' => true,
20 | 'phpdoc_order' => true,
21 | 'phpdoc_scalar' => true,
22 | 'pre_increment' => true,
23 | 'short_scalar_cast' => true,
24 | 'space_after_semicolon' => true,
25 | 'ternary_operator_spaces' => true,
26 | 'trailing_comma_in_multiline_array' => true,
27 | 'semicolon_after_instruction' => true,
28 | 'trim_array_spaces' => true,
29 | 'whitespace_after_comma_in_array' => true,
30 | 'phpdoc_add_missing_param_annotation' => true,
31 | 'ordered_imports' => true,
32 | 'binary_operator_spaces' => ['align_equals' => false, 'align_double_arrow' => true],
33 | 'concat_space' => ['spacing' => 'one'],
34 | 'array_syntax' => ['syntax' => 'short'],
35 | ])
36 | ->setFinder($finder);
37 |
--------------------------------------------------------------------------------
/.phpstan.neon:
--------------------------------------------------------------------------------
1 | parameters:
2 | level: 8
3 | inferPrivatePropertyTypeFromConstructor: true
4 | checkMissingIterableValueType: false
5 | reportUnmatchedIgnoredErrors: false
6 | checkGenericClassInNonGenericObjectType: false
7 | paths:
8 | - ./src
9 | excludes_analyse:
10 | - ./src/Resources/app/administration/node_modules/*
11 | - ./src/Resources/app/storefront/node_modules/*
12 | - ./src/WerklOpenBlogware.php
13 |
--------------------------------------------------------------------------------
/.shopware-extension.yml:
--------------------------------------------------------------------------------
1 | build:
2 | zip:
3 | composer:
4 | enabled: true
5 | assets:
6 | enabled: true
7 | enable_es_build_for_admin: true
8 | enable_es_build_for_storefront: true
9 | pack:
10 | excludes:
11 | paths:
12 | - .idea
13 | - var
14 | - .gitignore
--------------------------------------------------------------------------------
/AGENTS.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Werkstattl/OpenBlogware/ba3f7ab908e3501a2a8434ebfea3344cdd19d53a/AGENTS.md
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | Be nice and respectful.
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 SMK SHAPE & SHIFT LTD
4 | Copyright (c) 2024 Werkstattl
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
--------------------------------------------------------------------------------
/bin/fix-cs.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | php ../../../../dev-ops/analyze/vendor/bin/ecs check --fix --config=../../../vendor/shopware/platform/easy-coding-standard.yml
3 |
--------------------------------------------------------------------------------
/composer-ci.json:
--------------------------------------------------------------------------------
1 | {
2 | "autoload": {
3 | "psr-4": {
4 | "Werkl\\OpenBlogware\\": "src/"
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | shop:
3 | image: dockware/dev:latest
4 | ports:
5 | - "80:80"
6 | volumes:
7 | - .:/var/www/html/custom/plugins/WerklOpenBlogware
8 |
--------------------------------------------------------------------------------
/phpunit.autoload.php:
--------------------------------------------------------------------------------
1 | addPsr4('Werkl\\OpenBlogware\\', __DIR__ . '/src', true);
8 | $classLoader->addPsr4('OpenBlogware\\Tests\\', __DIR__ . '/tests/PHPUnit', true);
9 | $classLoader->register();
10 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 | ./tests/PHPUnit/
14 |
15 |
16 |
17 |
18 |
19 | ./src
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/Content/Blog/Aggregate/BlogCategoryMappingDefinition.php:
--------------------------------------------------------------------------------
1 | addFlags(new PrimaryKey(), new Required()),
29 | (new FkField('werkl_blog_category_id', 'blogCategoryId', BlogCategoryDefinition::class))->addFlags(new PrimaryKey(), new Required()),
30 | (new ReferenceVersionField(BlogCategoryDefinition::class))->addFlags(new PrimaryKey(), new Required()),
31 |
32 | new ManyToOneAssociationField('blog', 'werkl_blog_entries_id', BlogEntriesDefinition::class, 'id', false),
33 | new ManyToOneAssociationField('blogCategory', 'werkl_blog_category_id', BlogCategoryDefinition::class, 'id', false),
34 | ]);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Content/Blog/Aggregate/BlogEntriesTagMappingDefinition.php:
--------------------------------------------------------------------------------
1 | addFlags(new PrimaryKey(), new Required()),
28 | (new FkField('tag_id', 'tagId', TagDefinition::class))->addFlags(new PrimaryKey(), new Required()),
29 |
30 | new ManyToOneAssociationField('blog', 'werkl_blog_entries_id', BlogEntriesDefinition::class, 'id', false),
31 | new ManyToOneAssociationField('tag', 'tag_id', TagDefinition::class, 'id', false),
32 | ]);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Content/Blog/BlogEntriesCollection.php:
--------------------------------------------------------------------------------
1 | addFlags(new Required()),
47 | (new StringField('slug', 'slug'))->addFlags(new Required()),
48 | new StringField('teaser', 'teaser'),
49 | new StringField('meta_title', 'metaTitle'),
50 | new StringField('meta_description', 'metaDescription'),
51 | (new LongTextField('content', 'content'))->addFlags(new AllowHtml()),
52 | (new CustomFields())->addFlags(new ApiAware()),
53 | ]);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Content/Blog/BlogListingFilterBuildEvent.php:
--------------------------------------------------------------------------------
1 | seoUrlUpdater = $seoUrlUpdater;
17 | }
18 |
19 | public static function getSubscribedEvents(): array
20 | {
21 | return [
22 | 'werkl_blog_entries.written' => 'onBlogUpdated',
23 | ];
24 | }
25 |
26 | public function onBlogUpdated(EntityWrittenEvent $event): void
27 | {
28 | $this->seoUrlUpdater->update(BlogSeoUrlRoute::ROUTE_NAME, $event->getIds());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Content/Blog/BlogSeoUrlRoute.php:
--------------------------------------------------------------------------------
1 | definition = $definition;
26 | }
27 |
28 | public function getConfig(): SeoUrlRouteConfig
29 | {
30 | return new SeoUrlRouteConfig(
31 | $this->definition,
32 | self::ROUTE_NAME,
33 | self::DEFAULT_TEMPLATE,
34 | true
35 | );
36 | }
37 |
38 | public function prepareCriteria(Criteria $criteria, SalesChannelEntity $salesChannel): void
39 | {
40 | $criteria->addAssociations([
41 | 'blogCategories',
42 | 'blogAuthor',
43 | 'tags',
44 | ]);
45 | }
46 |
47 | public function getMapping(Entity $entry, ?SalesChannelEntity $salesChannel): SeoUrlMapping
48 | {
49 | if (!$entry instanceof BlogEntriesEntity) {
50 | throw new \InvalidArgumentException('Expected BlogEntriesEntity');
51 | }
52 |
53 | return new SeoUrlMapping(
54 | $entry,
55 | ['articleId' => $entry->getId()],
56 | [
57 | 'entry' => $entry,
58 | ]
59 | );
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/Content/Blog/Events/BlogIndexerEvent.php:
--------------------------------------------------------------------------------
1 | ids = $ids;
26 | $this->context = $context;
27 | $this->skip = $skip;
28 | }
29 |
30 | public function getIds(): array
31 | {
32 | return $this->ids;
33 | }
34 |
35 | public function getContext(): Context
36 | {
37 | return $this->context;
38 | }
39 |
40 | public function getSkip(): array
41 | {
42 | return $this->skip;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Content/Blog/Events/BlogMainFilterEvent.php:
--------------------------------------------------------------------------------
1 | request = $request;
24 | $this->criteria = $criteria;
25 | $this->context = $context;
26 | }
27 |
28 | public function getRequest(): Request
29 | {
30 | return $this->request;
31 | }
32 |
33 | public function getCriteria(): Criteria
34 | {
35 | return $this->criteria;
36 | }
37 |
38 | public function getContext(): Context
39 | {
40 | return $this->context->getContext();
41 | }
42 |
43 | public function getSalesChannelContext(): SalesChannelContext
44 | {
45 | return $this->context;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Content/Blog/Events/CategoriesCriteriaEvent.php:
--------------------------------------------------------------------------------
1 | request = $request;
24 | $this->criteria = $criteria;
25 | $this->context = $context;
26 | }
27 |
28 | public function getRequest(): Request
29 | {
30 | return $this->request;
31 | }
32 |
33 | public function getCriteria(): Criteria
34 | {
35 | return $this->criteria;
36 | }
37 |
38 | public function getContext(): Context
39 | {
40 | return $this->context->getContext();
41 | }
42 |
43 | public function getSalesChannelContext(): SalesChannelContext
44 | {
45 | return $this->context;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Content/Blog/Events/NewestListingCriteriaEvent.php:
--------------------------------------------------------------------------------
1 | request = $request;
24 | $this->criteria = $criteria;
25 | $this->context = $context;
26 | }
27 |
28 | public function getRequest(): Request
29 | {
30 | return $this->request;
31 | }
32 |
33 | public function getCriteria(): Criteria
34 | {
35 | return $this->criteria;
36 | }
37 |
38 | public function getContext(): Context
39 | {
40 | return $this->context->getContext();
41 | }
42 |
43 | public function getSalesChannelContext(): SalesChannelContext
44 | {
45 | return $this->context;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Content/BlogAuthor/BlogAuthorCollection.php:
--------------------------------------------------------------------------------
1 | werklBlogAuthorId;
22 | }
23 |
24 | public function setWerklBlogAuthorId(string $werklBlogAuthorId): void
25 | {
26 | $this->werklBlogAuthorId = $werklBlogAuthorId;
27 | }
28 |
29 | public function getWerklBlogAuthor(): ?BlogAuthorEntity
30 | {
31 | return $this->werklBlogAuthor;
32 | }
33 |
34 | public function setWerklBlogAuthor(BlogAuthorEntity $werklBlogAuthor): void
35 | {
36 | $this->werklBlogAuthor = $werklBlogAuthor;
37 | }
38 |
39 | public function getDescription(): ?string
40 | {
41 | return $this->description;
42 | }
43 |
44 | public function setDescription(string $description): void
45 | {
46 | $this->description = $description;
47 | }
48 |
49 | public function getCustomFields(): ?array
50 | {
51 | return $this->customFields;
52 | }
53 |
54 | public function setCustomFields(?array $customFields): void
55 | {
56 | $this->customFields = $customFields;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Content/BlogCategory/BlogCategoryCollection.php:
--------------------------------------------------------------------------------
1 | addFlags(new Required()),
41 | new CustomFields(),
42 | ]);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Content/BlogCategory/BlogCategoryTranslation/BlogCategoryTranslationEntity.php:
--------------------------------------------------------------------------------
1 | name;
22 | }
23 |
24 | public function setName(string $name): void
25 | {
26 | $this->name = $name;
27 | }
28 |
29 | public function getCustomFields(): ?array
30 | {
31 | return $this->customFields;
32 | }
33 |
34 | public function setCustomFields(?array $customFields): void
35 | {
36 | $this->customFields = $customFields;
37 | }
38 |
39 | public function getWerklBlogCategoryId(): string
40 | {
41 | return $this->werklBlogCategoryId;
42 | }
43 |
44 | public function setWerklBlogCategoryId(string $werklBlogCategoryId): void
45 | {
46 | $this->werklBlogCategoryId = $werklBlogCategoryId;
47 | }
48 |
49 | public function getWerklBlogCategory(): ?BlogCategoryEntity
50 | {
51 | return $this->werklBlogCategory;
52 | }
53 |
54 | public function setWerklBlogCategory(BlogCategoryEntity $werklBlogCategory): void
55 | {
56 | $this->werklBlogCategory = $werklBlogCategory;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Content/Extension/LanguageExtension.php:
--------------------------------------------------------------------------------
1 | add(
20 | (new OneToManyAssociationField('blogTranslations', BlogEntriesTranslationDefinition::class, 'language_id'))->addFlags(new CascadeDelete()),
21 | );
22 | $collection->add(
23 | (new OneToManyAssociationField('blogCategoryTranslations', BlogCategoryTranslationDefinition::class, 'language_id'))->addFlags(new CascadeDelete()),
24 | );
25 | $collection->add(
26 | (new OneToManyAssociationField('blogAuthorTranslations', BlogAuthorTranslationDefinition::class, 'language_id'))->addFlags(new CascadeDelete()),
27 | );
28 | }
29 |
30 | public function getDefinitionClass(): string
31 | {
32 | return LanguageDefinition::class;
33 | }
34 |
35 | public function getEntityName(): string
36 | {
37 | return LanguageDefinition::ENTITY_NAME;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Content/Extension/MediaExtension.php:
--------------------------------------------------------------------------------
1 | add(
18 | new OneToOneAssociationField('blogEntriesTranslation', 'id', 'media_id', BlogEntriesTranslationDefinition::class, false),
19 | );
20 | $collection->add(
21 | new OneToOneAssociationField('blogAuthor', 'id', 'media_id', BlogAuthorDefinition::class, false),
22 | );
23 | }
24 |
25 | public function getDefinitionClass(): string
26 | {
27 | return MediaDefinition::class;
28 | }
29 |
30 | public function getEntityName(): string
31 | {
32 | return MediaDefinition::ENTITY_NAME;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Content/Extension/SalutationExtension.php:
--------------------------------------------------------------------------------
1 | add(
18 | (new OneToManyAssociationField('blogAuthors', BlogAuthorDefinition::class, 'salutation_id', 'id'))->addFlags(new SetNullOnDelete()),
19 | );
20 | }
21 |
22 | public function getDefinitionClass(): string
23 | {
24 | return SalutationDefinition::class;
25 | }
26 |
27 | public function getEntityName(): string
28 | {
29 | return SalutationDefinition::ENTITY_NAME;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Controller/BlogController.php:
--------------------------------------------------------------------------------
1 | ['storefront']])]
17 | class BlogController extends StorefrontController
18 | {
19 | private BlogPageLoader $blogPageLoader;
20 |
21 | public function __construct(BlogPageLoader $blogPageLoader)
22 | {
23 | $this->blogPageLoader = $blogPageLoader;
24 | }
25 |
26 | #[Route(path: '/werkl_blog/{articleId}', name: 'werkl.frontend.blog.detail', methods: ['GET'])]
27 | public function detailAction(Request $request, SalesChannelContext $context): Response
28 | {
29 | $page = $this->blogPageLoader->load($request, $context);
30 |
31 | return $this->renderStorefront('@Storefront/storefront/page/content/index.html.twig', ['page' => $page]);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Controller/BlogSearchController.php:
--------------------------------------------------------------------------------
1 | ['storefront']])]
18 | class BlogSearchController extends StorefrontController
19 | {
20 | private BlogSearchPageLoader $blogSearchPageLoader;
21 |
22 | public function __construct(
23 | BlogSearchPageLoader $blogSearchPageLoader
24 | ) {
25 | $this->blogSearchPageLoader = $blogSearchPageLoader;
26 | }
27 |
28 | #[Route(path: '/werkl_blog_search', name: 'werkl.frontend.blog.search', methods: ['GET'])]
29 | public function search(Request $request, SalesChannelContext $context): Response
30 | {
31 | try {
32 | $page = $this->blogSearchPageLoader->load($request, $context);
33 | } catch (RoutingException $routingException) {
34 | return $this->forwardToRoute('frontend.home.page');
35 | }
36 |
37 | return $this->renderStorefront('@Storefront/storefront/page/blog-search/index.html.twig', ['page' => $page]);
38 | }
39 |
40 | /**
41 | * @throws RoutingException
42 | */
43 | #[Route(path: '/widgets/blog-search', name: 'widgets.blog.search.pagelet', methods: ['GET', 'POST'], defaults: ['XmlHttpRequest' => true])]
44 | public function ajax(Request $request, SalesChannelContext $context): Response
45 | {
46 | $request->request->set('no-aggregations', true);
47 |
48 | $page = $this->blogSearchPageLoader->load($request, $context);
49 |
50 | $response = $this->renderStorefront('@Storefront/storefront/page/blog-search/search-pagelet.html.twig', ['page' => $page]);
51 | $response->headers->set('x-robots-tag', 'noindex');
52 |
53 | return $response;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Controller/StoreApi/AbstractBlogController.php:
--------------------------------------------------------------------------------
1 | object->getEntities();
26 |
27 | return $collection;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Migration/Migration1602739765AddTeaserImageColumnToBlogEntries.php:
--------------------------------------------------------------------------------
1 | executeStatement('
19 | ALTER TABLE
20 | werkl_blog_entries
21 | ADD
22 | COLUMN media_id BINARY(16) DEFAULT NULL
23 | AFTER
24 | id
25 | ');
26 | }
27 |
28 | public function updateDestructive(Connection $connection): void
29 | {
30 | // implement update destructive
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Migration/Migration1612160298CreatePubslihedDateColumn.php:
--------------------------------------------------------------------------------
1 | executeStatement('
19 | ALTER TABLE
20 | werkl_blog_entries
21 | ADD
22 | COLUMN published_at DATETIME(3) NOT NULL
23 | AFTER
24 | created_at
25 | ');
26 |
27 | $connection->executeStatement('
28 | UPDATE werkl_blog_entries SET published_at = created_at
29 | ');
30 | }
31 |
32 | public function updateDestructive(Connection $connection): void
33 | {
34 | // implement update destructive
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Migration/Migration1626760242AddCustomFieldToBlogTranslation.php:
--------------------------------------------------------------------------------
1 | executeStatement('
19 | ALTER TABLE `werkl_blog_entries_translation`
20 | ADD COLUMN `custom_fields` json DEFAULT NULL AFTER `content`;
21 | ');
22 | }
23 |
24 | public function updateDestructive(Connection $connection): void
25 | {
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Migration/Migration1647338771WerklBlogEntriesUpdate.php:
--------------------------------------------------------------------------------
1 | updateSchema($connection);
19 | $this->createDeleteTrigger($connection);
20 | }
21 |
22 | public function updateDestructive(Connection $connection): void
23 | {
24 | // implement update destructive
25 | }
26 |
27 | public function updateSchema(Connection $connection): void
28 | {
29 | $connection->executeStatement('
30 | ALTER TABLE `werkl_blog_entries`
31 | ADD `cms_page_id` BINARY(16) NULL AFTER `id`,
32 | ADD `cms_page_version_id` binary(16) NULL AFTER `cms_page_id`,
33 |
34 | ADD CONSTRAINT `fk.werkl_blog_entries.cms_page_id`
35 | FOREIGN KEY (`cms_page_id`, `cms_page_version_id`)
36 | REFERENCES `cms_page` (`id`, `version_id`)
37 | ON DELETE RESTRICT ON UPDATE CASCADE;
38 | ');
39 | }
40 |
41 | private function createDeleteTrigger(Connection $connection): void
42 | {
43 | $query
44 | = 'CREATE TRIGGER werkl_blog_entries_delete AFTER DELETE ON werkl_blog_entries
45 | FOR EACH ROW
46 | BEGIN
47 | IF @TRIGGER_DISABLED IS NULL OR @TRIGGER_DISABLED = 0 THEN
48 | IF (OLD.cms_page_id IS NOT NULL) THEN
49 | DELETE FROM cms_page WHERE id = OLD.cms_page_id;
50 | END IF;
51 | END IF;
52 | END;';
53 |
54 | $this->createTrigger($connection, $query);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Migration/Migration1649580844AddParentVersionId.php:
--------------------------------------------------------------------------------
1 | executeStatement('
21 | ALTER TABLE `werkl_blog_category`
22 | ADD `parent_version_id` BINARY(16) NULL AFTER `parent_id`,
23 | DROP FOREIGN KEY `fk.werkl_blog_category.parent_id`,
24 | DROP INDEX `fk.werkl_blog_category.parent_id`;
25 | ');
26 | $connection->executeStatement('
27 | ALTER TABLE `werkl_blog_category`
28 | ADD CONSTRAINT `fk.werkl_blog_category.parent_id`
29 | FOREIGN KEY (`parent_id`, `parent_version_id`)
30 | REFERENCES `werkl_blog_category` (`id`, `version_id`)
31 | ON DELETE CASCADE ON UPDATE CASCADE;
32 | ');
33 | $connection->executeStatement(
34 | '
35 | UPDATE `werkl_blog_category` SET parent_version_id = unhex(:version)
36 | ',
37 | ['version' => $version]
38 | );
39 | }
40 |
41 | public function updateDestructive(Connection $connection): void
42 | {
43 | // implement update destructive
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Migration/Migration1702998914SetSalutationIdAuthorToNullable.php:
--------------------------------------------------------------------------------
1 | executeStatement('ALTER TABLE `werkl_blog_author` MODIFY `salutation_id` BINARY(16) NULL;');
19 | $connection->executeStatement('ALTER TABLE `werkl_blog_author` DROP FOREIGN KEY `fk.werkl_blog_author.salutation_id`;');
20 | $connection->executeStatement('ALTER TABLE `werkl_blog_author` ADD CONSTRAINT `fk.werkl_blog_author.salutation_id` FOREIGN KEY (`salutation_id`) REFERENCES `salutation` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;');
21 | }
22 |
23 | public function updateDestructive(Connection $connection): void
24 | {
25 | // implement update destructive
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Migration/Migration1736010505Tags.php:
--------------------------------------------------------------------------------
1 | executeStatement('
19 | CREATE TABLE IF NOT EXISTS `werkl_blog_entries_tag` (
20 | `werkl_blog_entries_id` BINARY(16) NOT NULL,
21 | `tag_id` BINARY(16) NOT NULL,
22 | PRIMARY KEY (`werkl_blog_entries_id`,`tag_id`),
23 | KEY `fk.werkl_blog_entries_tag.werkl_blog_entries_id` (`werkl_blog_entries_id`),
24 | KEY `fk.werkl_blog_entries_tag.tag_id` (`tag_id`),
25 | CONSTRAINT `fk.werkl_blog_entries_tag.werkl_blog_entries_id` FOREIGN KEY (`werkl_blog_entries_id`) REFERENCES `werkl_blog_entries` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
26 | CONSTRAINT `fk.werkl_blog_entries_tag.tag_id` FOREIGN KEY (`tag_id`) REFERENCES `tag` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
27 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
28 | ');
29 | }
30 |
31 | public function updateDestructive(Connection $connection): void
32 | {
33 | // implement update destructive
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Migration/Migration1744229687TranslatableTeaserImage.php:
--------------------------------------------------------------------------------
1 | addColumnToTranslationTable($connection);
21 | $this->migrateMediaIdToTranslationTable($connection);
22 | $this->removeColumnFromTable($connection);
23 | }
24 |
25 | private function addColumnToTranslationTable(Connection $connection): void
26 | {
27 | $connection->executeStatement('
28 | ALTER TABLE `werkl_blog_entries_translation`
29 | ADD COLUMN `media_id` BINARY(16) DEFAULT NULL AFTER `language_id`;
30 | ');
31 | }
32 |
33 | private function migrateMediaIdToTranslationTable(Connection $connection): void
34 | {
35 | $connection->executeStatement('
36 | UPDATE `werkl_blog_entries_translation`
37 | SET `media_id` = (
38 | SELECT `media_id`
39 | FROM `werkl_blog_entries`
40 | WHERE `werkl_blog_entries`.`id` = `werkl_blog_entries_translation`.`werkl_blog_entries_id`
41 | )
42 | WHERE `werkl_blog_entries_translation`.`language_id` = :languageId;
43 | ', [
44 | 'languageId' => Uuid::fromHexToBytes(Defaults::LANGUAGE_SYSTEM),
45 | ]);
46 | }
47 |
48 | private function removeColumnFromTable(Connection $connection): void
49 | {
50 | $connection->executeStatement('
51 | ALTER TABLE `werkl_blog_entries`
52 | DROP COLUMN `media_id`;
53 | ');
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Page/Blog/BlogPage.php:
--------------------------------------------------------------------------------
1 | blogEntry;
19 | }
20 |
21 | public function setBlogEntry(BlogEntriesEntity $blogEntry): void
22 | {
23 | $this->blogEntry = $blogEntry;
24 | }
25 |
26 | public function getNavigationId(): ?string
27 | {
28 | return $this->navigationId;
29 | }
30 |
31 | public function setNavigationId(?string $navigationId): void
32 | {
33 | $this->navigationId = $navigationId;
34 | }
35 |
36 | public function getEntityName(): string
37 | {
38 | return BlogEntriesDefinition::ENTITY_NAME;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Page/Blog/BlogPageCriteriaEvent.php:
--------------------------------------------------------------------------------
1 | articleId = $articleId;
23 | $this->criteria = $criteria;
24 | $this->salesChannelContext = $context;
25 | }
26 |
27 | public function getArticleId(): string
28 | {
29 | return $this->articleId;
30 | }
31 |
32 | public function getCriteria(): Criteria
33 | {
34 | return $this->criteria;
35 | }
36 |
37 | public function getContext(): Context
38 | {
39 | return $this->salesChannelContext->getContext();
40 | }
41 |
42 | public function getSalesChannelContext(): SalesChannelContext
43 | {
44 | return $this->salesChannelContext;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Page/Blog/BlogPageLoadedEvent.php:
--------------------------------------------------------------------------------
1 | page = $page;
17 | parent::__construct($salesChannelContext, $request);
18 | }
19 |
20 | public function getPage(): BlogPage
21 | {
22 | return $this->page;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Page/Search/BlogSearchPage.php:
--------------------------------------------------------------------------------
1 | searchTerm;
18 | }
19 |
20 | public function setSearchTerm(string $searchTerm): void
21 | {
22 | $this->searchTerm = $searchTerm;
23 | }
24 |
25 | public function getListing(): EntitySearchResult
26 | {
27 | return $this->listing;
28 | }
29 |
30 | public function setListing(EntitySearchResult $listing): void
31 | {
32 | $this->listing = $listing;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "jquery": true,
5 | "node": true,
6 | "es6": true
7 | },
8 | "extends": [
9 | "eslint:recommended"
10 | ],
11 | "parser": "@babel/eslint-parser",
12 | "parserOptions": {
13 | "ecmaVersion": 6,
14 | "sourceType": "module"
15 | },
16 | "globals": {
17 | "Shopware": true,
18 | "warn": true
19 | },
20 | "rules": {
21 | "comma-dangle": [
22 | "error",
23 | "always-multiline"
24 | ],
25 | "one-var": [
26 | "error",
27 | "never"
28 | ],
29 | "no-console": [
30 | "error",
31 | {
32 | "allow": [
33 | "warn",
34 | "error"
35 | ]
36 | }
37 | ],
38 | "no-debugger": 2,
39 | "prefer-const": "warn",
40 | "quotes": [
41 | "warn",
42 | "single"
43 | ],
44 | "indent": [
45 | "warn",
46 | 4,
47 | {
48 | "SwitchCase": 1
49 | }
50 | ]
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"],
3 | "plugins": [
4 | "@babel/plugin-transform-runtime",
5 | "@babel/plugin-proposal-class-properties"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/build/webpack.config.js:
--------------------------------------------------------------------------------
1 | const { join, resolve } = require('path');
2 |
3 | module.exports = () => {
4 | return {
5 | resolve: {
6 | alias: {
7 | '@slugify': resolve(
8 | join(__dirname, '..', 'node_modules', 'slugify')
9 | )
10 | }
11 | }
12 | };
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "administration",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "dependencies": {
7 | "slugify": "^1.4.6"
8 | },
9 | "devDependencies": {
10 | "@babel/plugin-proposal-class-properties": "^7.16.7",
11 | "@babel/plugin-transform-runtime": "7.13.15",
12 | "@babel/preset-env": "7.13.15",
13 | "@babel/eslint-parser": "7.24.8",
14 | "babel-loader": "8.0.6",
15 | "eslint": "8.36.0",
16 | "eslint-config-standard": "17.1.0",
17 | "eslint-plugin-import": "2.27.5",
18 | "eslint-plugin-promise": "6.1.1",
19 | "eslint-plugin-standard": "^5.0.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/init/cms-page-type.init.js:
--------------------------------------------------------------------------------
1 | const cmsPageTypeService = Shopware.Service('cmsPageTypeService');
2 | import BLOG from '../module/blog-module/constant/open-blogware.constant';
3 |
4 | cmsPageTypeService.register({
5 | name: BLOG.PAGE_TYPES.BLOG_DETAIL,
6 | icon: 'regular-file-text',
7 | });
8 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/main.js:
--------------------------------------------------------------------------------
1 | import './module/blog-module';
2 | import './init/cms-page-type.init';
3 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/categories/component/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-cms-block-blog.html.twig';
2 |
3 | export default {
4 | template,
5 | };
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/categories/component/werkl-cms-block-blog.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_block_categories %}
2 |
3 |
4 |
5 | {% endblock %}
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/categories/index.js:
--------------------------------------------------------------------------------
1 | const { Component } = Shopware;
2 |
3 | Component.register('sw-cms-block-blog-categories', () => import('./component'));
4 | Component.register('werkl-cms-preview-blog-categories', () => import('./preview'));
5 |
6 | Shopware.Service('cmsService').registerCmsBlock({
7 | name: 'blog-categories',
8 | label: 'werkl-blog.blocks.blog.categories.label',
9 | category: 'werkl-blog',
10 | component: 'werkl-cms-block-categories',
11 | previewComponent: 'werkl-cms-preview-blog-categories',
12 | defaultConfig: {
13 | marginBottom: '0px',
14 | marginTop: '0px',
15 | marginLeft: '0px',
16 | marginRight: '0px',
17 | sizingMode: 'boxed',
18 | },
19 | slots: {
20 | categories: 'blog-categories',
21 | },
22 | });
23 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/categories/preview/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-cms-preview-blog-categories.html.twig';
2 | import './werkl-cms-preview-blog-categories.scss';
3 |
4 | export default {
5 | template,
6 |
7 | computed: {
8 | today() {
9 | return new Date().toLocaleDateString();
10 | },
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/categories/preview/werkl-cms-preview-blog-categories.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_preview_blog_categories %}
2 |
3 |
4 |
{{ $tc('werkl-blog.blocks.blog.categories.previewTitle') }}
5 |
6 |
{{ today }}
7 |
8 |
9 |
10 |
11 |
{{ today }}
12 |
13 |
14 |
15 |
16 |
17 | {% endblock %}
18 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/categories/preview/werkl-cms-preview-blog-categories.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .werkl-cms-preview-blog-categories {
4 | width: 100%;
5 | background: $color-white;
6 | font-size: 22px;
7 | color: $color-darkgray-200;
8 | font-weight: 600;
9 | border-radius: 5px;
10 | padding: 20px;
11 |
12 | h2 {
13 | grid-column: span 2;
14 | font-size: 16px;
15 | line-height: 18px;
16 | margin: 0 0 2px 0;
17 | }
18 |
19 | .werkl-cms-preview-blog-categories-item {
20 | display: grid;
21 | grid-template-columns: 1fr 1fr;
22 | grid-gap: 20px;
23 | row-gap: 0;
24 |
25 | div > div {
26 | margin: 10px 0;
27 | height: 0.7em;
28 | border-radius: 4px;
29 | background-color: $color-gray-100;
30 | }
31 |
32 | hr {
33 | max-width: 90%;
34 | margin: 10px auto;
35 | border: 1px solid $color-gray-300;
36 | }
37 |
38 | time {
39 | font-size: 12px;
40 | line-height: 14px;
41 | font-weight: normal;
42 | margin: 0 0 6px 0;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/detail/component/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-cms-block-blog-detail.html.twig';
2 |
3 | export default {
4 | template,
5 | };
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/detail/component/werkl-cms-block-blog-detail.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_block_detail %}
2 |
3 |
4 |
5 | {% endblock %}
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/detail/index.js:
--------------------------------------------------------------------------------
1 | const { Component } = Shopware;
2 |
3 | Component.register('sw-cms-block-blog-detail', () => import('./component'));
4 | Component.register('werkl-cms-preview-blog-detail', () => import('./preview'));
5 |
6 | Shopware.Service('cmsService').registerCmsBlock({
7 | name: 'blog-detail',
8 | label: 'werkl-blog.blocks.blog.detail.label',
9 | category: 'werkl-blog',
10 | component: 'werkl-cms-block-blog-detail',
11 | previewComponent: 'werkl-cms-preview-blog-detail',
12 | defaultConfig: {
13 | marginBottom: '0px',
14 | marginTop: '0px',
15 | marginLeft: '0px',
16 | marginRight: '0px',
17 | sizingMode: 'boxed',
18 | },
19 | slots: {
20 | blogDetail: 'blog-detail',
21 | },
22 | });
23 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/detail/preview/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-cms-preview-blog-detail.html.twig';
2 | import './werkl-cms-preview-blog-detail.scss';
3 |
4 | export default {
5 | template,
6 |
7 | computed: {
8 | today() {
9 | return new Date().toLocaleDateString();
10 | },
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/detail/preview/werkl-cms-preview-blog-detail.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_preview_blog_detail %}
2 |
3 |
4 |
{{ $tc('werkl-blog.blocks.blog.detail.previewTitle') }}
5 |
6 |
{{ today }}
7 |
Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
8 | sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
9 | sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
10 |
11 |
12 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/detail/preview/werkl-cms-preview-blog-detail.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .werkl-cms-preview-blog-detail {
4 | width: 100%;
5 | background: $color-white;
6 | font-size: 22px;
7 | color: $color-darkgray-200;
8 | font-weight: 600;
9 | border-radius: 5px;
10 | padding: 20px;
11 |
12 | h2 {
13 | grid-column: span 2;
14 | font-size: 16px;
15 | line-height: 18px;
16 | margin: 0 0 2px 0;
17 | }
18 |
19 | .werkl-cms-preview-blog-detail-item {
20 |
21 | div > div {
22 | margin: 10px 0;
23 | height: 0.7em;
24 | border-radius: 4px;
25 | background-color: $color-gray-100;
26 | }
27 |
28 | hr {
29 | max-width: 90%;
30 | margin: 10px auto;
31 | border: 1px solid $color-gray-300;
32 | }
33 |
34 | time {
35 | font-size: 12px;
36 | line-height: 14px;
37 | font-weight: normal;
38 | margin: 0 0 6px 0;
39 | }
40 |
41 | p {
42 | font-size: 12px;
43 | line-height: 14px;
44 | font-weight: normal;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/index.js:
--------------------------------------------------------------------------------
1 | import './categories';
2 | import './detail';
3 | import './listing';
4 | import './newest-listing';
5 | import './single-entry';
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/listing/component/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-cms-block-blog.html.twig';
2 |
3 | export default {
4 | template,
5 | };
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/listing/component/werkl-cms-block-blog.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_block_listing %}
2 |
3 |
4 |
5 | {% endblock %}
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/listing/index.js:
--------------------------------------------------------------------------------
1 | const { Component } = Shopware;
2 |
3 | Component.register('sw-cms-block-blog-listing', () => import('./component'));
4 | Component.register('werkl-cms-preview-blog-listing', () => import('./preview'));
5 |
6 | Shopware.Service('cmsService').registerCmsBlock({
7 | name: 'blog-listing',
8 | label: 'werkl-blog.blocks.blog.listing.label',
9 | category: 'werkl-blog',
10 | component: 'werkl-cms-block-blog',
11 | previewComponent: 'werkl-cms-preview-blog-listing',
12 | defaultConfig: {
13 | marginBottom: '0px',
14 | marginTop: '0px',
15 | marginLeft: '0px',
16 | marginRight: '0px',
17 | sizingMode: 'boxed',
18 | },
19 | slots: {
20 | listing: 'blog',
21 | },
22 | });
23 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/listing/preview/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-cms-preview-blog-listing.html.twig';
2 | import './werkl-cms-preview-blog-listing.scss';
3 |
4 | export default {
5 | template,
6 |
7 | computed: {
8 | today() {
9 | return new Date().toLocaleDateString();
10 | },
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/listing/preview/werkl-cms-preview-blog-listing.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_preview_blog_listing %}
2 |
3 |
4 |
{{ $tc('werkl-blog.blocks.blog.listing.previewTitle') }}
5 |
6 |
{{ today }}
7 |
8 |
9 |
10 |
11 |
{{ today }}
12 |
13 |
14 |
15 |
16 |
17 | {% endblock %}
18 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/listing/preview/werkl-cms-preview-blog-listing.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .werkl-cms-preview-blog-listing {
4 | width: 100%;
5 | background: $color-white;
6 | font-size: 22px;
7 | color: $color-darkgray-200;
8 | font-weight: 600;
9 | border-radius: 5px;
10 | padding: 20px;
11 |
12 | h2 {
13 | grid-column: span 2;
14 | font-size: 16px;
15 | line-height: 18px;
16 | margin: 0 0 2px 0;
17 | }
18 |
19 | .werkl-cms-preview-blog-listing-item {
20 | display: grid;
21 | grid-template-columns: 1fr 1fr;
22 | grid-gap: 20px;
23 | row-gap: 0;
24 |
25 | div > div {
26 | margin: 10px 0;
27 | height: 0.7em;
28 | border-radius: 4px;
29 | background-color: $color-gray-100;
30 | }
31 |
32 | hr {
33 | max-width: 90%;
34 | margin: 10px auto;
35 | border: 1px solid $color-gray-300;
36 | }
37 |
38 | time {
39 | font-size: 12px;
40 | line-height: 14px;
41 | font-weight: normal;
42 | margin: 0 0 6px 0;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/newest-listing/component/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-cms-block-newest-listing.html.twig';
2 |
3 | export default {
4 | template,
5 | };
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/newest-listing/component/werkl-cms-block-newest-listing.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_block_newest_listing %}
2 |
3 |
4 |
5 | {% endblock %}
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/newest-listing/index.js:
--------------------------------------------------------------------------------
1 | const { Component } = Shopware;
2 |
3 | Component.register('sw-cms-block-blog-newest-listing', () => import('./component'));
4 | Component.register('werkl-cms-preview-newest-listing', () => import('./preview'));
5 |
6 | Shopware.Service('cmsService').registerCmsBlock({
7 | name: 'blog-newest-listing',
8 | label: 'werkl-blog.blocks.blog.newestListing.label',
9 | category: 'werkl-blog',
10 | component: 'werkl-cms-block-newest-listing',
11 | previewComponent: 'werkl-cms-preview-newest-listing',
12 | defaultConfig: {
13 | marginBottom: '0px',
14 | marginTop: '0px',
15 | marginLeft: '0px',
16 | marginRight: '0px',
17 | sizingMode: 'boxed',
18 | },
19 | slots: {
20 | listing: 'blog-newest-listing',
21 | },
22 | });
23 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/newest-listing/preview/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-cms-preview-newest-listing.html.twig';
2 | import './werkl-cms-preview-newest-listing.scss';
3 |
4 | export default {
5 | template,
6 | };
7 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/newest-listing/preview/werkl-cms-preview-newest-listing.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_preview_newest_listing %}
2 |
3 |
4 |
{{ $tc('werkl-blog.blocks.blog.newestListing.previewTitle') }}
5 |
9 |
13 |
14 |
15 | {% endblock %}
16 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/newest-listing/preview/werkl-cms-preview-newest-listing.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .werkl-cms-preview-newest-listing {
4 | width: 100%;
5 | background: $color-white;
6 | font-size: 22px;
7 | color: $color-darkgray-200;
8 | font-weight: 600;
9 | border-radius: 5px;
10 | padding: 20px;
11 |
12 | h2 {
13 | grid-column: span 2;
14 | font-size: 16px;
15 | line-height: 18px;
16 | margin: 0 0 2px 0;
17 | }
18 |
19 | .werkl-cms-preview-newest-listing-item {
20 | display: grid;
21 | grid-template-columns: 1fr 1fr;
22 | grid-gap: 20px;
23 | row-gap: 0;
24 |
25 | div > div {
26 | margin: 10px 0;
27 | height: 0.7em;
28 | border-radius: 4px;
29 | background-color: $color-gray-100;
30 | }
31 |
32 | hr {
33 | max-width: 90%;
34 | margin: 10px auto;
35 | border: 1px solid $color-gray-300;
36 | }
37 |
38 | time {
39 | font-size: 12px;
40 | line-height: 14px;
41 | font-weight: normal;
42 | margin: 0 0 6px 0;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/single-entry/component/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-cms-block-blog-single-entry.html.twig';
2 |
3 | export default {
4 | template,
5 | };
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/single-entry/component/werkl-cms-block-blog-single-entry.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_block_blog_single_entry %}
2 |
3 |
4 |
5 | {% endblock %}
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/single-entry/index.js:
--------------------------------------------------------------------------------
1 | const { Component } = Shopware;
2 |
3 | Component.register('sw-cms-block-blog-single-entry', () => import('./component'));
4 | Component.register('werkl-cms-preview-blog-single-entry', () => import('./preview'));
5 |
6 | Shopware.Service('cmsService').registerCmsBlock({
7 | name: 'blog-single-entry',
8 | label: 'werkl-blog.blocks.blog.singleEntry.label',
9 | category: 'werkl-blog',
10 | component: 'werkl-cms-block-blog-single-entry',
11 | previewComponent: 'werkl-cms-preview-blog-single-entry',
12 | defaultConfig: {
13 | marginBottom: '0px',
14 | marginTop: '0px',
15 | marginLeft: '0px',
16 | marginRight: '0px',
17 | sizingMode: 'boxed',
18 | },
19 | slots: {
20 | singleEntry: {
21 | type: 'blog-single-select',
22 | default: {
23 | config: {
24 | blogEntry: {
25 | source: 'static',
26 | value: null,
27 | },
28 | },
29 | },
30 | },
31 | },
32 | });
33 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/single-entry/preview/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-cms-preview-blog-single-entry.html.twig';
2 | import './werkl-cms-preview-blog-single-entry.scss';
3 |
4 | export default {
5 | template,
6 |
7 | computed: {
8 | today() {
9 | return new Date().toLocaleDateString();
10 | },
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/single-entry/preview/werkl-cms-preview-blog-single-entry.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_preview_blog_single_entry %}
2 |
3 |
4 |
{{ $tc('werkl-blog.blocks.blog.singleEntry.previewTitle') }}
5 |
6 |
{{ today }}
7 |
8 |
9 |
10 |
11 |
12 | {% endblock %}
13 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/blocks/single-entry/preview/werkl-cms-preview-blog-single-entry.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .werkl-cms-preview-blog-single-entry {
4 | width: 100%;
5 | background: $color-white;
6 | font-size: 22px;
7 | color: $color-darkgray-200;
8 | font-weight: 600;
9 | border-radius: 5px;
10 | padding: 20px;
11 |
12 | h2 {
13 | grid-column: span 2;
14 | font-size: 16px;
15 | line-height: 18px;
16 | margin: 0 0 2px 0;
17 | }
18 |
19 | .werkl-cms-preview-blog-single-entry-item {
20 | width: 100%;
21 |
22 | div > div {
23 | margin: 10px 0;
24 | height: 0.7em;
25 | border-radius: 4px;
26 | background-color: $color-gray-100;
27 | }
28 |
29 | hr {
30 | max-width: 90%;
31 | margin: 10px auto;
32 | border: 1px solid $color-gray-300;
33 | }
34 |
35 | time {
36 | font-size: 12px;
37 | line-height: 14px;
38 | font-weight: normal;
39 | margin: 0 0 6px 0;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/component/blog-category-tree-field/index.js:
--------------------------------------------------------------------------------
1 | const { Criteria } = Shopware.Data;
2 |
3 | export default {
4 | computed: {
5 | globalCategoryRepository() {
6 | return this.repositoryFactory.create('werkl_blog_category');
7 | },
8 | },
9 | methods: {
10 | searchCategories(term) {
11 | // create criteria
12 | const categorySearchCriteria = new Criteria(1, 500);
13 | categorySearchCriteria.setTerm(term);
14 |
15 | // search for categories
16 | return this.globalCategoryRepository.search(categorySearchCriteria, Shopware.Context.api);
17 | },
18 | },
19 | };
20 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/component/blog-category-tree/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-blog-category-tree.html.twig';
2 |
3 | export default {
4 | template,
5 |
6 | data() {
7 | return {
8 | blogCategory: null,
9 | translationContext: 'werkl-blog-category',
10 | };
11 | },
12 |
13 | methods: {
14 | changeCategory(category) {
15 | this.$emit('change-category-id', category.id);
16 | },
17 | },
18 |
19 | computed: {
20 | category() {
21 | return this.blogCategory;
22 | },
23 |
24 | categoryRepository() {
25 | return this.repositoryFactory.create('werkl_blog_category');
26 | },
27 |
28 | disableContextMenu() {
29 | if (!this.allowEdit) {
30 | return true;
31 | }
32 |
33 | return this.currentLanguageId !== Shopware.Context.api.systemLanguageId;
34 | },
35 | syncProducts() {
36 | return;
37 | },
38 | },
39 | };
40 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/component/blog-extension-component-sections/blog-extension-component-sections.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/component/blog-extension-component-sections/index.js:
--------------------------------------------------------------------------------
1 | import template from './blog-extension-component-sections.html.twig';
2 |
3 | const { State } = Shopware;
4 |
5 | export default {
6 | template,
7 |
8 | props: {
9 | positionIdentifier: {
10 | type: String,
11 | required: true,
12 | },
13 | },
14 |
15 | computed: {
16 | componentSections() {
17 | return State.get('extensionComponentSections').identifier[this.positionIdentifier] ?? [];
18 | },
19 | },
20 | };
21 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/component/blog-tree-item/blog-tree-item.html.twig:
--------------------------------------------------------------------------------
1 | {% block sw_tree_item_children_items %}
2 |
20 | {% block sw_tree_item_children_items_slots %}
21 | {% parent %}
22 | {% endblock %}
23 |
24 | {% endblock %}
25 |
26 | {% block sw_tree_items_actions_edit %}
27 |
28 | {{ $tc('werkl-blog-tree-item.actions.edit') }}
29 |
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/component/blog-tree-item/index.js:
--------------------------------------------------------------------------------
1 | import template from './blog-tree-item.html.twig';
2 |
3 | export default {
4 | template,
5 |
6 | computed: {
7 | parentScope() {
8 | let parentNode = this.$parent;
9 | // eslint-disable-next-line
10 | while (parentNode.$options.name !== 'sw-tree') {
11 | parentNode = parentNode.$parent;
12 | }
13 |
14 | return parentNode;
15 | },
16 | },
17 |
18 | data() {
19 | return {
20 | editingCategory: null,
21 | };
22 | },
23 |
24 | methods: {
25 | onEditCategory(category) {
26 | this.editingCategory = category;
27 | this.currentEditElement = category.id;
28 | this.editElementName();
29 | },
30 |
31 | onBlurTreeItemInput(item) {
32 | this.abortCreateElement(item);
33 | },
34 |
35 | onCancelSubmit(item) {
36 | this.abortCreateElement(item);
37 | },
38 |
39 | abortCreateElement(item) {
40 | this.currentEditElement = null;
41 | this.editingCategory = null;
42 | this.$super('abortCreateElement', item);
43 | },
44 | },
45 | };
46 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/component/blog-vertical-tabs/blog-vertical-tabs.html.twig:
--------------------------------------------------------------------------------
1 |
9 |
10 | {% block werkl_block_list_tab_item %}
11 |
19 | {{ $tc('werkl-blog.general.mainMenuItemList') }}
20 |
21 | {% endblock %}
22 |
23 | {% block werkl_block_tags_tab_item %}
24 |
32 | {{ $tc('werkl-blog-author.general.mainMenuItemList') }}
33 |
34 | {% endblock %}
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/component/blog-vertical-tabs/index.js:
--------------------------------------------------------------------------------
1 | import template from './blog-vertical-tabs.html.twig';
2 |
3 | export default {
4 | template,
5 |
6 | props: {
7 | defaultItem: {
8 | type: String,
9 | default: 'blog',
10 | },
11 | },
12 |
13 | methods: {
14 | onChangeTab(name) {
15 | this.currentTab = name;
16 | },
17 | },
18 | };
19 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/component/index.js:
--------------------------------------------------------------------------------
1 | const { Component } = Shopware;
2 |
3 | Component.extend('werkl-blog-category-tree', 'sw-category-tree', () => import('./blog-category-tree'));
4 | Component.extend('werkl-blog-category-tree-field', 'sw-category-tree-field', () => import('./blog-category-tree-field'));
5 | Component.register('werkl-blog-extension-component-sections', () => import('./blog-extension-component-sections'));
6 | Component.extend('werkl-blog-tree-item', 'sw-tree-item', () => import('./blog-tree-item'));
7 | Component.register('werkl-blog-vertical-tabs', () => import('./blog-vertical-tabs'));
8 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/constant/open-blogware.constant.js:
--------------------------------------------------------------------------------
1 | export default Object.freeze({
2 | REQUIRED_FIELD_ERROR_CODE: 'c1051bb4-d103-4f74-8988-acbcafc7fdc3',
3 | PAGE_TYPES: {
4 | BLOG_DETAIL: 'blog_detail',
5 | },
6 | });
7 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-categories/component/index.js:
--------------------------------------------------------------------------------
1 | import template from './sw-cms-el-categories.html.twig';
2 | import './sw-cms-el-categories.scss';
3 |
4 | const { Mixin } = Shopware;
5 |
6 | export default {
7 | template,
8 |
9 | mixins: [
10 | Mixin.getByName('cms-element'),
11 | ],
12 |
13 | created() {
14 | this.createdComponent();
15 | },
16 |
17 | methods: {
18 | createdComponent() {
19 | this.initElementConfig('blog-categories');
20 | },
21 | },
22 | };
23 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-categories/component/sw-cms-el-categories.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_element_categories_listing %}
2 |
3 |
{{ $tc('werkl-blog.elements.categories.component.elementHeadline') }}
4 |
5 | {{ $tc('werkl-blog.elements.categories.component.infoText') }}
6 |
7 |
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-categories/component/sw-cms-el-categories.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .werkl-cms-el-categories-listing {
4 | width: 100%;
5 | border: 1px solid #dadee5;
6 | border-radius: 4px;
7 | background: $color-white;
8 | padding: 10px;
9 |
10 | .werkl-cms-el-blog-placeholder div {
11 | margin: 15px 30px;
12 | height: 1.5em;
13 | border-radius: 4px;
14 | background-color: $color-gray-100;
15 |
16 | &.werkl-cms-el-werkl-cms-el-blog__placeholder {
17 | margin: 15px 30px 15px 70px;
18 | }
19 | }
20 |
21 | hr {
22 | max-width: 90%;
23 | margin: 10px auto;
24 | border: 1px solid $color-gray-300;
25 | }
26 |
27 | h2 {
28 | margin: 10px;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-categories/config/sw-cms-el-config-categories.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_element_blog_listing_config %}
2 |
3 | {% endblock %}
4 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-categories/index.js:
--------------------------------------------------------------------------------
1 | const { Component } = Shopware;
2 |
3 | Component.register('sw-cms-el-categories', () => import('./component'));
4 | Component.register('sw-cms-el-config-categories', () => import('./config'));
5 | Component.register('sw-cms-el-preview-categories', () => import('./preview'));
6 |
7 | Shopware.Service('cmsService').registerCmsElement({
8 | name: 'blog-categories',
9 | label: 'Blog Categories',
10 | component: 'sw-cms-el-categories',
11 | configComponent: 'sw-cms-el-config-categories',
12 | previewComponent: 'sw-cms-el-preview-categories',
13 | defaultConfig: {
14 | },
15 | });
16 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-categories/preview/index.js:
--------------------------------------------------------------------------------
1 | import template from './sw-cms-el-preview-categories.html.twig';
2 | import './sw-cms-el-preview-categories.scss';
3 |
4 | export default {
5 | template,
6 | };
7 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-categories/preview/sw-cms-el-preview-categories.html.twig:
--------------------------------------------------------------------------------
1 | {% block sw_cms_element_categories_preview %}
2 |
3 |
Categories Element
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-categories/preview/sw-cms-el-preview-categories.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .sw-cms-el-preview-categories {
4 | width: 100%;
5 | background: $color-white;
6 | font-size: 22px;
7 | color: $color-darkgray-200;
8 | font-weight: $font-weight-semi-bold;
9 |
10 | .sw-cms-el-category-placeholder-listing div {
11 | margin: 10px 0;
12 | height: 0.4em;
13 | border-radius: 25px;
14 | background-color: $color-gray-100;
15 |
16 | &.sw-cms-el-category-navigation__placeholder--subcategory {
17 | margin: 7px 20px;
18 |
19 | &:last-of-type {
20 | margin-right: 10px;
21 | }
22 | }
23 | }
24 |
25 | hr {
26 | max-width: 100%;
27 | margin: 10px auto;
28 | height: 1px;
29 | border: 0 none;
30 | background-color: $color-gray-300;
31 | }
32 |
33 | p {
34 | font-size: 14px;
35 | margin: auto 10px auto 0;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-detail/component/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-blog-element-blog-detail.html.twig';
2 | import './werkl-blog-element-blog-detail.scss';
3 |
4 | const { Mixin } = Shopware;
5 |
6 | export default {
7 | template,
8 |
9 | mixins: [
10 | Mixin.getByName('cms-element'),
11 | ],
12 |
13 | created() {
14 | this.createdComponent();
15 | },
16 |
17 | methods: {
18 | createdComponent() {
19 | this.initElementConfig('blog-detail');
20 | },
21 | },
22 | };
23 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-detail/component/werkl-blog-element-blog-detail.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_element_blog_detail %}
2 |
3 |
{{ $tc('werkl-blog.elements.detail.component.elementHeadline') }}
4 |
5 | {{ $tc('werkl-blog.elements.detail.component.infoText') }}
6 |
7 |
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-detail/component/werkl-blog-element-blog-detail.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .werkl-cms-el-blog-detail {
4 | width: 100%;
5 | border: 1px solid #dadee5;
6 | border-radius: 4px;
7 | background: $color-white;
8 | padding: 10px;
9 |
10 | .werkl-cms-el-blog-placeholder div {
11 | margin: 15px 30px;
12 | height: 1.5em;
13 | border-radius: 4px;
14 | background-color: $color-gray-100;
15 |
16 | &.werkl-cms-el-werkl-cms-el-blog__placeholder {
17 | margin: 15px 30px 15px 70px;
18 | }
19 | }
20 |
21 | hr {
22 | max-width: 90%;
23 | margin: 10px auto;
24 | border: 1px solid $color-gray-300;
25 | }
26 |
27 | h2 {
28 | margin: 10px;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-detail/config/index.js:
--------------------------------------------------------------------------------
1 | import template from './sw-cms-el-config-blog-detail.html.twig';
2 | import './sw-cms-el-config-blog-detail.scss';
3 |
4 | const { Mixin } = Shopware;
5 |
6 | export default {
7 | template,
8 |
9 | inject: ['repositoryFactory'],
10 |
11 | mixins: [
12 | Mixin.getByName('cms-element'),
13 | ],
14 |
15 | created() {
16 | this.createdComponent();
17 | },
18 |
19 | methods: {
20 | createdComponent() {
21 | this.initElementConfig('blog');
22 | },
23 | },
24 | };
25 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-detail/config/sw-cms-el-config-blog-detail.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_element_blog_detail_config %}
2 |
3 |
4 | {% block werkl_cms_element_blog_detail_config_show_meta %}
5 |
11 |
12 |
15 |
16 |
17 |
20 |
21 |
22 |
25 |
26 |
27 | {% endblock %}
28 |
29 |
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-detail/config/sw-cms-el-config-blog-detail.scss:
--------------------------------------------------------------------------------
1 | .sw-blog-detail-config-filter {
2 |
3 | .sw-field--checkbox {
4 | &:last-child {
5 | margin-bottom: 0;
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-detail/index.js:
--------------------------------------------------------------------------------
1 | const { Component } = Shopware;
2 |
3 | Component.register('werkl-blog-el-blog-detail', () => import('./component'));
4 | Component.register('sw-cms-el-config-blog-detail', () => import('./config'));
5 | Component.register('werkl-blog-el-blog-detail-preview', () => import('./preview'));
6 |
7 | Shopware.Service('cmsService').registerCmsElement({
8 | name: 'blog-detail',
9 | label: 'Blog Detail',
10 | component: 'werkl-blog-el-blog-detail',
11 | configComponent: 'sw-cms-el-config-blog-detail',
12 | previewComponent: 'werkl-blog-el-blog-detail-preview',
13 | defaultConfig: {
14 | showCategory: {
15 | source: 'static',
16 | value: true,
17 | },
18 | showAuthor: {
19 | source: 'static',
20 | value: true,
21 | },
22 | fullWidth: {
23 | source: 'static',
24 | value: false,
25 | },
26 | },
27 | });
28 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-detail/preview/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-blog-element-preview.html.twig';
2 | import './werkl-blog-element-preview.scss';
3 |
4 | export default {
5 | template,
6 | };
7 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-detail/preview/werkl-blog-element-preview.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_blog_element_previews %}
2 |
3 |
Lorem ipsum dolor
4 |
5 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
6 | sed diam nonumy eirmod tempor invidunt ut labore et dolore magna.
7 |
8 |
9 | {% endblock %}
10 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-detail/preview/werkl-blog-element-preview.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .sw-cms-el-preview-blog {
4 | width: 100%;
5 | background: $color-white;
6 | font-size: 22px;
7 | color: $color-darkgray-200;
8 | font-weight: 600;
9 |
10 | .sw-cms-el-category-placeholder-listing div {
11 | margin: 10px 0;
12 | height: 0.4em;
13 | border-radius: 25px;
14 | background-color: $color-gray-100;
15 |
16 | &.sw-cms-el-category-navigation__placeholder--subcategory {
17 | margin: 7px 20px 7px 20px;
18 |
19 | &:last-of-type {
20 | margin-right: 10px;
21 | }
22 | }
23 | }
24 |
25 | hr {
26 | max-width: 100%;
27 | margin: 10px auto;
28 | height: 1px;
29 | border: 0 none;
30 | background-color: $color-gray-300;
31 | }
32 |
33 | p {
34 | font-size: 14px;
35 | margin: auto 10px auto 0;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-newest-listing/component/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-cms-el-newest-listing.html.twig';
2 | import './werkl-cms-el-newest-listing.scss';
3 |
4 | const { Mixin } = Shopware;
5 |
6 | export default {
7 | template,
8 |
9 | mixins: [
10 | Mixin.getByName('cms-element'),
11 | ],
12 |
13 | created() {
14 | this.createdComponent();
15 | },
16 |
17 | methods: {
18 | createdComponent() {
19 | this.initElementConfig('blog-newest-listing');
20 | this.initElementData('blog-newest-listing');
21 | },
22 | },
23 | };
24 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-newest-listing/component/werkl-cms-el-newest-listing.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_el_newest_listing %}
2 |
3 |
{{ $tc('werkl-blog.elements.newestListing.component.elementHeadline') }}
4 |
5 | {{ $tc('werkl-blog.elements.newestListing.component.infoText') }}
6 |
7 |
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-newest-listing/component/werkl-cms-el-newest-listing.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .werkl-cms-el-newest-listing {
4 | width: 100%;
5 | border: 1px solid #dadee5;
6 | border-radius: 4px;
7 | background: $color-white;
8 | padding: 10px;
9 |
10 | h2 {
11 | margin: 10px;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-newest-listing/config/werkl-cms-el-config-newest-listing.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .werkl-cms-el-config-newest-listing {
4 | width: 100%;
5 | }
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-newest-listing/index.js:
--------------------------------------------------------------------------------
1 | const { Component } = Shopware;
2 |
3 | Component.register('werkl-cms-el-newest-listing', () => import('./component'));
4 | Component.register('werkl-cms-el-config-newest-listing', () => import('./config'));
5 | Component.register('werkl-cms-el-preview-newest-listing', () => import('./preview'));
6 |
7 | Shopware.Service('cmsService').registerCmsElement({
8 | name: 'blog-newest-listing',
9 | label: 'werkl-blog.elements.newestListing.preview.label',
10 | component: 'werkl-cms-el-newest-listing',
11 | configComponent: 'werkl-cms-el-config-newest-listing',
12 | previewComponent: 'werkl-cms-el-preview-newest-listing',
13 | defaultConfig: {
14 | itemCount: {
15 | source: 'static',
16 | value: 5,
17 | },
18 | offsetCount: {
19 | source: 'static',
20 | value: 0,
21 | },
22 | showType: {
23 | source: 'static',
24 | value: 'all',
25 | },
26 | blogCategories: {
27 | source: 'static',
28 | value: null,
29 | entity: {
30 | name: 'werkl_blog_categories',
31 | },
32 | },
33 | },
34 | });
35 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-newest-listing/preview/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-cms-el-preview-newest-listing.html.twig';
2 | import './werkl-cms-el-preview-newest-listing.scss';
3 |
4 | export default {
5 | template,
6 | };
7 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-newest-listing/preview/werkl-cms-el-preview-newest-listing.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_element_newest_listing_preview %}
2 |
3 |
Newest Listing Element
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-newest-listing/preview/werkl-cms-el-preview-newest-listing.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .werkl-cms-el-preview-newest-listing {
4 | width: 100%;
5 | background: $color-white;
6 | font-size: 22px;
7 | color: $color-darkgray-200;
8 | font-weight: $font-weight-semi-bold;
9 |
10 | .werkl-cms-el-category-placeholder-listing div {
11 | margin: 10px 0;
12 | height: 0.4em;
13 | border-radius: 25px;
14 | background-color: $color-gray-100;
15 |
16 | &.werkl-cms-el-category-navigation__placeholder--subcategory {
17 | margin: 7px 20px;
18 |
19 | &:last-of-type {
20 | margin-right: 10px;
21 | }
22 | }
23 | }
24 |
25 | hr {
26 | max-width: 100%;
27 | margin: 10px auto;
28 | height: 1px;
29 | border: 0 none;
30 | background-color: $color-gray-300;
31 | }
32 |
33 | p {
34 | font-size: 14px;
35 | margin: auto 10px auto 0;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-single-select/component/sw-cms-el-blog-single-select.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_element_blog_single_select %}
2 |
3 |
{{ categoryName }}
4 |
{{ title }}
5 |
6 |
{{ teaser }}
7 |
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-single-select/component/sw-cms-el-blog-single-select.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .werkl-cms-el-blog-single-select {
4 | width: 100%;
5 | padding: 20px;
6 |
7 | h6 {
8 | color: #0063AE;
9 | font-size: 14px;
10 | text-transform: uppercase;
11 | margin-bottom: 0;
12 | line-height: 1.2;
13 | }
14 |
15 | h3 {
16 | margin: 7px 0 18px;
17 | color: #343434;
18 | font-size: 23px;
19 | line-height: 1.2;
20 | }
21 |
22 | img {
23 | width: 100%;
24 | height: 100%;
25 | max-height: 225px;
26 | object-fit: cover;
27 | }
28 |
29 | p {
30 | margin: 18px 0;
31 | display: block;
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-single-select/config/index.js:
--------------------------------------------------------------------------------
1 | import template from './sw-cms-el-config-blog-single-select.html.twig';
2 |
3 | const { Mixin } = Shopware;
4 |
5 | export default {
6 | template,
7 |
8 | inject: ['repositoryFactory'],
9 |
10 | mixins: [
11 | Mixin.getByName('cms-element'),
12 | ],
13 |
14 | data() {
15 | return {
16 | blogEntry: null,
17 | selectedEntry: null,
18 | };
19 | },
20 | computed: {
21 | blogEntryRepository() {
22 | return this.repositoryFactory.create('werkl_blog_entries');
23 | },
24 | },
25 |
26 | created() {
27 | this.createdComponent();
28 | },
29 |
30 | methods: {
31 | createdComponent() {
32 | this.initElementConfig('blog-single-select');
33 | },
34 | },
35 | };
36 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-single-select/config/sw-cms-el-config-blog-single-select.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_element_blog_single_select_config %}
2 |
3 |
8 |
9 |
10 |
11 | {{ item.translated.title || item.name }}
12 |
13 |
14 |
15 |
16 |
17 |
18 | {{ item.translated.title || item.name }}
19 |
20 |
21 |
22 |
23 |
24 | {% endblock %}
25 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-single-select/index.js:
--------------------------------------------------------------------------------
1 | const { Component } = Shopware;
2 |
3 | Component.register('sw-cms-el-blog-single-select', () => import('./component'));
4 | Component.register('sw-cms-el-config-blog-single-select', () => import('./config'));
5 | Component.register('sw-cms-el-preview-blog-single-select', () => import('./preview'));
6 |
7 | Shopware.Service('cmsService').registerCmsElement({
8 | name: 'blog-single-select',
9 | label: 'werkl-blog.elements.single-select.label',
10 | component: 'sw-cms-el-blog-single-select',
11 | configComponent: 'sw-cms-el-config-blog-single-select',
12 | previewComponent: 'sw-cms-el-preview-blog-single-select',
13 | defaultConfig: {
14 | blogEntry: {
15 | source: 'static',
16 | value: null,
17 | entity: {
18 | name: 'werkl_blog_entries',
19 | },
20 | },
21 | },
22 | });
23 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-single-select/preview/index.js:
--------------------------------------------------------------------------------
1 | import template from './sw-cms-el-preview-blog-single-select.html.twig';
2 | import './sw-cms-el-preview-blog-single-select.scss';
3 |
4 | const { Filter } = Shopware;
5 |
6 | export default {
7 | template,
8 |
9 | computed: {
10 | assetFilter() {
11 | return Filter.getByName('asset');
12 | },
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-single-select/preview/sw-cms-el-preview-blog-single-select.html.twig:
--------------------------------------------------------------------------------
1 | {% block sw_cms_element_blog_single_select_preview %}
2 |
3 |
{{ $tc('werkl-blog.elements.single-select.previewText') }}
4 |
5 |
9 |
10 | {% endblock %}
11 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog-single-select/preview/sw-cms-el-preview-blog-single-select.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .sw-cms-el-preview-blog-single-select {
4 | width: 100%;
5 | background: $color-white;
6 | font-size: 22px;
7 | color: $color-darkgray-200;
8 | font-weight: 600;
9 |
10 | h6 {
11 | font-size: 14px;
12 | margin: auto 10px auto 0;
13 | }
14 |
15 | .sw-cms-el-category-placeholder-listing div {
16 | margin: 7px 0;
17 | height: 0.4em;
18 | border-radius: 25px;
19 | background-color: $color-gray-100;
20 | }
21 |
22 | img {
23 | width: 100%;
24 | height: 50px;
25 | object-fit: cover;
26 | margin-top: 5px;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog/component/index.js:
--------------------------------------------------------------------------------
1 | import template from './sw-cms-el-blog.html.twig';
2 | import './sw-cms-el-blog.scss';
3 |
4 | const { Mixin } = Shopware;
5 |
6 | export default {
7 | template,
8 |
9 | mixins: [
10 | Mixin.getByName('cms-element'),
11 | ],
12 |
13 | created() {
14 | this.createdComponent();
15 | },
16 |
17 | methods: {
18 | createdComponent() {
19 | this.initElementConfig('blog');
20 | },
21 | },
22 | };
23 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog/component/sw-cms-el-blog.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_cms_element_blog_listing %}
2 |
3 |
{{ $tc('werkl-blog.elements.listing.component.elementHeadline') }}
4 |
5 | {{ $tc('werkl-blog.elements.listing.component.infoText') }}
6 |
7 |
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog/component/sw-cms-el-blog.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .werkl-cms-el-blog-listing {
4 | width: 100%;
5 | border: 1px solid #dadee5;
6 | border-radius: 4px;
7 | background: $color-white;
8 | padding: 10px;
9 |
10 | .werkl-cms-el-blog-placeholder div {
11 | margin: 15px 30px;
12 | height: 1.5em;
13 | border-radius: 4px;
14 | background-color: $color-gray-100;
15 |
16 | &.werkl-cms-el-werkl-cms-el-blog__placeholder {
17 | margin: 15px 30px 15px 70px;
18 | }
19 | }
20 |
21 | hr {
22 | max-width: 90%;
23 | margin: 10px auto;
24 | border: 1px solid $color-gray-300;
25 | }
26 |
27 | h2 {
28 | margin: 10px;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog/config/sw-cms-el-config-blog.scss:
--------------------------------------------------------------------------------
1 | .sw-blog-config-filter {
2 |
3 | .sw-field--checkbox {
4 | &:last-child {
5 | margin-bottom: 0;
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog/index.js:
--------------------------------------------------------------------------------
1 | const { Component } = Shopware;
2 |
3 | Component.register('sw-cms-el-blog', () => import('./component'));
4 | Component.register('sw-cms-el-config-blog', () => import('./config'));
5 | Component.register('sw-cms-el-preview-blog', () => import('./preview'));
6 |
7 | Shopware.Service('cmsService').registerCmsElement({
8 | name: 'blog',
9 | label: 'Blog',
10 | component: 'sw-cms-el-blog',
11 | configComponent: 'sw-cms-el-config-blog',
12 | previewComponent: 'sw-cms-el-preview-blog',
13 | defaultConfig: {
14 | paginationCount: {
15 | source: 'static',
16 | value: 5,
17 | },
18 | showType: {
19 | source: 'static',
20 | value: 'all',
21 | },
22 | showCategoryFilter: {
23 | source: 'static',
24 | value: true,
25 | },
26 | showAuthorFilter: {
27 | source: 'static',
28 | value: true,
29 | },
30 | blogCategories: {
31 | source: 'static',
32 | value: null,
33 | entity: {
34 | name: 'werkl_blog_categories',
35 | },
36 | },
37 | showTags: {
38 | source: 'static',
39 | value: 'all',
40 | },
41 | blogTags: {
42 | source: 'static',
43 | value: null,
44 | entity: {
45 | name: 'tag',
46 | },
47 | },
48 | },
49 | });
50 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog/preview/index.js:
--------------------------------------------------------------------------------
1 | import template from './sw-cms-el-preview-blog.html.twig';
2 | import './sw-cms-el-preview-blog.scss';
3 |
4 | export default {
5 | template,
6 | };
7 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog/preview/sw-cms-el-preview-blog.html.twig:
--------------------------------------------------------------------------------
1 | {% block sw_cms_element_blog_preview %}
2 |
3 |
Blog Listing Element
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/blog/preview/sw-cms-el-preview-blog.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .sw-cms-el-preview-blog {
4 | width: 100%;
5 | background: $color-white;
6 | font-size: 22px;
7 | color: $color-darkgray-200;
8 | font-weight: $font-weight-semi-bold;
9 |
10 | .sw-cms-el-category-placeholder-listing div {
11 | margin: 10px 0;
12 | height: 0.4em;
13 | border-radius: 25px;
14 | background-color: $color-gray-100;
15 |
16 | &.sw-cms-el-category-navigation__placeholder--subcategory {
17 | margin: 7px 20px;
18 |
19 | &:last-of-type {
20 | margin-right: 10px;
21 | }
22 | }
23 | }
24 |
25 | hr {
26 | max-width: 100%;
27 | margin: 10px auto;
28 | height: 1px;
29 | border: 0 none;
30 | background-color: $color-gray-300;
31 | }
32 |
33 | p {
34 | font-size: 14px;
35 | margin: auto 10px auto 0;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/elements/index.js:
--------------------------------------------------------------------------------
1 | import './blog';
2 | import './blog-categories';
3 | import './blog-detail';
4 | import './blog-newest-listing';
5 | import './blog-single-select';
6 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/error-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "blog.module.detail": {
3 | "werkl_blog_entries": [
4 | "title",
5 | "slug",
6 | "teaser",
7 | "authorId",
8 | "publishedAt",
9 | "blogCategories"
10 | ]
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/extension/component/cms/index.js:
--------------------------------------------------------------------------------
1 | const { Component } = Shopware;
2 |
3 | Component.extend('werkl-cms-sidebar', 'sw-cms-sidebar', () => import('./werkl-cms-sidebar'));
4 | Component.extend('werkl-cms-slot', 'sw-cms-slot', () => import('./werkl-cms-slot'));
5 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/extension/component/cms/werkl-cms-sidebar/werkl-cms-sidebar.scss:
--------------------------------------------------------------------------------
1 | .werkl-field--switch {
2 | margin-top: 0;
3 | margin-bottom: 0;
4 | }
5 |
6 | .werkl-extension-component {
7 | width: 100%;
8 | height: 100%;
9 | }
10 |
11 | .serp-preview-card {
12 | .serp-preview {
13 | margin-bottom: 20px;
14 |
15 | h3 {
16 | font-family: arial, sans-serif !important;
17 | margin: 0;
18 | color: rgb(26, 13, 171);
19 | font-size: 18px;
20 | font-weight: 400;
21 | line-height: 1.2;
22 | word-break: break-all;
23 | }
24 |
25 | p {
26 | font-family: arial, sans-serif !important;
27 | color: #4d5156;
28 | font-size: 13px;
29 | line-height: 1.4;
30 | margin-top: 5px;
31 | word-break: break-all;
32 | }
33 |
34 | cite {
35 | font-family: arial, sans-serif !important;
36 | margin: 0;
37 | font-style: normal;
38 | height: 18px;
39 | color: rgb(0, 102, 33);
40 | font-size: 14px;
41 | line-height: 16px;
42 | display: block;
43 | white-space: nowrap;
44 | overflow: hidden;
45 | text-overflow: ellipsis;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/extension/component/cms/werkl-cms-slot/index.js:
--------------------------------------------------------------------------------
1 | import template from './werkl-cms-slot.html.twig';
2 | import './werkl-cms-slot.scss';
3 |
4 | export default {
5 | template,
6 | };
7 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/extension/component/cms/werkl-cms-slot/werkl-cms-slot.html.twig:
--------------------------------------------------------------------------------
1 | {% block sw_cms_slot_content_overlay_action_swap %}{% endblock %}
2 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/extension/component/cms/werkl-cms-slot/werkl-cms-slot.scss:
--------------------------------------------------------------------------------
1 | .werkl-blog-cms-stage-section {
2 | .sw-cms-slot {
3 | .sw-cms-slot__actions {
4 | grid-template-columns: auto;
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/extension/index.js:
--------------------------------------------------------------------------------
1 | import './component/cms';
2 | import './sw-cms';
3 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/extension/sw-cms/component/sw-cms-sidebar/index.js:
--------------------------------------------------------------------------------
1 | import template from './sw-cms-sidebar.html.twig';
2 | import BLOG from '../../../../constant/open-blogware.constant';
3 |
4 | export default {
5 | template,
6 |
7 | computed: {
8 | isBlogDetail() {
9 | return this.page.type === BLOG.PAGE_TYPES.BLOG_DETAIL;
10 | },
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/extension/sw-cms/component/sw-cms-sidebar/sw-cms-sidebar.html.twig:
--------------------------------------------------------------------------------
1 | {% block sw_cms_sidebar_block_overview_category_options %}
2 | {% parent %}
3 | Blog
4 | {% endblock %}
5 |
6 | {% block sw_cms_sidebar_page_settings_type_field_options %}
7 | {% parent %}
8 |
12 | {{ $tc('sw-cms.detail.label.pageTypeBlog') }}
13 |
14 | {% endblock %}
15 |
16 | {% block sw_cms_sidebar_page_settings_type_field %}
17 | {% parent %}
18 |
24 | {% endblock %}
25 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/extension/sw-cms/index.js:
--------------------------------------------------------------------------------
1 | const { Component } = Shopware;
2 |
3 | Component.override('sw-cms-sidebar', () => import('./component/sw-cms-sidebar'));
4 | Component.override('sw-cms-list', () => import('./page/sw-cms-list'));
5 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/extension/sw-cms/page/sw-cms-list/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | computed: {
3 | sortPageTypes() {
4 | const sortPageTypes = this.$super('sortPageTypes');
5 |
6 | sortPageTypes.push({
7 | value: 'blog_detail',
8 | name: this.$tc('sw-cms.sorting.labelSortByBlogPages'),
9 | });
10 |
11 | return sortPageTypes;
12 | },
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/extension/sw-cms/snippet/de-DE.json:
--------------------------------------------------------------------------------
1 | {
2 | "sw-cms": {
3 | "sorting": {
4 | "labelSortByBlogPages": "Blogseiten"
5 | },
6 | "detail": {
7 | "label": {
8 | "pageType": {
9 | "blogDetail": "Blogseite"
10 | }
11 | }
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/extension/sw-cms/snippet/en-GB.json:
--------------------------------------------------------------------------------
1 | {
2 | "sw-cms": {
3 | "sorting": {
4 | "labelSortByBlogPages": "Blog pages"
5 | },
6 | "detail": {
7 | "label": {
8 | "pageType": {
9 | "blogDetail": "Blog page"
10 | }
11 | }
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/page/index.js:
--------------------------------------------------------------------------------
1 | import './werkl-blog-author';
2 | import './werkl-blog-detail/acl';
3 | import './werkl-blog-list/acl';
4 |
5 | const { Component } = Shopware;
6 |
7 | Component.extend('werkl-blog-create', 'werkl-blog-detail', () => import('./werkl-blog-create'));
8 | Component.extend('werkl-blog-detail', 'sw-cms-detail', () => import('./werkl-blog-detail'));
9 | Component.register('werkl-blog-list', () => import('./werkl-blog-list'));
10 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/page/werkl-blog-author/acl/index.js:
--------------------------------------------------------------------------------
1 | Shopware.Service('privileges').addPrivilegeMappingEntry({
2 | category: 'permissions',
3 | parent: 'content',
4 | key: 'werkl-blog-author',
5 | roles: {
6 | viewer: {
7 | privileges: [
8 | 'werkl_blog_author:read',
9 | 'werkl_blog_author_translation:read',
10 | ],
11 | dependencies: [],
12 | },
13 | editor: {
14 | privileges: [
15 | 'werkl_blog_author:update',
16 | 'werkl_blog_author_translation:update',
17 | ],
18 | dependencies: [],
19 | },
20 | creator: {
21 | privileges: [
22 | 'werkl_blog_author:create',
23 | 'werkl_blog_author_translation:create',
24 | ],
25 | dependencies: [],
26 | },
27 | deleter: {
28 | privileges: [
29 | 'werkl_blog_author:delete',
30 | 'werkl_blog_author_translation:delete',
31 | ],
32 | dependencies: [],
33 | },
34 | },
35 | });
36 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/page/werkl-blog-author/index.js:
--------------------------------------------------------------------------------
1 | import './acl';
2 |
3 | const { Component } = Shopware;
4 |
5 | Component.extend('werkl-blog-author-create', 'werkl-blog-author-detail', () => import('./werkl-blog-author-create'));
6 | Component.register('werkl-blog-author-detail', () => import('./werkl-blog-author-detail'));
7 | Component.register('werkl-blog-author-list', () => import('./werkl-blog-author-list'));
8 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/page/werkl-blog-author/werkl-blog-author-create/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | methods: {
3 | createdComponent() {
4 | Shopware.State.commit('context/resetLanguageToDefault');
5 |
6 | this.blogAuthor = this.blogAuthorRepository.create(Shopware.Context.api);
7 | },
8 | },
9 | };
10 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/page/werkl-blog-author/werkl-blog-author-detail/werkl-blog-author-detail.scss:
--------------------------------------------------------------------------------
1 | .sw-blog-author-detail {
2 | .smart-bar__actions {
3 | span {
4 | display: flex;
5 | }
6 |
7 | .sw-tooltip--wrapper {
8 | margin-left: 8px;
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/page/werkl-blog-author/werkl-blog-author-list/werkl-blog-author-list.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | .werkl-blog-author-list {
4 |
5 | .sw-data-grid__cell--title {
6 | width: 82%;
7 | }
8 |
9 | .sw-page__content {
10 | .sw-page__main-content {
11 | grid-area: b;
12 | border-left: 1px solid $color-gray-300;
13 | }
14 |
15 | .sw-page__sidebar {
16 | grid-area: a;
17 | padding: 40px 15px;
18 | }
19 |
20 | &.has--smart-bar.has--side-bar {
21 | grid-template-columns: 120px auto;
22 | grid-template-areas: "a b";
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/page/werkl-blog-create/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | methods: {
3 | async createdComponent() {
4 | Shopware.Store.get('adminMenu').collapseSidebar();
5 |
6 | const isSystemDefaultLanguage = Shopware.State.getters['context/isSystemDefaultLanguage'];
7 | this.cmsPageState.setIsSystemDefaultLanguage(isSystemDefaultLanguage);
8 | if (!isSystemDefaultLanguage) {
9 | Shopware.State.commit('context/resetLanguageToDefault');
10 | }
11 |
12 | if (Shopware.Context.api.languageId !== Shopware.Context.api.systemLanguageId) {
13 | Shopware.State.commit('context/setApiLanguageId', Shopware.Context.api.languageId);
14 | }
15 |
16 | this.resetCmsPageState();
17 |
18 | this.createPage();
19 | this.createBlog(this.page.id);
20 | this.isLoading = false;
21 |
22 | this.setPageContext();
23 | },
24 |
25 | createBlog(pageId) {
26 | this.blog = this.blogRepository.create();
27 | this.blog.cmsPageId = pageId;
28 | this.blogId = this.blog.id;
29 | },
30 | },
31 | };
32 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/page/werkl-blog-detail/acl/index.js:
--------------------------------------------------------------------------------
1 | Shopware.Service('privileges').addPrivilegeMappingEntry({
2 | category: 'permissions',
3 | parent: 'content',
4 | key: 'werkl-blog',
5 | roles: {
6 | viewer: {
7 | privileges: [
8 | 'werkl_blog_entries:read',
9 | 'werkl_blog_entries_translation:read',
10 | 'werkl_blog_blog_category:read',
11 | ],
12 | dependencies: [],
13 | },
14 | editor: {
15 | privileges: [
16 | 'werkl_blog_entries:update',
17 | 'werkl_blog_entries_translation:update',
18 | 'system_config:read',
19 | ],
20 | dependencies: [],
21 | },
22 | creator: {
23 | privileges: [
24 | 'werkl_blog_entries:create',
25 | 'werkl_blog_entries_translation:create',
26 | 'werkl_blog_blog_category:create',
27 | 'system_config:read',
28 | ],
29 | dependencies: [],
30 | },
31 | deleter: {
32 | privileges: [
33 | 'werkl_blog_entries:delete',
34 | 'werkl_blog_entries_translation:delete',
35 | ],
36 | dependencies: [],
37 | },
38 | },
39 | });
40 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/page/werkl-blog-list/acl/index.js:
--------------------------------------------------------------------------------
1 | Shopware.Service('privileges').addPrivilegeMappingEntry({
2 | category: 'permissions',
3 | parent: 'content',
4 | key: 'werkl-blog-category',
5 | roles: {
6 | viewer: {
7 | privileges: [
8 | 'werkl_blog_category:read',
9 | 'werkl_blog_category_translation:read',
10 | ],
11 | dependencies: [],
12 | },
13 | editor: {
14 | privileges: [
15 | 'werkl_blog_category:update',
16 | 'werkl_blog_category_translation:update',
17 | ],
18 | dependencies: [],
19 | },
20 | creator: {
21 | privileges: [
22 | 'werkl_blog_category:create',
23 | 'werkl_blog_category_translation:create',
24 | ],
25 | dependencies: [],
26 | },
27 | deleter: {
28 | privileges: [
29 | 'werkl_blog_category:delete',
30 | 'werkl_blog_category_translation:delete',
31 | ],
32 | dependencies: [],
33 | },
34 | },
35 | });
36 |
--------------------------------------------------------------------------------
/src/Resources/app/administration/src/module/blog-module/page/werkl-blog-list/werkl-blog-list.scss:
--------------------------------------------------------------------------------
1 | @import "~scss/variables";
2 |
3 | $sw-property-list-color-error: $color-crimson-500;
4 | $sw-property-list-color-success: $color-emerald-500;
5 |
6 | .werkl-blog-list {
7 |
8 | .is--inactive {
9 | color: $sw-property-list-color-error;
10 | }
11 |
12 | .is--active {
13 | color: $sw-property-list-color-success;
14 | }
15 |
16 | .sw-data-grid__cell--title {
17 | width: 82%;
18 | }
19 |
20 | .sw-page__content {
21 | .sw-page__side-content {
22 | grid-area: a;
23 |
24 | .sw-tree .sw-tree-actions__headline {
25 | font-size: 14px;
26 | font-weight: bold;
27 | height: 64px;
28 | color: $color-darkgray-200;
29 | }
30 |
31 | .sw-tree__content, .sw-tree .sw-tree-actions__headline {
32 | border-left: 1px solid $color-gray-300;
33 | }
34 | }
35 |
36 | .sw-page__main-content {
37 | grid-area: b;
38 | }
39 |
40 | .sw-page__sidebar {
41 | grid-area: c;
42 | padding: 40px 15px;
43 | }
44 |
45 | &.has--smart-bar.has--side-content {
46 | grid-template-columns: 120px 440px auto;
47 | grid-template-areas: "c a b";
48 | }
49 |
50 | .sw-data-grid__cell--active {
51 | .sw-data-grid__cell-content {
52 | justify-content: center;
53 | }
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Resources/app/storefront/src/scss/base.scss:
--------------------------------------------------------------------------------
1 | @import 'layout/header/_search-suggest';
2 |
3 | .blog-image,
4 | .blog-image-placeholder {
5 | object-fit: cover;
6 | width: 100%;
7 | height: 250px;
8 | }
9 |
10 | .blog-card {
11 |
12 | .card-text {
13 | height: 85px;
14 | overflow: hidden;
15 | }
16 |
17 | .card-footer {
18 | display: flex;
19 | align-items: center;
20 | background: none;
21 | padding: 0;
22 | margin-top: 25px;
23 |
24 | .blog-author-avatar,
25 | .blog-image-placeholder {
26 | width: 50px;
27 | height: 50px;
28 | border-radius: 50%;
29 | object-fit: cover;
30 | margin-right: 20px;
31 | }
32 |
33 | .blog-author-display-name {
34 | font-weight: $font-weight-bold;
35 | margin-bottom: 0;
36 | }
37 | }
38 | }
39 |
40 | .has-element-loader .cms-element-product-listing {
41 | .blog-image-link span.icon{
42 | opacity: 0;
43 | }
44 |
45 | .blog-date,
46 | .blog-title a,
47 | .blog-image-link {
48 | border-radius: $border-radius;
49 | color: transparent;
50 | animation: skeletonShimmer 1.5s linear 0s infinite normal forwards running;
51 | background: linear-gradient(to right, $gray-300 8%, $gray-100 18%, $gray-300 28%);
52 | background-size: 800px 100px;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Resources/app/storefront/src/scss/layout/header/_search-suggest.scss:
--------------------------------------------------------------------------------
1 | @include media-breakpoint-up(md) {
2 | .search-suggest-container {
3 | width: 700px;
4 | left: 50%;
5 | transform: translateX(-50%);
6 | }
7 | .search-suggest-container-width {
8 | width: 500px;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Resources/config/plugin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Werkstattl/OpenBlogware/ba3f7ab908e3501a2a8434ebfea3344cdd19d53a/src/Resources/config/plugin.png
--------------------------------------------------------------------------------
/src/Resources/config/routes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/Resources/config/routes/storefront.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
10 | true
11 | storefront
12 | true
13 | landingpage
14 | index
15 | true
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/134.css:
--------------------------------------------------------------------------------
1 | .werkl-cms-el-blog-listing{width:100%;border:1px solid #dadee5;border-radius:4px;background:#fff;padding:10px}.werkl-cms-el-blog-listing .werkl-cms-el-blog-placeholder div{margin:15px 30px;height:1.5em;border-radius:4px;background-color:#f0f2f5}.werkl-cms-el-blog-listing .werkl-cms-el-blog-placeholder div.werkl-cms-el-werkl-cms-el-blog__placeholder{margin:15px 30px 15px 70px}.werkl-cms-el-blog-listing hr{max-width:90%;margin:10px auto;border:1px solid #d1d9e0}.werkl-cms-el-blog-listing h2{margin:10px}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/156.css:
--------------------------------------------------------------------------------
1 | .sw-cms-el-preview-blog{width:100%;background:#fff;font-size:22px;color:#52667a;font-weight:600}.sw-cms-el-preview-blog .sw-cms-el-category-placeholder-listing div{margin:10px 0;height:.4em;border-radius:25px;background-color:#f0f2f5}.sw-cms-el-preview-blog .sw-cms-el-category-placeholder-listing div.sw-cms-el-category-navigation__placeholder--subcategory{margin:7px 20px}.sw-cms-el-preview-blog .sw-cms-el-category-placeholder-listing div.sw-cms-el-category-navigation__placeholder--subcategory:last-of-type{margin-right:10px}.sw-cms-el-preview-blog hr{max-width:100%;margin:10px auto;height:1px;border:0 none;background-color:#d1d9e0}.sw-cms-el-preview-blog p{font-size:14px;margin:auto 10px auto 0}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/16.css:
--------------------------------------------------------------------------------
1 | .werkl-cms-el-preview-newest-listing{width:100%;background:#fff;font-size:22px;color:#52667a;font-weight:600}.werkl-cms-el-preview-newest-listing .werkl-cms-el-category-placeholder-listing div{margin:10px 0;height:.4em;border-radius:25px;background-color:#f0f2f5}.werkl-cms-el-preview-newest-listing .werkl-cms-el-category-placeholder-listing div.werkl-cms-el-category-navigation__placeholder--subcategory{margin:7px 20px}.werkl-cms-el-preview-newest-listing .werkl-cms-el-category-placeholder-listing div.werkl-cms-el-category-navigation__placeholder--subcategory:last-of-type{margin-right:10px}.werkl-cms-el-preview-newest-listing hr{max-width:100%;margin:10px auto;height:1px;border:0 none;background-color:#d1d9e0}.werkl-cms-el-preview-newest-listing p{font-size:14px;margin:auto 10px auto 0}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/18.css:
--------------------------------------------------------------------------------
1 | .sw-cms-el-preview-blog-single-select{width:100%;background:#fff;font-size:22px;color:#52667a;font-weight:600}.sw-cms-el-preview-blog-single-select h6{font-size:14px;margin:auto 10px auto 0}.sw-cms-el-preview-blog-single-select .sw-cms-el-category-placeholder-listing div{margin:7px 0;height:.4em;border-radius:25px;background-color:#f0f2f5}.sw-cms-el-preview-blog-single-select img{width:100%;height:50px;object-fit:cover;margin-top:5px}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/384.css:
--------------------------------------------------------------------------------
1 | .sw-cms-el-preview-blog{width:100%;background:#fff;font-size:22px;color:#52667a;font-weight:600}.sw-cms-el-preview-blog .sw-cms-el-category-placeholder-listing div{margin:10px 0;height:.4em;border-radius:25px;background-color:#f0f2f5}.sw-cms-el-preview-blog .sw-cms-el-category-placeholder-listing div.sw-cms-el-category-navigation__placeholder--subcategory{margin:7px 20px 7px 20px}.sw-cms-el-preview-blog .sw-cms-el-category-placeholder-listing div.sw-cms-el-category-navigation__placeholder--subcategory:last-of-type{margin-right:10px}.sw-cms-el-preview-blog hr{max-width:100%;margin:10px auto;height:1px;border:0 none;background-color:#d1d9e0}.sw-cms-el-preview-blog p{font-size:14px;margin:auto 10px auto 0}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/403.css:
--------------------------------------------------------------------------------
1 | .werkl-cms-el-categories-listing{width:100%;border:1px solid #dadee5;border-radius:4px;background:#fff;padding:10px}.werkl-cms-el-categories-listing .werkl-cms-el-blog-placeholder div{margin:15px 30px;height:1.5em;border-radius:4px;background-color:#f0f2f5}.werkl-cms-el-categories-listing .werkl-cms-el-blog-placeholder div.werkl-cms-el-werkl-cms-el-blog__placeholder{margin:15px 30px 15px 70px}.werkl-cms-el-categories-listing hr{max-width:90%;margin:10px auto;border:1px solid #d1d9e0}.werkl-cms-el-categories-listing h2{margin:10px}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/425.css:
--------------------------------------------------------------------------------
1 | .werkl-cms-preview-newest-listing{width:100%;background:#fff;font-size:22px;color:#52667a;font-weight:600;border-radius:5px;padding:20px}.werkl-cms-preview-newest-listing h2{grid-column:span 2;font-size:16px;line-height:18px;margin:0 0 2px 0}.werkl-cms-preview-newest-listing .werkl-cms-preview-newest-listing-item{display:grid;grid-template-columns:1fr 1fr;grid-gap:20px;row-gap:0}.werkl-cms-preview-newest-listing .werkl-cms-preview-newest-listing-item div>div{margin:10px 0;height:.7em;border-radius:4px;background-color:#f0f2f5}.werkl-cms-preview-newest-listing .werkl-cms-preview-newest-listing-item hr{max-width:90%;margin:10px auto;border:1px solid #d1d9e0}.werkl-cms-preview-newest-listing .werkl-cms-preview-newest-listing-item time{font-size:12px;line-height:14px;font-weight:normal;margin:0 0 6px 0}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/44.css:
--------------------------------------------------------------------------------
1 | .sw-blog-author-detail .smart-bar__actions span{display:flex}.sw-blog-author-detail .smart-bar__actions .sw-tooltip--wrapper{margin-left:8px}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/462.css:
--------------------------------------------------------------------------------
1 | .werkl-field--switch{margin-top:0;margin-bottom:0}.werkl-extension-component{width:100%;height:100%}.serp-preview-card .serp-preview{margin-bottom:20px}.serp-preview-card .serp-preview h3{font-family:arial,sans-serif !important;margin:0;color:#1a0dab;font-size:18px;font-weight:400;line-height:1.2;word-break:break-all}.serp-preview-card .serp-preview p{font-family:arial,sans-serif !important;color:#4d5156;font-size:13px;line-height:1.4;margin-top:5px;word-break:break-all}.serp-preview-card .serp-preview cite{font-family:arial,sans-serif !important;margin:0;font-style:normal;height:18px;color:#006621;font-size:14px;line-height:16px;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/470.css:
--------------------------------------------------------------------------------
1 | .werkl-cms-preview-blog-listing{width:100%;background:#fff;font-size:22px;color:#52667a;font-weight:600;border-radius:5px;padding:20px}.werkl-cms-preview-blog-listing h2{grid-column:span 2;font-size:16px;line-height:18px;margin:0 0 2px 0}.werkl-cms-preview-blog-listing .werkl-cms-preview-blog-listing-item{display:grid;grid-template-columns:1fr 1fr;grid-gap:20px;row-gap:0}.werkl-cms-preview-blog-listing .werkl-cms-preview-blog-listing-item div>div{margin:10px 0;height:.7em;border-radius:4px;background-color:#f0f2f5}.werkl-cms-preview-blog-listing .werkl-cms-preview-blog-listing-item hr{max-width:90%;margin:10px auto;border:1px solid #d1d9e0}.werkl-cms-preview-blog-listing .werkl-cms-preview-blog-listing-item time{font-size:12px;line-height:14px;font-weight:normal;margin:0 0 6px 0}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/485.css:
--------------------------------------------------------------------------------
1 | .sw-blog-detail-config-filter .sw-field--checkbox:last-child{margin-bottom:0}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/528.css:
--------------------------------------------------------------------------------
1 | .werkl-cms-el-newest-listing{width:100%;border:1px solid #dadee5;border-radius:4px;background:#fff;padding:10px}.werkl-cms-el-newest-listing h2{margin:10px}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/549.css:
--------------------------------------------------------------------------------
1 | .werkl-cms-el-config-newest-listing{width:100%}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/618.css:
--------------------------------------------------------------------------------
1 | .werkl-cms-el-blog-detail{width:100%;border:1px solid #dadee5;border-radius:4px;background:#fff;padding:10px}.werkl-cms-el-blog-detail .werkl-cms-el-blog-placeholder div{margin:15px 30px;height:1.5em;border-radius:4px;background-color:#f0f2f5}.werkl-cms-el-blog-detail .werkl-cms-el-blog-placeholder div.werkl-cms-el-werkl-cms-el-blog__placeholder{margin:15px 30px 15px 70px}.werkl-cms-el-blog-detail hr{max-width:90%;margin:10px auto;border:1px solid #d1d9e0}.werkl-cms-el-blog-detail h2{margin:10px}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/656.css:
--------------------------------------------------------------------------------
1 | .werkl-blog-list .is--inactive{color:#de294c}.werkl-blog-list .is--active{color:#37d046}.werkl-blog-list .sw-data-grid__cell--title{width:82%}.werkl-blog-list .sw-page__content .sw-page__side-content{grid-area:a}.werkl-blog-list .sw-page__content .sw-page__side-content .sw-tree .sw-tree-actions__headline{font-size:14px;font-weight:bold;height:64px;color:#52667a}.werkl-blog-list .sw-page__content .sw-page__side-content .sw-tree__content,.werkl-blog-list .sw-page__content .sw-page__side-content .sw-tree .sw-tree-actions__headline{border-left:1px solid #d1d9e0}.werkl-blog-list .sw-page__content .sw-page__main-content{grid-area:b}.werkl-blog-list .sw-page__content .sw-page__sidebar{grid-area:c;padding:40px 15px}.werkl-blog-list .sw-page__content.has--smart-bar.has--side-content{grid-template-columns:120px 440px auto;grid-template-areas:"c a b"}.werkl-blog-list .sw-page__content .sw-data-grid__cell--active .sw-data-grid__cell-content{justify-content:center}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/70.css:
--------------------------------------------------------------------------------
1 | .werkl-cms-preview-blog-detail{width:100%;background:#fff;font-size:22px;color:#52667a;font-weight:600;border-radius:5px;padding:20px}.werkl-cms-preview-blog-detail h2{grid-column:span 2;font-size:16px;line-height:18px;margin:0 0 2px 0}.werkl-cms-preview-blog-detail .werkl-cms-preview-blog-detail-item div>div{margin:10px 0;height:.7em;border-radius:4px;background-color:#f0f2f5}.werkl-cms-preview-blog-detail .werkl-cms-preview-blog-detail-item hr{max-width:90%;margin:10px auto;border:1px solid #d1d9e0}.werkl-cms-preview-blog-detail .werkl-cms-preview-blog-detail-item time{font-size:12px;line-height:14px;font-weight:normal;margin:0 0 6px 0}.werkl-cms-preview-blog-detail .werkl-cms-preview-blog-detail-item p{font-size:12px;line-height:14px;font-weight:normal}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/725.css:
--------------------------------------------------------------------------------
1 | .werkl-cms-preview-blog-categories{width:100%;background:#fff;font-size:22px;color:#52667a;font-weight:600;border-radius:5px;padding:20px}.werkl-cms-preview-blog-categories h2{grid-column:span 2;font-size:16px;line-height:18px;margin:0 0 2px 0}.werkl-cms-preview-blog-categories .werkl-cms-preview-blog-categories-item{display:grid;grid-template-columns:1fr 1fr;grid-gap:20px;row-gap:0}.werkl-cms-preview-blog-categories .werkl-cms-preview-blog-categories-item div>div{margin:10px 0;height:.7em;border-radius:4px;background-color:#f0f2f5}.werkl-cms-preview-blog-categories .werkl-cms-preview-blog-categories-item hr{max-width:90%;margin:10px auto;border:1px solid #d1d9e0}.werkl-cms-preview-blog-categories .werkl-cms-preview-blog-categories-item time{font-size:12px;line-height:14px;font-weight:normal;margin:0 0 6px 0}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/75.css:
--------------------------------------------------------------------------------
1 | .werkl-cms-el-blog-single-select{width:100%;padding:20px}.werkl-cms-el-blog-single-select h6{color:#0063ae;font-size:14px;text-transform:uppercase;margin-bottom:0;line-height:1.2}.werkl-cms-el-blog-single-select h3{margin:7px 0 18px;color:#343434;font-size:23px;line-height:1.2}.werkl-cms-el-blog-single-select img{width:100%;height:100%;max-height:225px;object-fit:cover}.werkl-cms-el-blog-single-select p{margin:18px 0;display:block}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/788.css:
--------------------------------------------------------------------------------
1 | .werkl-cms-preview-blog-single-entry{width:100%;background:#fff;font-size:22px;color:#52667a;font-weight:600;border-radius:5px;padding:20px}.werkl-cms-preview-blog-single-entry h2{grid-column:span 2;font-size:16px;line-height:18px;margin:0 0 2px 0}.werkl-cms-preview-blog-single-entry .werkl-cms-preview-blog-single-entry-item{width:100%}.werkl-cms-preview-blog-single-entry .werkl-cms-preview-blog-single-entry-item div>div{margin:10px 0;height:.7em;border-radius:4px;background-color:#f0f2f5}.werkl-cms-preview-blog-single-entry .werkl-cms-preview-blog-single-entry-item hr{max-width:90%;margin:10px auto;border:1px solid #d1d9e0}.werkl-cms-preview-blog-single-entry .werkl-cms-preview-blog-single-entry-item time{font-size:12px;line-height:14px;font-weight:normal;margin:0 0 6px 0}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/859.css:
--------------------------------------------------------------------------------
1 | .werkl-blog-author-list .sw-data-grid__cell--title{width:82%}.werkl-blog-author-list .sw-page__content .sw-page__main-content{grid-area:b;border-left:1px solid #d1d9e0}.werkl-blog-author-list .sw-page__content .sw-page__sidebar{grid-area:a;padding:40px 15px}.werkl-blog-author-list .sw-page__content.has--smart-bar.has--side-bar{grid-template-columns:120px auto;grid-template-areas:"a b"}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/925.css:
--------------------------------------------------------------------------------
1 | .sw-blog-config-filter .sw-field--checkbox:last-child{margin-bottom:0}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/940.css:
--------------------------------------------------------------------------------
1 | .sw-cms-el-preview-categories{width:100%;background:#fff;font-size:22px;color:#52667a;font-weight:600}.sw-cms-el-preview-categories .sw-cms-el-category-placeholder-listing div{margin:10px 0;height:.4em;border-radius:25px;background-color:#f0f2f5}.sw-cms-el-preview-categories .sw-cms-el-category-placeholder-listing div.sw-cms-el-category-navigation__placeholder--subcategory{margin:7px 20px}.sw-cms-el-preview-categories .sw-cms-el-category-placeholder-listing div.sw-cms-el-category-navigation__placeholder--subcategory:last-of-type{margin-right:10px}.sw-cms-el-preview-categories hr{max-width:100%;margin:10px auto;height:1px;border:0 none;background-color:#d1d9e0}.sw-cms-el-preview-categories p{font-size:14px;margin:auto 10px auto 0}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/css/965.css:
--------------------------------------------------------------------------------
1 | .werkl-blog-cms-stage-section .sw-cms-slot .sw-cms-slot__actions{grid-template-columns:auto}
2 |
--------------------------------------------------------------------------------
/src/Resources/public/static/js/33c36fd5d76856f33f76.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[968],{1968:function(e,o,r){r.r(o);let{Criteria:t}=Shopware.Data;o.default={computed:{globalCategoryRepository(){return this.repositoryFactory.create("werkl_blog_category")}},methods:{searchCategories(e){let o=new t(1,500);return o.setTerm(e),this.globalCategoryRepository.search(o,Shopware.Context.api)}}}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/369933b2aab52e07a724.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[359],{9359:function(e,t,l){l.r(t),l.d(t,{default:function(){return i}});let{Mixin:n}=Shopware;var i={template:'{% block werkl_cms_element_blog_single_select_config %}\n\n \n\n \n \n {{ item.translated.title || item.name }}\n \n \n\n \n \n \n {{ item.translated.title || item.name }}\n \n \n \n \n
\n{% endblock %}\n',inject:["repositoryFactory"],mixins:[n.getByName("cms-element")],data(){return{blogEntry:null,selectedEntry:null}},computed:{blogEntryRepository(){return this.repositoryFactory.create("werkl_blog_entries")}},created(){this.createdComponent()},methods:{createdComponent(){this.initElementConfig("blog-single-select")}}}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/4a38dd497688ee75a124.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[347],{6347:function(n,l,e){e.r(l),e.d(l,{default:function(){return o}});var o={template:'{% block werkl_cms_block_listing %}\n\n \n
\n{% endblock %}\n'}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/4c6e82e67679d63a7a6f.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[973],{6973:function(n,e,t){t.r(e),t.d(e,{default:function(){return i}});let{State:o}=Shopware;var i={template:'\n \n \n \n
\n',props:{positionIdentifier:{type:String,required:!0}},computed:{componentSections(){return o.get("extensionComponentSections").identifier[this.positionIdentifier]??[]}}}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/5ef3c68e64f9eeacfb51.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[768],{8768:function(e,t,n){n.r(t),n.d(t,{default:function(){return i}});let{Mixin:o}=Shopware;var i={template:'{% block werkl_cms_element_blog_listing_config %}\n
\n{% endblock %}\n',inject:["repositoryFactory"],mixins:[o.getByName("cms-element")],data(){return{}},computed:{},watch:{},created(){this.createdComponent()},methods:{async createdComponent(){this.initElementConfig("blog-categories")},getSelectedCategories(){}}}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/8b2b6c5bb0a41393003a.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[185],{8185:function(n,e,l){l.r(e),l.d(e,{default:function(){return o}});var o={template:'{% block werkl_cms_block_newest_listing %}\n\n \n
\n{% endblock %}\n'}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/915ebe549e746152b355.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[984],{1984:function(e,t,a){a.r(t),t.default={methods:{async createdComponent(){Shopware.Store.get("adminMenu").collapseSidebar();let e=Shopware.State.getters["context/isSystemDefaultLanguage"];this.cmsPageState.setIsSystemDefaultLanguage(e),e||Shopware.State.commit("context/resetLanguageToDefault"),Shopware.Context.api.languageId!==Shopware.Context.api.systemLanguageId&&Shopware.State.commit("context/setApiLanguageId",Shopware.Context.api.languageId),this.resetCmsPageState(),this.createPage(),this.createBlog(this.page.id),this.isLoading=!1,this.setPageContext()},createBlog(e){this.blog=this.blogRepository.create(),this.blog.cmsPageId=e,this.blogId=this.blog.id}}}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/94c20f9caef696e0136f.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[622],{7622:function(l,e,n){n.r(e),n.d(e,{default:function(){return o}});var o={template:'{% block werkl_cms_block_detail %}\n\n \n
\n{% endblock %}\n'}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/b5b1227c870757fb6c15.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[182],{2182:function(n,e,l){l.r(e),l.d(e,{default:function(){return o}});var o={template:'{% block werkl_cms_block_blog_single_entry %}\n\n \n
\n{% endblock %}\n'}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/baa196a2bd193a4a577c.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[565],{9565:function(e,s,o){o.r(s),s.default={computed:{sortPageTypes(){let e=this.$super("sortPageTypes");return e.push({value:"blog_detail",name:this.$tc("sw-cms.sorting.labelSortByBlogPages")}),e}}}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/ca06e9e52b00474374b8.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[291],{8291:function(e,o,t){t.r(o),o.default={methods:{createdComponent(){Shopware.State.commit("context/resetLanguageToDefault"),this.blogAuthor=this.blogAuthorRepository.create(Shopware.Context.api)}}}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/d3b8f578386315abdd6d.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[939],{5939:function(e,n,o){o.r(n),o.d(n,{default:function(){return l}});var l={template:'{% block werkl_cms_block_categories %}\n\n \n
\n{% endblock %}\n'}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/ec3c4260240b6a3b8ef7.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[262],{7262:function(e,n,t){t.r(n),t.d(n,{default:function(){return a}});var a={template:'\n \n {% block werkl_block_list_tab_item %}\n \n {{ $tc(\'werkl-blog.general.mainMenuItemList\') }}\n \n {% endblock %}\n\n {% block werkl_block_tags_tab_item %}\n \n {{ $tc(\'werkl-blog-author.general.mainMenuItemList\') }}\n \n {% endblock %}\n \n \n',props:{defaultItem:{type:String,default:"blog"}},methods:{onChangeTab(e){this.currentTab=e}}}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/fbe93fc23dd1cbadee55.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[778],{4778:function(e,t,n){n.r(t),n.d(t,{default:function(){return i}});var i={template:'{% block sw_tree_item_children_items %}\n\n {% block sw_tree_item_children_items_slots %}\n {% parent %}\n {% endblock %}\n \n{% endblock %}\n\n{% block sw_tree_items_actions_edit %}\n\n {{ $tc(\'werkl-blog-tree-item.actions.edit\') }}\n \n{% endblock %}\n',computed:{parentScope(){let e=this.$parent;for(;"sw-tree"!==e.$options.name;)e=e.$parent;return e}},data(){return{editingCategory:null}},methods:{onEditCategory(e){this.editingCategory=e,this.currentEditElement=e.id,this.editElementName()},onBlurTreeItemInput(e){this.abortCreateElement(e)},onCancelSubmit(e){this.abortCreateElement(e)},abortCreateElement(e){this.currentEditElement=null,this.editingCategory=null,this.$super("abortCreateElement",e)}}}}}]);
--------------------------------------------------------------------------------
/src/Resources/public/static/js/fceb9e682485d5fab032.js:
--------------------------------------------------------------------------------
1 | "use strict";(window["webpackJsonpPluginwerkl-open-blogware"]=window["webpackJsonpPluginwerkl-open-blogware"]||[]).push([[990],{7990:function(e,n,l){l.r(n),l.d(n,{default:function(){return a}});var o=l(2059),a={template:'{% block sw_cms_sidebar_block_overview_category_options %}\n{% parent %}\nBlog \n{% endblock %}\n\n{% block sw_cms_sidebar_page_settings_type_field_options %}\n{% parent %}\n\n {{ $tc(\'sw-cms.detail.label.pageTypeBlog\') }}\n \n{% endblock %}\n\n{% block sw_cms_sidebar_page_settings_type_field %}\n{% parent %}\n \n{% endblock %}\n',computed:{isBlogDetail(){return this.page.type===o.A.PAGE_TYPES.BLOG_DETAIL}}}}}]);
--------------------------------------------------------------------------------
/src/Resources/snippet/de_DE/storefront.de-DE.json:
--------------------------------------------------------------------------------
1 | {
2 | "werkl-blog": {
3 | "detail": {
4 | "meta": {
5 | "author": "Autor",
6 | "category": "Kategorien"
7 | }
8 | },
9 | "element": {
10 | "detail": {
11 | "warning": {
12 | "heading": "Fehler beim laden der Blog Detail Ansicht",
13 | "content": "Vielleicht hast du das Blog Detail CMS Element auf derselben Seite wie das CMS Listing Element?"
14 | }
15 | },
16 | "singleSelect": {
17 | "emptyResult": "Es ist kein Blog Eintrag ausgewählt."
18 | }
19 | },
20 | "box": {
21 | "author": {
22 | "countEntries": "Beiträge"
23 | }
24 | },
25 | "listing": {
26 | "readMoreLabel": "mehr lesen",
27 | "emptyResultMessage": "Wir konnten leider keine Suchergebnisse finden ...",
28 | "filterPanelResetAll": "Zurück setzen",
29 | "filterBlogCategoriesDisplayName": "Kategorien",
30 | "filterBlogAuthorDisplayName": "Autor",
31 | "filterBlogTagsDisplayName": "Tags"
32 | },
33 | "search": {
34 | "tabs": {
35 | "product": "Produkt",
36 | "blog": "Blog Eintrag"
37 | },
38 | "in": "In",
39 | "searchAllResults": "Suchergebnis für Blogs anzeigen",
40 | "searchResults": "{1} 1 Eintrag|]1,Inf[ %count% Eingaben",
41 | "headline": "{0} Zu \"%searchTerm%\" wurde kein Blog gefunden | {1} Zu \"%searchTerm%\" wurde 1 Blog gefunden | ]1,Inf[ Zu \"%searchTerm%\" wurden %count% Blogs gefunden",
42 | "emptyResult": "Wir konnten leider keine Suchergebnisse finden ..."
43 | }
44 | },
45 | "header": {
46 | "searchAllResults": "Alle Produkte anzeigen Suchergebnis",
47 | "searchPlaceholder": "Suche nach Produkten, Blogeinträgen, Autoren..."
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Resources/snippet/en_GB/storefront.en-GB.json:
--------------------------------------------------------------------------------
1 | {
2 | "werkl-blog": {
3 | "detail": {
4 | "meta": {
5 | "author": "Author",
6 | "category": "Categories"
7 | }
8 | },
9 | "element": {
10 | "detail": {
11 | "warning": {
12 | "heading": "Error while loading the detail page",
13 | "content": "There seems to be an issue while loading the blog detail page. Maybe you have the Blog detail CMS element within the same page as the Blog listing CMS element?"
14 | }
15 | },
16 | "singleSelect": {
17 | "emptyResult": "No blog entry was chosen"
18 | }
19 | },
20 | "box": {
21 | "author": {
22 | "countEntries": "Entries"
23 | }
24 | },
25 | "listing": {
26 | "readMoreLabel": "read more",
27 | "emptyResultMessage": "We couldn't find any results for your search request",
28 | "filterPanelResetAll": "Reset",
29 | "filterBlogCategoriesDisplayName": "Categories",
30 | "filterBlogAuthorDisplayName": "Author",
31 | "filterBlogTagsDisplayName": "Tags"
32 | },
33 | "search": {
34 | "tabs": {
35 | "product": "Product",
36 | "blog": "Blog"
37 | },
38 | "in": "In",
39 | "searchAllResults": "Show all blogs search result",
40 | "searchResults": "{1} 1 Entry|]1,Inf[ %count% Entries",
41 | "emptyResult": "No blog entries found with the request keyword",
42 | "headline": "{0} 0 blogs found for \"%searchTerm%\" | {1} One blog found for \"%searchTerm%\" | ]1,Inf[ %count% blogs found for \"%searchTerm%\""
43 | }
44 | },
45 | "header": {
46 | "searchAllResults": "Show all products search result",
47 | "searchPlaceholder": "Search products, blog entries, authors"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/block/cms-block-blog-categories.html.twig:
--------------------------------------------------------------------------------
1 | {% block block_werkl_blog_categories %}
2 | {% set element = block.slots.getSlot('categories') %}
3 |
4 |
5 | {% sw_include "@Storefront/storefront/element/cms-element-" ~ element.type ~ ".html.twig" ignore missing %}
6 |
7 |
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/block/cms-block-blog-detail.html.twig:
--------------------------------------------------------------------------------
1 | {% block block_werkl_blog_detail %}
2 | {% set element = block.slots.getSlot('blogDetail') %}
3 |
4 |
5 | {% sw_include "@Storefront/storefront/element/cms-element-" ~ element.type ~ ".html.twig" ignore missing %}
6 |
7 |
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/block/cms-block-blog-listing.html.twig:
--------------------------------------------------------------------------------
1 | {% block block_werkl_blog_listing %}
2 | {% set element = block.slots.getSlot('listing') %}
3 |
4 |
5 | {% sw_include "@Storefront/storefront/element/cms-element-" ~ element.type ~ ".html.twig" ignore missing %}
6 |
7 |
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/block/cms-block-blog-newest-listing.html.twig:
--------------------------------------------------------------------------------
1 | {% block block_newest_listing %}
2 | {% set element = block.slots.getSlot('listing') %}
3 |
4 |
5 | {% sw_include "@Storefront/storefront/element/cms-element-" ~ element.type ~ ".html.twig" ignore missing %}
6 |
7 | {% endblock %}
8 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/block/cms-block-blog-single-entry.html.twig:
--------------------------------------------------------------------------------
1 | {% block block_werkl_blog_single_entry %}
2 | {% set element = block.slots.getSlot('singleEntry') %}
3 |
4 |
5 | {% sw_include "@Storefront/storefront/element/cms-element-" ~ element.type ~ ".html.twig" ignore missing %}
6 |
7 |
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/component/blog/_partials/_block_author.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_block_partials_author %}
2 |
3 | {% sw_icon 'avatar' style { 'size': 'sm' } %}
4 |
8 | {{ author.displayName ?: author.firstName ~ ' ' ~ author.lastName }}
9 |
10 |
11 |
12 | {% endblock %}
13 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/component/blog/_partials/_block_category.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_block_partials_category %}
2 | {% set categoriesName = [] %}
3 | {% for category in categories %}
4 | {% set categoriesName = categoriesName|merge([category.translated.name]) %}
5 | {% endfor %}
6 |
7 | {% sw_icon 'folder-thumbnail' style { 'size': 'sm' } %}
8 |
12 | {{ categoriesName|join(', ') }}
13 |
14 |
15 |
16 | {% endblock %}
17 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/component/blog/newest-listing.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_element_blog_newest_listing_row %}
2 |
3 | {% if searchResult.total > 0 %}
4 | {% block werkl_element_blog_newest_listing_col %}
5 |
6 | {% for article in searchResult %}
7 | {% block werkl_element_blog_newest_listing_box %}
8 |
9 | {% sw_include '@Storefront/storefront/component/blog/card/box.html.twig' %}
10 |
11 | {% endblock %}
12 | {% endfor %}
13 |
14 | {% endblock %}
15 | {% else %}
16 | {% block werkl_element_blog_newest_listing_col_empty %}
17 |
18 | {% block werkl_element_blog_newest_listing_col_empty_alert %}
19 | {% sw_include '@Storefront/storefront/utilities/alert.html.twig' with {
20 | type: 'info',
21 | content: 'werkl-blog.search.emptyResult'|trans|sw_sanitize
22 | } %}
23 | {% endblock %}
24 |
25 | {% endblock %}
26 | {% endif %}
27 |
28 | {% endblock %}
29 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/component/listing/filter/blog-filter-multi-select-list-item.html.twig:
--------------------------------------------------------------------------------
1 | {% sw_extends '@Storefront/storefront/component/listing/filter/filter-multi-select-list-item.html.twig' %}
2 |
3 | {% block component_filter_multi_select_list_item %}
4 |
5 | {% set id = element.id %}
6 |
7 | {#
8 | Some entities (e.g. BlogAuthorEntity) provide a getFullName method
9 | which should be used for display. Others, like TagEntity, only have
10 | a name property. Fallback to the name attribute if getFullName does
11 | not exist to avoid empty labels in the filter.
12 | #}
13 | {% if element.getFullName is defined %}
14 | {% set name = element.getFullName() %}
15 | {% else %}
16 | {% set name = element.name %}
17 | {% endif %}
18 |
19 | {% block component_filter_multi_select_list_item_checkbox_input %}
20 | {{ parent() }}
21 | {% endblock %}
22 |
23 | {% block component_filter_multi_select_list_item_label_element %}
24 | {{ parent() }}
25 | {% endblock %}
26 |
27 | {% endblock %}
28 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/component/listing/filter/blog-filter-multi-select.html.twig:
--------------------------------------------------------------------------------
1 | {% sw_extends '@Storefront/storefront/component/listing/filter/filter-multi-select.html.twig' %}
2 |
3 | {% block component_filter_multi_select_list_item_inner %}
4 | {% sw_include '@Storefront/storefront/component/listing/filter/blog-filter-multi-select-list-item.html.twig' %}
5 | {% endblock %}
6 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/element/cms-element-blog-categories.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_element_blog_categories %}
2 | {% set searchResult = element.data %}
3 |
4 |
5 | {% for category in searchResult.entities.elements %}
6 |
7 | {{ category.translated.name ? category.name }}
8 |
9 | {% endfor %}
10 |
11 |
12 | {% endblock %}
13 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/element/cms-element-blog-newest-listing.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_element_blog_newest_listing %}
2 |
3 | {% block werkl_element_blog_newest_listing_wrapper %}
4 | {% sw_include '@Storefront/storefront/component/blog/newest-listing.html.twig' with {
5 | searchResult: element.data,
6 | } %}
7 | {% endblock %}
8 |
9 | {% endblock %}
10 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/element/cms-element-blog-single-select.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_element_blog_single_select %}
2 | {% set article = element.data %}
3 |
4 | {% if article|length %}
5 | {% sw_include '@Storefront/storefront/component/blog/card/box.html.twig' %}
6 | {% else %}
7 | {% sw_include '@Storefront/storefront/utilities/alert.html.twig' with {
8 | type: "primary",
9 | content: "werkl-blog.element.singleSelect.emptyResult"|trans|sw_sanitize,
10 | icon: false
11 | } %}
12 | {% endif %}
13 |
14 | {% endblock %}
15 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/element/cms-element-blog.html.twig:
--------------------------------------------------------------------------------
1 | {% block werkl_element_blog_listing %}
2 | {% set cmsPage = page.landingPage ? page.landingPage.cmsPage : page.cmsPage %}
3 | {# @var result \Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult #}
4 | {% set searchResult = element.data %}
5 | {% set config = element.fieldConfig.elements %}
6 |
7 | {% set slot = cmsPage.firstElementOfType('blog') %}
8 |
9 | {% set filterUrl = null %}
10 | {% set dataUrl = null %}
11 |
12 | {% if page.landingPage %}
13 | {% set dataUrl = url('frontend.landing.page', { landingPageId: page.landingPage.id }) %}
14 | {% elseif page.header.navigation.active.id %}
15 | {% set dataUrl = url('frontend.cms.navigation.page', { navigationId: page.header.navigation.active.id }) %}
16 | {% endif %}
17 |
18 | {% set params = { slots: slot.id, 'no-aggregations': 1 } %}
19 |
20 | {% block werkl_element_blog_listing_wrapper %}
21 | {% block werkl_block_filter_panel %}
22 | {% if config.showCategoryFilter.value or config.showAuthorFilter.value %}
23 |
26 | {% sw_include '@Storefront/storefront/component/listing/blog-filter-panel.html.twig' with {
27 | listing: searchResult,
28 | sidebar: false
29 | } %}
30 |
31 | {% endif %}
32 | {% endblock %}
33 |
34 | {% sw_include '@Storefront/storefront/component/blog/listing.html.twig' with {
35 | searchResult: searchResult,
36 | dataUrl: dataUrl,
37 | filterUrl: filterUrl,
38 | params: params,
39 | config: config
40 | } %}
41 | {% endblock %}
42 | {% endblock %}
43 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/layout/header/search.html.twig:
--------------------------------------------------------------------------------
1 | {% sw_extends '@Storefront/storefront/layout/header/search.html.twig' %}
2 |
3 | {% block layout_header_search %}
4 | {% if app.request.attributes.get('_route') == 'werkl.frontend.blog.search' %}
5 |
7 |
18 |
19 | {% else %}
20 | {{ parent() }}
21 | {% endif %}
22 | {% endblock %}
23 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/page/blog-search/index.html.twig:
--------------------------------------------------------------------------------
1 | {% sw_extends '@Storefront/storefront/page/search/index.html.twig' %}
2 |
3 | {% block page_search %}
4 |
5 | {% block page_search_headline %}
6 |
7 | {% block page_search_headline_text %}
8 | {{ "werkl-blog.search.headline"|trans({
9 | '%count%': page.listing.total,
10 | '%searchTerm%': page.searchTerm,
11 | }) }}
12 | {% endblock %}
13 |
14 | {% endblock %}
15 |
16 | {% sw_include '@Storefront/storefront/page/blog-search/search-pagelet.html.twig' with { page: page } %}
17 |
18 | {% endblock %}
19 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/page/blog-search/search-pagelet.html.twig:
--------------------------------------------------------------------------------
1 | {% set listingColumns = 'col-sm-6 col-lg-4 col-xl-3' %}
2 |
3 | {% block element_product_listing_wrapper %}
4 |
23 | {% endblock %}
24 |
--------------------------------------------------------------------------------
/src/Resources/views/storefront/page/rss.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% if page.header.navigation.active.translated.metaTitle %}
5 | {{ page.header.navigation.active.translated.metaTitle|striptags|trim }}
6 | {% else %}
7 | Blog
8 | {% endif %}
9 | {{ app.request.schemeAndHttpHost }}
10 | {{ app.request.locale }}
11 | {% if page.header.navigation.active.translated.metaDescription %}
12 | {{ page.header.navigation.active.translated.metaDescription|striptags|trim|u.truncate(maxLength ?? 160, '…') }}
13 | {% endif %}
14 | {% for result in results %}
15 | -
16 | {% set title = result.translated.metaTitle ?? result.translated.title %}
17 |
{{ title|striptags|trim }}
18 | {{ app.request.schemeAndHttpHost ~ "/blog/" ~ result.translated.slug }}
19 | {{ app.request.schemeAndHttpHost ~ "/blog/" ~ result.translated.slug }}
20 | {{ result.translated.metaDescription|striptags|trim|u.truncate(maxLength ?? 160, '…') }}
21 | {% if result.blogAuthor.email != "N/A" %}
22 | {{ result.blogAuthor.email ~ " (" ~ result.blogAuthor.displayName ~ ")"}}
23 | {% endif %}
24 | {{ result.publishedAt | date("d M Y H:i:s T") }}
25 |
26 | {% endfor %}
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/Util/Update.php:
--------------------------------------------------------------------------------
1 | getCurrentPluginVersion(), '1.1.0', '<')) {
18 | $this->updateTo110($container);
19 | }
20 |
21 | if (version_compare($updateContext->getCurrentPluginVersion(), '1.3.0', '<')) {
22 | $this->updateTo130($container);
23 | }
24 | }
25 |
26 | private function updateTo110(ContainerInterface $container): void
27 | {
28 | /** @var Connection $connection */
29 | $connection = $container->get(Connection::class);
30 |
31 | $blogEntriesEntityName = BlogEntriesDefinition::ENTITY_NAME;
32 | if (!$connection->getSchemaManager()->tablesExist([$blogEntriesEntityName])) {
33 | $blogEntriesMigration = new Migration1602739765AddTeaserImageColumnToBlogEntries();
34 | $blogEntriesMigration->update($connection);
35 | }
36 | }
37 |
38 | private function updateTo130(ContainerInterface $container): void
39 | {
40 | /** @var Connection $connection */
41 | $connection = $container->get(Connection::class);
42 |
43 | $blogEntriesEntityName = BlogEntriesDefinition::ENTITY_NAME;
44 | if (!$connection->getSchemaManager()->tablesExist([$blogEntriesEntityName])) {
45 | $blogEntriesMigration = new Migration1612160298CreatePubslihedDateColumn();
46 | $blogEntriesMigration->update($connection);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/tests/Cypress/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .DS_Store
3 | .idea
4 | /node_modules
5 |
6 | /cypress/videos
7 | /cypress/screenshots
8 |
9 |
--------------------------------------------------------------------------------
/tests/Cypress/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## Easy Testing
3 |
4 | Running Cypress tests is easy!
5 | Just install it by using the built in makefile commands
6 | and either open your tests in the Cypress UI, or run them directly from your CLI.
7 |
8 |
9 | ### Installation
10 |
11 | This folder contains a `makefile` with all required commands.
12 | Run the installation command to install Cypress and all its dependencies on your machine
13 |
14 | ```ruby
15 | make install
16 | ```
17 |
18 |
19 | ### Cypress UI
20 | If you want to run your Cypress UI, just open it with the following command.
21 | Please note, because this is an Open Source project, we cannot include a
22 | shop URL in the configuration. Thus you need to provide it on your own.
23 | The tests might differ between Shopware versions, though the baseline is always the same.
24 | So there is an additional parameter to tell Cypress what Shopware version should be tested.
25 | This parameter is optional and its default is always the latest supported Shopware version.
26 |
27 | ```ruby
28 | make open-ui url=https://my-local-or-remote-domain
29 |
30 | make open-ui url=https://my-local-or-remote-domain shopware=6.3
31 | ```
32 |
33 | ### Run in CLI
34 | You can also use the CLI command to run Cypress on your machine or directly in your build pipeline.
35 | Cypress will then test your local or remote shop with the tests of the provided Shopware version.
36 |
37 | ```ruby
38 | make run url=https://my-local-or-remote-domain shopware=6.x
39 | ```
40 |
41 | ### Troubleshooting
42 |
43 | Shopware 6.4.4.0 introduced LAX cookies.
44 | The tests have been adjusted to work with that change, but you need to use HTTPS!
45 | Once changed, it should all work as expected.
--------------------------------------------------------------------------------
/tests/Cypress/cypress.config.example.js:
--------------------------------------------------------------------------------
1 | const { defineConfig } = require('cypress')
2 |
3 | module.exports = defineConfig({
4 | e2e: {
5 | experimentalSessionAndOrigin: true,
6 | },
7 | responseTimeout: 80000,
8 | env: {
9 | user: 'admin',
10 | pass: 'shopware',
11 | salesChannelName: 'Storefront',
12 | admin: '/admin',
13 | apiPath: 'api',
14 | locale: 'en-GB',
15 | shopwareRoot: "../../../../..",
16 | localUsage: false,
17 | usePercy: false,
18 | minAuthTokenLifetime: 60,
19 | acceptLanguage: 'en-GB,en;q=0.5',
20 | expectedVersion: '6.6.',
21 | grepOmitFiltered: true,
22 | grepFilterSpecs: true,
23 | },
24 | })
--------------------------------------------------------------------------------
/tests/Cypress/cypress/config/dev.json:
--------------------------------------------------------------------------------
1 | {
2 | "chromeWebSecurity": false,
3 | "watchForFileChanges": false,
4 | "trashAssetsBeforeRuns": true,
5 | "screenshotOnRunFailure": true,
6 | "experimentalSessionAndOrigin": true,
7 | "video": false,
8 | "retries": 1,
9 | "devices": [
10 | {
11 | "key": "desktop",
12 | "name": "Desktop",
13 | "width": 1920,
14 | "height": 1080,
15 | "userAgent": ""
16 | },
17 | {
18 | "key": "ipad-landscape",
19 | "name": "iPad (Landscape)",
20 | "width": 1024,
21 | "height": 768,
22 | "userAgent": "Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3"
23 | }
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/tests/Cypress/cypress/fixtures/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Using fixtures to represent data",
3 | "email": "hello@cypress.io",
4 | "body": "Fixtures are a great way to mock data for responses to routes"
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Cypress/cypress/integration/administration/cms.spec.js:
--------------------------------------------------------------------------------
1 | import blogDetailAction from '../../support/actions/admin/BlogDetailAction';
2 | import repoCmsPage from '../../support/repositories/admin/general/CmsPageRepository';
3 |
4 | const blogTitle = 'Blog Entry Title';
5 |
6 | describe('Blog CMS: content with cms blocks', () => {
7 | beforeEach(() => {
8 | cy.authenticate()
9 | .then(() => {
10 | cy.viewport(1920, 1080);
11 | cy.openInitialPage(`${Cypress.env('admin')}#/blog/module/create`);
12 | });
13 | });
14 |
15 | it('@content: should not show werkl-blog block category', () => {
16 |
17 | blogDetailAction.openBlockSidebar();
18 |
19 | repoCmsPage.getBlockCategoryWerklBlogOption().should('not.exist');
20 | });
21 |
22 | it.only('@content: can drag block to stage', () => {
23 | blogDetailAction.openSidebar();
24 |
25 | blogDetailAction.fillBlogForm(blogTitle, true, true, true);
26 |
27 | blogDetailAction.addFullWidthCmsSection();
28 |
29 | blogDetailAction.setBlockCategory('Text');
30 |
31 | repoCmsPage.getCmsTextBlock().should('be.visible');
32 |
33 | repoCmsPage.getCmsTextBlock().dragTo(repoCmsPage.getEmptySectionSelector());
34 |
35 | repoCmsPage.getCmsBlockConfigOverlay().should('exist');
36 | });
37 | });
38 |
--------------------------------------------------------------------------------
/tests/Cypress/cypress/plugins/index.js:
--------------------------------------------------------------------------------
1 | ///
2 | // ***********************************************************
3 | // This example plugins/index.js can be used to load plugins
4 | //
5 | // You can change the location of this file or turn off loading
6 | // the plugins file with the 'pluginsFile' configuration option.
7 | //
8 | // You can read more here:
9 | // https://on.cypress.io/plugins-guide
10 | // ***********************************************************
11 |
12 | // This function is called when a project is opened or re-opened (e.g. due to
13 | // the project's config changing)
14 |
15 | /**
16 | * @type {Cypress.PluginConfig}
17 | */
18 | // eslint-disable-next-line no-unused-vars
19 | module.exports = (on, config) => {
20 | // `on` is used to hook into various events Cypress emits
21 | // `config` is the resolved Cypress config
22 | }
23 |
--------------------------------------------------------------------------------
/tests/Cypress/cypress/support/commands.js:
--------------------------------------------------------------------------------
1 | // ***********************************************
2 | // This example commands.js shows you how to
3 | // create various custom commands and overwrite
4 | // existing commands.
5 | //
6 | // For more comprehensive examples of custom
7 | // commands please read more here:
8 | // https://on.cypress.io/custom-commands
9 | // ***********************************************
10 | //
11 | //
12 | // -- This is a parent command --
13 | // Cypress.Commands.add("login", (email, password) => { ... })
14 | //
15 | //
16 | // -- This is a child command --
17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
18 | //
19 | //
20 | // -- This is a dual command --
21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
22 | //
23 | //
24 | // -- This will overwrite an existing command --
25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
26 |
27 | /**
28 | * Performs a drag and drop operation
29 | * @memberOf Cypress.Chainable#
30 | * @name dragTo
31 | * @param {String} targetEl - The target element to drag source to
32 | * @function
33 | */
34 | Cypress.Commands.add(
35 | "dragTo",
36 | {prevSubject: 'element'},
37 | (subject, targetEl) => {
38 | cy.wrap(subject).trigger("mousedown");
39 | cy.wait(200);
40 |
41 | cy.get('.is--draggable').should('be.visible');
42 | cy.get(targetEl)
43 | .should('be.visible')
44 | .trigger('mouseenter')
45 | .trigger('mousemove', 'center')
46 | .should('have.class', 'is--droppable')
47 | .trigger('mouseup');
48 | }
49 | );
50 |
--------------------------------------------------------------------------------
/tests/Cypress/cypress/support/index.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | require('@shopware-ag/e2e-testsuite-platform/cypress/support');
17 | require('./commands');
18 |
19 | Cypress.on('uncaught:exception', (err, runnable) => {
20 | // returning false here prevents Cypress from
21 | // failing the test because some third party apps
22 | // cause an error in the console which stops the test
23 | return false;
24 | });
25 |
--------------------------------------------------------------------------------
/tests/Cypress/cypress/support/repositories/admin/blog/BlogDetailsRepository.js:
--------------------------------------------------------------------------------
1 | class BlogDetailsRepository {
2 |
3 | /**
4 | * @returns {Cypress.Chainable>}
5 | */
6 | getPageHeadline() {
7 | return cy.get('.sw-sidebar-item__headline');
8 | }
9 |
10 | /**
11 | * @returns {Cypress.Chainable>}
12 | */
13 | getSaveButton() {
14 | return cy.get('.sw-cms-detail__save-action');
15 | }
16 |
17 | /**
18 | * @returns {Cypress.Chainable>}
19 | */
20 | getBlogDetailNavItem() {
21 | return cy.get(':nth-child(1) > .sw-sidebar-navigation-item');
22 | }
23 |
24 | /**
25 | * @returns {Cypress.Chainable>}
26 | */
27 | getBlogDetailNavItemBadge() {
28 | return this.getBlogDetailNavItem().children('.sidebar-item-badge');
29 | }
30 | }
31 |
32 | export default new BlogDetailsRepository();
33 |
--------------------------------------------------------------------------------
/tests/Cypress/cypress/support/repositories/admin/general/DatePickerRepository.js:
--------------------------------------------------------------------------------
1 | class DatePickerRepository {
2 |
3 | /**
4 | * Get today's date
5 | * @returns {Cypress.Chainable>}
6 | */
7 | getDatePickerToday() {
8 | return cy.get('.flatpickr-day.today');
9 | }
10 |
11 | /**
12 | * Get first day of the month in the date picker
13 | * @returns {Cypress.Chainable>}
14 | */
15 | getDatePickerStartOfMonth() {
16 | return cy.get('.flatpickr-day:first-child');
17 | }
18 |
19 | /**
20 | * Get last day of the month in the date picker
21 | * @returns {Cypress.Chainable>}
22 | */
23 | getDatePickerEndOfMonth() {
24 | return cy.get('.flatpickr-day:last-child');
25 | }
26 |
27 | /**
28 | * Get the previous month button in the date picker
29 | * @returns {Cypress.Chainable>}
30 | */
31 | getDatePickerPrevMonth() {
32 | return cy.get('.flatpickr-prev-month');
33 | }
34 |
35 | /**
36 | * Get the next month button in the date picker
37 | * @returns {Cypress.Chainable>}
38 | */
39 | getDatePickerNextMonth() {
40 | return cy.get('.flatpickr-next-month');
41 | }
42 | }
43 |
44 | export default new DatePickerRepository();
45 |
--------------------------------------------------------------------------------
/tests/Cypress/cypress/support/services/shopware/Shopware.js:
--------------------------------------------------------------------------------
1 | export default class Shopware {
2 |
3 | /**
4 | *
5 | * @returns {*}
6 | */
7 | getVersion() {
8 | return Cypress.env().SHOPWARE;
9 | }
10 |
11 | /**
12 | *
13 | * @param version
14 | * @returns {boolean}
15 | */
16 | isVersionLower(version) {
17 | const diff = this._cmpVersions(this.getVersion(), version);
18 | return (diff < 0);
19 | }
20 |
21 | /**
22 | *
23 | * @param version
24 | * @returns {boolean}
25 | */
26 | isVersionLowerEqual(version) {
27 | const diff = this._cmpVersions(this.getVersion(), version);
28 | return (diff <= 0);
29 | }
30 |
31 | /**
32 | *
33 | * @param version
34 | * @returns {boolean}
35 | */
36 | isVersionEqual(version) {
37 | const diff = this._cmpVersions(this.getVersion(), version);
38 | return (diff === 0);
39 | }
40 |
41 | /**
42 | *
43 | * @param version
44 | * @returns {boolean}
45 | */
46 | isVersionGreater(version) {
47 | const diff = this._cmpVersions(this.getVersion(), version);
48 | return (diff > 0);
49 | }
50 |
51 | /**
52 | *
53 | * @param version
54 | * @returns {boolean}
55 | */
56 | isVersionGreaterEqual(version) {
57 | const diff = this._cmpVersions(this.getVersion(), version);
58 | return (diff >= 0);
59 | }
60 |
61 | /**
62 | *
63 | * @param a
64 | * @param b
65 | * @returns {number}
66 | */
67 | _cmpVersions(a, b) {
68 |
69 | a = a.toString();
70 | b = b.toString();
71 |
72 | var i, diff;
73 | var regExStrip0 = /(\.0+)+$/;
74 | var segmentsA = a.replace(regExStrip0, '').split('.');
75 | var segmentsB = b.replace(regExStrip0, '').split('.');
76 | var l = Math.min(segmentsA.length, segmentsB.length);
77 |
78 | for (i = 0; i < l; i++) {
79 | diff = parseInt(segmentsA[i], 10) - parseInt(segmentsB[i], 10);
80 | if (diff) {
81 | return diff;
82 | }
83 | }
84 | return segmentsA.length - segmentsB.length;
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/tests/Cypress/makefile:
--------------------------------------------------------------------------------
1 | .PHONY: help
2 | .DEFAULT_GOAL := help
3 |
4 |
5 | help:
6 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
7 |
8 | # ---------------------------------------------------------------------------------------------
9 |
10 | install: ## Installs all dependencies
11 | npm install cypress --save-dev --save .
12 | npm install webpack@5.88.2 --save-dev --save .
13 | npm install @cypress/webpack-preprocessor --save-dev --save .
14 | npm install @cucumber/tag-expressions --save-dev --save .
15 | npm install axios --save-dev --save .
16 |
17 | clean: ## Clean all dependencies
18 | rm -rf node_modules
19 | rm -rf package.json
20 | rm -rf package-lock.json
21 |
22 | # ---------------------------------------------------------------------------------------------
23 |
24 | open-ui: ## Opens Cypress UI
25 | ifndef url
26 | $(warning Please provide the URL argument to Start Cypress!)
27 | @exit 1
28 | endif
29 | ifndef shopware
30 | CYPRESS_BASE_URL=$(url) CYPRESS_SHOPWARE=6.6.4.0 ./node_modules/.bin/cypress open --env conf=dev
31 | else
32 | CYPRESS_BASE_URL=$(url) CYPRESS_SHOPWARE=$(shopware) ./node_modules/.bin/cypress open --env conf=dev
33 | endif
34 |
35 | # ---------------------------------------------------------------------------------------------
36 |
37 | run: ## Runs all E2E tests for Shopware
38 | ifndef url
39 | $(warning Please provide the URL argument to Start Cypress!)
40 | @exit 1
41 | endif
42 | ifndef shopware
43 | $(warning Please provide the Shopware Version as argument to Start Cypress!)
44 | @exit 1
45 | endif
46 | CYPRESS_BASE_URL=$(url) CYPRESS_SHOPWARE=$(shopware) ./node_modules/.bin/cypress run --env conf=dev --headless
47 |
--------------------------------------------------------------------------------
/tests/Cypress/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "@shopware-ag/e2e-testsuite-platform": "^8.0.0",
4 | "uuid": "3.3.3"
5 | },
6 | "devDependencies": {
7 | "@cucumber/tag-expressions": "^4.1.0",
8 | "@cypress/webpack-preprocessor": "^5.17.1",
9 | "axios": "^0.27.2",
10 | "cypress": "^9.7.0",
11 | "webpack": "^5.88.2"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/PHPUnit/Content/Blog/Events/BlogMainFilterEventTest.php:
--------------------------------------------------------------------------------
1 | createMock(Request::class);
23 | $fakeSalesChannelContext = $this->getMockBuilder(SalesChannelContext::class)->disableOriginalConstructor()->getMock();
24 |
25 | $criteria = new Criteria();
26 | $event = new BlogMainFilterEvent(
27 | $request,
28 | $criteria,
29 | $fakeSalesChannelContext
30 | );
31 |
32 | static::assertEquals($criteria, $event->getCriteria());
33 | static::assertEquals($fakeSalesChannelContext, $event->getSalesChannelContext());
34 | static::assertEquals($fakeSalesChannelContext->getContext(), $event->getContext());
35 | static::assertInstanceOf(Criteria::class, $event->getCriteria());
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tests/PHPUnit/Page/Blog/BlogPageCriteriaEventTest.php:
--------------------------------------------------------------------------------
1 | getMockBuilder(SalesChannelContext::class)->disableOriginalConstructor()->getMock();
23 |
24 | $criteria = new Criteria();
25 | $event = new BlogPageCriteriaEvent(
26 | $articleId,
27 | $criteria,
28 | $fakeSalesChannelContext
29 | );
30 |
31 | static::assertEquals($criteria, $event->getCriteria());
32 | static::assertEquals($fakeSalesChannelContext, $event->getSalesChannelContext());
33 | static::assertEquals($fakeSalesChannelContext->getContext(), $event->getContext());
34 | static::assertInstanceOf(Criteria::class, $event->getCriteria());
35 | static::assertSame($articleId, $event->getArticleId());
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tests/PHPUnit/Page/Blog/BlogPageLoadedEventTest.php:
--------------------------------------------------------------------------------
1 | getMockBuilder(SalesChannelContext::class)->disableOriginalConstructor()->getMock();
22 |
23 | $page = $this->createMock(BlogPage::class);
24 |
25 | $event = new BlogPageLoadedEvent(
26 | $page,
27 | $fakeSalesChannelContext,
28 | new Request()
29 | );
30 |
31 | static::assertEquals($page, $event->getPage());
32 | static::assertEquals($fakeSalesChannelContext, $event->getSalesChannelContext());
33 | static::assertInstanceOf(BlogPage::class, $event->getPage());
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/PHPUnit/Traits/ContextTrait.php:
--------------------------------------------------------------------------------
1 | getContext($testCase);
20 |
21 | $salesChannel = $testCase->createConfiguredMock(SalesChannelEntity::class, [
22 | 'getId' => '12345678901234567890123456789012',
23 | ]);
24 |
25 | return $testCase->createConfiguredMock(SalesChannelContext::class, [
26 | 'getLanguageId' => '12345678901234567890123456789012',
27 | 'getSalesChannelId' => $salesChannel->getId(),
28 | 'getSalesChannel' => $salesChannel,
29 | 'getContext' => $context,
30 | ]);
31 | }
32 |
33 | /**
34 | * @return MockObject|Context
35 | */
36 | protected function getContext(TestCase $testCase)
37 | {
38 | return $testCase->createMock(Context::class);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------