ashsmith / magento2-blog-module-tutorial Goto Github PK
View Code? Open in Web Editor NEWA tutorial on how create a magento 2 module from scratch, with tests.
Home Page: https://www.ashsmith.io/magento2/module-from-scratch-introduction/
A tutorial on how create a magento 2 module from scratch, with tests.
Home Page: https://www.ashsmith.io/magento2/module-from-scratch-introduction/
Ability to work with multi-store would be great. Select which stores can publish a post.
Backend gives that:
Recoverable Error: Argument 1 passed to Magento\Framework\Exception\LocalizedException::__construct() must be an instance of Magento\Framework\Phrase, string given, called in /var/www/html/magento2/lib/internal/Magento/Framework/View/Element/UiComponent/Config/DomMerger.php on line 327 and defined in /var/www/html/magento2/lib/internal/Magento/Framework/Exception/LocalizedException.php on line 31
Seems like an issue with the ui-component xml
Great tutorial. One of the best.
Is primaryFieldName correct?
When trying to access the grid page, I get the error 'Not registered handle blog_post_listing_data_source'
Things are a little funky in 2.1.x, so it makes sense to follow what Magento_Cms
does, which uses ui components to build up the forms. Makes sense.
In Ashsmith\Blog\Block\PostList on line 24 you use \Ashsmith\Blog\Model\ResourceModel\Post\CollectionFactory - but this class does not seem to exist. Can this be fixed just by renaming \Ashsmith\Blog\Model\ResourceModel\Post\Collection to \Ashsmith\Blog\Model\ResourceModel\Post\CollectionFactory?
Great Tutorial! Thx!
Exception #0 (Zend_Db_Statement_Exception): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'block_id' in 'where clause', query was: SELECT main_table
.* FROM ashsmith_blog_post
AS main_table
WHERE (block_id
IN('9'))
https://www.ashsmith.io/magento2/module-from-scratch-module-part-2-models
On this page. link of "Service Contracts - Data interfaces" is broken
It just sends to main developer doc page.
i suggest replace
with
There's a extra "/" after v2.0
In the file view/adminhtml/ui_component/blog_post_listing.xml the correct path for the xsi:noNamespaceSchemaLocation is that:
xsi:noNamespaceSchemaLocation="../../../../../Magento/Ui/etc/ui_configuration.xsd">
First of all thanks for that great tutorial.
I think you just used the wrong variable in the __construct
and execute
method in the file
magento2-blog-module-tutorial/Controller/View/Index.php
The class variable is named $resultPageFactory
but in the following code you refer to a $resultForwardFactory
variable.
Either the class variable is unused or you used the wrong variable.
files:
Blog/Model/Post.php
Blog/Block/PostList.php
\Magento\Framework\DataObject\IdentityInterface does not exist
replace it with:
\Magento\Framework\Object\IdentityInterface
When I create a backend user who isn't full admin and has some ACL restrictions (not necessarily on this blog module, can be anywhere apparently), then that user cannot view the blog posts listing grid (gets Access Denied).
This is because in class https://github.com/ashsmith/magento2-blog-module-tutorial/blob/master/Controller/Adminhtml/Post/Index.php the const field ADMIN_RESOURCE
doesn't have the effect that you think it does.
In the ancestor (\Magento\Backend\App\AbstractAction
) that field is used in _isAllowed()
to check the ACL, but there it is called with self::ADMIN_RESOURCE
which will always be Magento_Backend::admin
, your child class cannot override that if I understand it correctly (it would be possible if the abstract class used static::ADMIN_RESOURCE
instead.
So you need to delete your constant and instead properly override the _isAllowed()
method like you do in other controllers.
A lot has changed since 2.0 release of Magento, so I want to investigate and document on this ticket everything that should change within the article, or where I can add sections about the differences between versions.
Key changes I already know I need to review:
Refactors to be made:
Additions that could be made:
I'm using the Magento 2.0.0 release and followed your tutorial, thanks for that!
It seems that you must have missed the massactions in your testing? The dropdown on top of the grid in the backend contains nothing.
I changed the section in view/adminhtml/ui_component/blog_post_listing.xml to match the formats that I see in core modules and now the dropdown contains values, but when I try to execute these actions there are exceptions in AbstractMassStatus.php.
Also another question, are you ever going to finish the tutorial part about unit testing?
We should follow best practises set out by Magento by using data models to access our blog posts.
I'm going to implement the following
Ashsmith\Blog\Api\Data\PostInterface
(this already exists)Ashsmith\Blog\Api\PostRepositoryInterface
Ashsmith\Blog\Model\PostRepository
Ashsmith\Blog\Model\Data\Post
Then modify Ashsmith\Blog\Model\Post
so that it no longer uses the interface, and has the method getDataModel
.
PostRepositoryInterface
should define the following methods:
getById($postId)
getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
delete(\Ashsmith\Blog\Api\Data\PostInterface $post)
deleteById($postId)
Any reference to loading the collections, or the original Post model directly will be switched out for the PostRepository.
Hi Ash Smith,
This is not an issue, but I really want to see you will write it as soon.
/**
* Return the desired URL of a post
* eg: /blog/view/index/id/1/
* @todo Move to a PostUrl model, and make use of the
* @todo rewrite system, using url_key to build url.
* @todo desired url: /blog/my-latest-blog-post-title
*
* @return string
*/
Thank you so much.
It's me yet again, I find that editing disabled posts is impossible in the current state with Magento 2.0.0 release.
The shown error says "This post no longer exists."
It's not surprising, since in https://github.com/ashsmith/magento2-blog-module-tutorial/blob/master/Model/ResourceModel/Post.php you override _getLoadSelect(...) so that only enabled posts can be loaded. Not sure what you were thinking there...
Class Gold\Blog\Block\Adminhtml\Post\Grid\Renderer\Action\UrlBuilder does not exist
any chance to fix it?
I am working on create a blog using magento 2. So, i have install your module and go to admin panel it throw below error:
Invalid Document
Element 'add': Duplicate key-sequence ['Ashsmith_Blog::blog_content'] in unique identity-constraint 'uniqueAddItemId'.
Line: 4
Element 'add': Duplicate key-sequence ['Ashsmith_Blog::post'] in unique identity-constraint 'uniqueAddItemId'.
Line: 5
#0 /var/www/html/magento2/vendor/magento/framework/Config/Reader/Filesystem.php(127): Magento\Framework\Config\Reader\Filesystem->_readFiles(Object(Magento\Framework\Config\FileIterator))
#1 /var/www/html/magento2/vendor/magento/module-backend/Model/Menu/Config.php(142): Magento\Framework\Config\Reader\Filesystem->read('adminhtml')
#2 /var/www/html/magento2/vendor/magento/module-backend/Model/Menu/Config.php(109): Magento\Backend\Model\Menu\Config->_initMenu()
#3 /var/www/html/magento2/vendor/magento/module-backend/Model/Url.php(345): Magento\Backend\Model\Menu\Config->getMenu()
#4 /var/www/html/magento2/vendor/magento/module-backend/Model/Url.php(305): Magento\Backend\Model\Url->_getMenu()
#5 /var/www/html/magento2/vendor/magento/module-backend/App/AbstractAction.php(273): Magento\Backend\Model\Url->getStartupPageUrl()
#6 /var/www/html/magento2/var/generation/Magento/Backend/Controller/Adminhtml/Index/Index/Interceptor.php(50): Magento\Backend\App\AbstractAction->_processUrlKeys()
#7 /var/www/html/magento2/vendor/magento/module-backend/App/AbstractAction.php(205): Magento\Backend\Controller\Adminhtml\Index\Index\Interceptor->_processUrlKeys()
#8 [internal function]: Magento\Backend\App\AbstractAction->dispatch(Object(Magento\Framework\App\Request\Http))
#9 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(74): call_user_func_array(Array, Array)
#10 /var/www/html/magento2/vendor/magento/framework/Interception/Chain/Chain.php(70): Magento\Backend\Controller\Adminhtml\Index\Index\Interceptor->___callParent('dispatch', Array)
#11 /var/www/html/magento2/vendor/magento/framework/Interception/Chain/Chain.php(63): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Backend...', 'dispatch', Object(Magento\Backend\Controller\Adminhtml\Index\Index\Interceptor), Array, 'adminAuthentica...')
#12 /var/www/html/magento2/vendor/magento/module-backend/App/Action/Plugin/Authentication.php(143): Magento\Framework\Interception\Chain\Chain->Magento\Framework\Interception\Chain\{closure}(Object(Magento\Framework\App\Request\Http))
#13 [internal function]: Magento\Backend\App\Action\Plugin\Authentication->aroundDispatch(Object(Magento\Backend\Controller\Adminhtml\Index\Index\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#14 /var/www/html/magento2/vendor/magento/framework/Interception/Chain/Chain.php(68): call_user_func_array(Array, Array)
#15 /var/www/html/magento2/vendor/magento/framework/Interception/Chain/Chain.php(63): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Backend...', 'dispatch', Object(Magento\Backend\Controller\Adminhtml\Index\Index\Interceptor), Array, 'designLoader')
#16 /var/www/html/magento2/vendor/magento/framework/App/Action/Plugin/Design.php(39): Magento\Framework\Interception\Chain\Chain->Magento\Framework\Interception\Chain\{closure}(Object(Magento\Framework\App\Request\Http))
#17 [internal function]: Magento\Framework\App\Action\Plugin\Design->aroundDispatch(Object(Magento\Backend\Controller\Adminhtml\Index\Index\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#18 /var/www/html/magento2/vendor/magento/framework/Interception/Chain/Chain.php(68): call_user_func_array(Array, Array)
#19 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(136): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Backend...', 'dispatch', Object(Magento\Backend\Controller\Adminhtml\Index\Index\Interceptor), Array, 'adminMassaction...')
#20 /var/www/html/magento2/vendor/magento/module-backend/App/Action/Plugin/MassactionKey.php(33): Magento\Backend\Controller\Adminhtml\Index\Index\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#21 [internal function]: Magento\Backend\App\Action\Plugin\MassactionKey->aroundDispatch(Object(Magento\Backend\Controller\Adminhtml\Index\Index\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#22 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(141): call_user_func_array(Array, Array)
#23 /var/www/html/magento2/var/generation/Magento/Backend/Controller/Adminhtml/Index/Index/Interceptor.php(39): Magento\Backend\Controller\Adminhtml\Index\Index\Interceptor->___callPlugins('dispatch', Array, Array)
#24 /var/www/html/magento2/vendor/magento/framework/App/FrontController.php(55): Magento\Backend\Controller\Adminhtml\Index\Index\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#25 [internal function]: Magento\Framework\App\FrontController->dispatch(Object(Magento\Framework\App\Request\Http))
#26 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(74): call_user_func_array(Array, Array)
#27 /var/www/html/magento2/vendor/magento/framework/Interception/Chain/Chain.php(70): Magento\Framework\App\FrontController\Interceptor->___callParent('dispatch', Array)
#28 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(136): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Framewo...', 'dispatch', Object(Magento\Framework\App\FrontController\Interceptor), Array, 'install')
#29 /var/www/html/magento2/vendor/magento/framework/Module/Plugin/DbStatusValidator.php(69): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#30 [internal function]: Magento\Framework\Module\Plugin\DbStatusValidator->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#31 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(141): call_user_func_array(Array, Array)
#32 /var/www/html/magento2/var/generation/Magento/Framework/App/FrontController/Interceptor.php(26): Magento\Framework\App\FrontController\Interceptor->___callPlugins('dispatch', Array, Array)
#33 /var/www/html/magento2/vendor/magento/framework/App/Http.php(115): Magento\Framework\App\FrontController\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#34 /var/www/html/magento2/vendor/magento/framework/App/Bootstrap.php(258): Magento\Framework\App\Http->launch()
#35 /var/www/html/magento2/index.php(39): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http))
#36 {main}
If I go to frontend its working its show
If I Comment menu.xml add element Now opening my admin panel Now show created custom menu in content menu. Content-> Blog -> posts. But I comment these two menus in menu.xml.
If click post its nothing to show, came blank page.
Suggest me How to solve this problem.
I don't see a grid collection which is referenced in the di.xml file
or do I misunderstand?
https://github.com/ashsmith/magento2-blog-module-tutorial/blob/master/etc/di.xml#L27
Keep up the great work!
It's me again, I want to say that deleting posts does not work in the current state with Magento 2.0.0 release.
Regardless if I select delete in the action field or on the edit page, I land on a 404 page. The page at /index.php/admin/blog/post/delete/post_id/1/ does not exist.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.