S
S
Screamy Di2017-05-11 18:38:57
Yii
Screamy Di, 2017-05-11 18:38:57

YII2 How to create a flexible modular architecture?

Hello! I am developing a project in YII2 and I need your help in understanding the architecture of modules and routing.
There is a Yii2-Advanced application. In it, I would like to implement a modular structure so that it would be possible to cut down and expand the functionality (in fact, everyone wants this). You need to make a website with a bunch of pages of the same type and pages on which additional functionality will be placed.
Let's say we have a Pages module that is responsible for working with all pages on the site. It forms a tree of pages and their URLs (depending on the nesting and alias that the admin came up with), and connects templates and content to them. And let's say in the admin panel we create the following page structure:

  • Home (alias: /home)
  • About company (alias: /about)
  • News (alias: /news)
  • Contacts (alias: /contact)

In the database in the Page table we have 4 records
id | alias | name
---------------------------------
1 | /home | Home
2 | / about | About company
3 | /news | News
4 | /contact | Contacts
While there are only 4 pages, you can make separate actions in the SiteController, but let's imagine that we have a lot of pages and this option is not suitable.
We create a PageController and change the router so that it first searches for pages in the database using our alias, and if it finds a page with such a URL, it sends it to PageController::actionPage(), where we get the desired page from the database, define its template, insert content and brought the whole thing to the front. And if not, then it looked for a controller / action depending on the URL-rules and executed its logic.
But on the News page, the news module should work for us, which are stored in a separate news table, because. there may be more than one hundred of them, or this module may not exist at all. And the news module has its own controller, which provides sorting of news by tags, dates, and any other functionality. For example NewsController::actionFindByTag() or NewsController::actionMostPopular().
And here I have a headache with routes. You can add an additional action field to the template table, which is responsible for page templates, and check the URL for it. That is, if the page has a template and its action != null
then we go NOT to PageController::actionPage(), but substitute the value of action and go by it.
Now everything seems to be in order, the user types in the sitename.ru/news address, we look for this page in the database, find its template.action which is equal to news/index and go to NewsController::actionIndex(). And here lies the problem. If the admin changes the alias of the News page, for example, to /events, then at the sitename.ru/events request, he will still get
to NewsController::actionIndex(), which is what we need, but if he clicks on "Show popular" on the news page , which should lead to NewsController::actionMostPopular(), then the only way is to specify the controller and action directly, like news/most-popular. Accordingly, there is an unreasonable change of addresses from /events to /news/most-popular.
Summarizing this huge question. I can’t figure out how to organize modules with their logic, next to ordinary pages without logic, and at the same time, in the admin panel, the Admin could change the alias of the pages, their nesting, and so on. But the functionality of the modules would be preserved.
Thanks in advance!
UPD:
So far, we have agreed that we need to determine if the module belongs to the page and somehow parse the URL in UrlManager::ParseRequest().
I want to express my deep gratitude to Dmitry Eliseev , for his help, he suggested the following URL parsing option:

In parseRequest:
- Looking for /city/events/most-popular. Not found.
- Looking for /city/events. Found. Type "news". We start recursion:
$r = clone $request;
$r->setPathInfo('news/most-popular');
return $manager->parseRequest($r);

I don't know yet if this method will work, but I will try it. I'll post here when I check. If anyone has any ideas I would be very grateful for the help.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
Maxim Fedorov, 2017-05-12
@qonand

In my opinion, you have not quite correctly divided your system into modules: Home, About the company, Contacts - these are ordinary pages of the site there are no questions, but news is not just pages - this is a separate module that can have its own specific functionality - search, tags, likes and etc. Accordingly, I would recommend that you divide this task into two modules:
1. Static content module - which will contain information pages of the site, such as "about the company", "contacts", etc.
2. News module - containing actually all the news

R
RustemS, 2017-05-12
@RustemS

Make the module in it another sub module and you will be
happy In urlManager write 'enableStrictParsing' => true and specify all explicit paths.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question