I'm trying to build a simple content management system based on the Zend Framework 2. The problem is that I don't know how should the folders structure be like.
Until now I have to solutions in mind:
A. Building a general "Admin" module that has multiple controllers like Login Controller, Pages Controller, Posts Controller, each of this controller with his own actions.
B. Building an module for each component, like: Pages Module that has an adminController an an frontendController.
I'm sure that none of the above solution is the corect one, but couldn't find any solid solution or books to provide one. I've taken a look at gotCMS but noticed that this one i.e, saves all the data like layout views in the database, and this is not a solution.
Though it's a very first alpha solution, I work on ensemble which is what I'd rather call a content management framework.
Ensemble's admin runs on ZfcAdmin. So you can drop in a Blog module which just has a admin controller under ZfcAdmin's route. But you can also manage pages (like texts) with a navigational page structure. All content parts (text, blog, etc) are separate modules.
So I'd suggest you take a look at the sample application and you can check out our blog as well, which just hooks in into ensemble. I know currently the documentation is scarce, but if we reach kinda beta stability we will focus more on docs.
The main benefits for "your system B" is you can drop in modules when needed. They all provide their own config, controllers, models and views. It's easy to install them from a developers perspective (load in composer, enable in application config) and you can easily override any view with your own ones.
TL;DR: choose structure B and have a look at Ensemble.
/edit: seeing you comment on Sam's answer: yes you have to do that. In ensemble, you specify a route config for the frontend and create your admin routes as child routes of ZfcAdmin. For both the frontend as the backend you have separate controllers.
There is no right or wrong when it comes to building something new. Personally I'd go with B. I wouldn't even name the Controllers like you did (I'd break them down a lot more, like NewsAddController, NewsEditController, NewsDetailsController, etc...). Then I'd have an AdminModule that would simply display a new Layout with a specific "AdminNavigation". This AdminNavigation can be filled via the other Modules (i.e. NewsModule would inject it's own administrative Routes into the AdminNavigation via module.config.php)
Related
or "How to decouple UI from business logic in Delphi?"
Each target platform has its own set of native firemonkey controls (Windows=VCL, MacOS=TMS mCL, Android=D.P.F, iOS=TMS iCL and D.P.F). The new FireUI (multi-device form designer) is a great solution for styled components, but not for native components because it still requires the same component on the master pane to support all platforms. As you cannot mix them on the same form, it completely breaks the whole idea with Delphi.
A lot of developers would say that Delphi is the broken approach, see "Why FireMonkey is so fundamentally wrong in every aspect". However, the premise for this question is NOT to argue against Delphi, but to get the best results out of what it does offer.
The conclusion is then that for each form in your application you have to make a separate form for each target platform. This leads to these questions:
Challenge 1: How to include different form files in your project depending on your target platform?
Solution 1: include all of them, i.e. MainForm_IOS.pas, MainForm_Android.pas, MainForm_Win, MainForm_OSX.pas, and then use compiler directives inside the files, so only the content of one of the files is active. Disadvantage: a large application can have many forms (we have around 40), so we are talking about a large number of included files.
Solution 2: Do not include them in the project, but instead just place them in seperate folders. Then you can add the matching folder to the search path for each target platform. Disadvantage: They will not show up in the Project Manager, so it will slow down the workflow every time you need to find a file.
Solution 3: Create a project for each target platform. Disadvantage: Every time you add new units or change common project settings you have to (remember to) apply it to all projects.
Update: As suggested in the Malcom Groves video, placing all the business logic in a package will remove the disadvantage from Solution 3. So I consider solution 3 as the best approach.
Challenge 2: How to connect the different device forms to the (same) business logic?
Possible solution: Create a "Helper" class that contains all the code you would normally have in the form unit.
Update: This "Helper class" is actually what the MVVM calls a ViewModel. What I need seem to be a MVVM framework that can support the databinding. I have made another question about that.
Any input and suggestions about best practice are welcome.
For challenge 1:
You can conditionally link in your FireMonkey form resources depending on the compile target:
{$R *.Windows.fmx MSWINDOWS}
{$R *.Macintosh.fmx _MACOS}
etc.
This is excatly what the XE7 Multiview designer does, but I see nothing against using this mechanism to link whole form files conditionally in to your executable. Of course you might also want to ifdef the corresponding units in your project file.
For challenge 2: Just use some form of Model View Controler logic. So your platform dependant forms will talk to a platform independant controler.
I am a sort-of newbie with MVC and Zend in particular. I have taken over a project from another team, site is built in Zend framework. There is an admin dashboard to add content, assets like images and media, a blog and a portal into Zen Cart for the store.
What is the easiest method of adding a new web page that has as its contents several things that are dynamic - items for sale, music to listen to, blog entries, news items from the database and a featured artist. All of this is stored in the MySQL db. I just do not know enough about MVC to make it work correctly.
I can create a page in the admin dashboard and use as the URL another "module" that already exists, but if I attempt to copy a module folder (for instance the folder called musiclive is almost exactly what I need except I need to add another column of elements...) the admin dashboard does not render. I know that I need to create some sort of "view" and fiddle with or create a controller, but not sure of the easiest method of doing this. I probably have to tell the admin dashboard I have added another "module" but it really is just the main or home page of the site - the other guys never built it because it was rich with details and I guess they put it off. I also probably have to change the files inside the module folder to reflect a different page.
Would love some help or pointers. Ask if you need more details on what the heck I am describing here...
Create a new controller in that same module instead of copying the whole module if the module is so similar to your requirements. And then extend already built resources like forms, models. I strongly recommend you to read about zend framework documentation, especially skeleton application tutorial. That will increase your knowledge as well as make you understand MVC and your current project.
http://framework.zend.com/learn/
One more thing there are 2 versions of zend framework and both are entirely different. You need to know the version in which the project is built. Zend framework 2 has following generic directory structure:
config/
autoload/
application.config.php
module
Application/
config/
src/
view
Module.php
SomeOtherModule/
...
public/
vendor/
We are developing a CMS. This will have a template system, so for example, if the admin wants to add a news section, then he will have to create a template for that section, and another one for each news, that is, for instance, /news/:int:/:title:/, but that route will be stored at the database... how can I do it?
You could use a common controller as a fallback route so that it catches all routes that the admin might create. This controller then goes on to read the appropriate template and show the data.
I want to create an admin bundle, that somehow detects other bundles and tries to add them to the menu and to the same RBAC context.
Eg:
AdminBundle defines a route /admin/dashboard, that requires authentication and authorization. There you can see 3 items in the menu, eg: dashboard, config (some config stored in the db), and users (CRUD for users, found in the UserBundle)
Then someone adds a ProductBundle, which deals with CRUD for e-commerce products or something. Somehow, without modifying any code in AdminBundle, we have now a new item 'products', available in the menu in /admin/dashboard
Later on, the products CRUD is no longer needed, so we just delete the ProductBundle, and it automagically disappears from the admin dashboard menu.
How would you go about implementing something like this? Is there any native support for a plugin-like design like this in symfony 2?
I don't know about a full plugin solution but my approach would be:
There is one "master backend" call it MasterAdminBundle for the sake of conversation. This bundle contains a base.html.twig which just helps define the navigation bar of the Administration area and a {% block content %}. It also has some kind of MenuService which displays the menu. I'd have my other bundles register with this service an AdminMenu subclass by way of using the Tag System just as a Voter can register with the Security Context (see here).
In the base.html.twig I'd then likely use an Embedded Controller to render the menu.
Now with this sort of framework in place your other bundles can stay encapsulated by keeping their own admin routes and interfaces:
ProductController would now also have ProductAdminController where you can use a route prefix #Route("/admin") on the class definition. Any routes could then render templates from within the bundle since templates are held under the controller name. Acme\ProductBundle\Resources\views\ProductAdmin\edit_products.html.twig as long as they extend the base.html.twig from MasterAdminBundle and put their content into the content block.
For other things like a dashboard that you wanted to plug other bundles into I'd likely just keep going the same way, create a service in the MasterAdminBundle and use tags to load other classes into it with the data required.
Hope that makes sense, maybe others will have a better solution to this, I'm interested to hear also since this is something I'm trying to tackle at the moment also.
I have a website that has related pages. They have links that point back and forth to one another but I have no integrated system, nor do I know what that would mean.
What is the minimum code that a group of web pages must have to be considered a Content Management System (CMS). Is it that all the settings are in the database and the pages are generated somehow? Is there some small snippet that all my pages could share that makes them a CMS, database or not?
Thanks. I was also hoping not to have to study a giant CMS to see what makes it a CMS . After maybe a basic understanding I would know what I was looking for.
edit: here's why I ask about code. Whenever I have looked at a CMS, and maybe they aren't all the same, I saw that to develop a module you always had to inherit from certain classes and had some necessary code. I didn't know if there was some magic model that I just don't get that all cms makers understand.
edit: perhaps my question is more about being extendable or pluggable. What would a minimum look like? Is it possible to show that here?
edit: how about this? Is something a CMS if it is not extendable and/or pluggable?
I think this is really impossible to say. We all manage content. The "system" is just whatever mechanism you use to do so(dragging and dropping in Explorer or committing content changes via a SQL query). To say there is a minimum amount of code needed really isn't indicative. What is indicative is how often you find yourself making mistakes and how easy it is for a given user of a given skill level and knowledge to execute the functions in the designed system. That tells you the quality/degree of what you have in place being worthy of being called a "CMS."
Simply put a CMS is an application that allows the user to publish and edit existing web content.
In response to the edit:
A "good" CMS allows of extensibility. By using inheritence you can extend the functionality of a CMS outside of the core components provided. That's the magic.
About Extensibility:
Depending on the language/framework you want to build your CMS with, you can load pages or controls(ASP.NET) using command built into the framework. Typically what is being done is a parent class/interface is being defined that forces an module that is to be developed to follow some given standards:
Public MustInherit Class CMSModule
'Here you will define properties and functions that need to be global to all modules being developed to extend your CMS.
public property ModuleName as string
End Class
public class PlugInFooCMSPage
inherits CMSModule
end class
Then it's just a matter of simply loading a module dynamically in whatever construct a given language/framework provides.
Ultimately, a CMS is a system that lets you manage content, so it needs an user interface that is dedicated to letting you easily create, edit and delete pages on your website.
However, it's fairly usual to expect from a CMS to provide a browser-based WYSIWYG page editor, file uploading, image resizing, url rewriting, page categories and tags, user accounts (editor, moderator, administrator), and some kind of templae system.
Without dragging you into a theoretical explanation of what a CMS is and what it's not, perhaps some tutorials on the building methodology of a CMS will help you better understand.
http://css-tricks.com/php-for-beginners-building-your-first-simple-cms/
http://www.intranetjournal.com/php-cms/
A Content Management System is a System that Manages Content. :)
So if you got many pages that share the same layout, you can create a system that stores the content into a database and when a page is requested, it gets that content, merges it with a template that contains the page header, menu, etc.. and outputs the result.
The basis idea is that you don't want to copy HTML pages, and have to edit hundreds of them when you want to change your layout.
Such a system can be very complex, featuring wysiwyg editors, toolbars, version control, multiple user publishing and much more, but it could be as simple as a single page behind a standard loging, that contains only an input field for the title and a textarea in which you type the html content.