Why does magento use xml files for themeing? [closed] - php

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I am new to Magento and studying its documentation. Excuse me if I sound a bit to much against it but I am open minded. I don't understand why Magento uses XML for theming. What's the reason behind it?
I am running the newest version 1.6 from the SVN repo and following this site.
I read that I need to create local.xml declaring what gets in and out of the theme. After I did the basic structure then added my theme directory through the backend. I removed a elements on the front end using a few xml elements
Example:
<remove name="right.poll"/>
<remove name="right.permanent.callout"/>
<remove name="left.permanent.callout"/>
<remove name="paypal.partner.right.logo"/>
The homepage doesn't change... why is this? Is there another location that would need modification? I found out that i needed to disable all caching for dev only.
(for those that dont know its (admin page) -> system -> cache management -> select all and disable)
I also don't understand why the CSS/JS/media directory is completely separate from the template directory. It makes no sense why they would do this. Another thing I don't understand is why there are a million directories (sarcasm) that I need to get into to make a modification. I assume they are using some kind of MVC model but it is by far nothing I have ever seen. If they are attempting to make pretty URLs with all these directories I'm pretty sure they have heard of htaccess. (again excuse me if I sound ignorant but I am new).
PS., I looked into the phtml files and most of them look like their just calling these XML elements, is it possible to use plain old HTML and PHP to create a theme? Or am I forced to use their XML methods?
edit: the theme folder at app/design/frontend has two folders base and default which im thinking each of these are interfaces for example a group of themes i would like to use. i modified the design_change db table from default/default to base/default (also done on the admin page but i like the db better). i saw that a different page was rendered. so i figured i can just take out the base folder because its extra confusion. when i did that the site broke. so it looks like magento has tied two theme directories into this application. its as if they are just as confused as we are. am i right?
Please let me know your input.
Thanks.
ps: i found out magento is from the zend framework.

Your answers, in turn:
"I don't understand why Magento uses XML for theming."
In many MVC systems, determining what content and data are available in the view means dealing with (creating & customizing) controller actions. Layout XML gives even frontend developers the ability to add and remove view elements and their data ("Blocks" in Magento) to different routes without having to rewrite action controller classes.
"I read that I need to create local.xml declaring what gets in and out of the theme."
Not necessarily. If you have no customizations of layout XML, you won't need a local.xml file. Moreover, if you have layout XML customizations for ONLY the homepage, you can add your layout update XML to the page data via the CMS admin.
"[W]hy [is] the CSS/JS/media directory is completely separate from the template directory[?]"
This is simply a security feature. All files under ./skin can be directly accessed via the browser, and all files under ./app cannot be accessed via the browser, including theme-related files under ./app/design. Is this a logical, developer-friendly strategy? Not at all, and Magento is addressing this in Magento 2, which is available on github.
"[Why are there] a million directories (sarcasm) that I need to get into to make a modification[?] I assume they are using some kind of MVC model but it is by far nothing I have ever seen."
Magento is indeed an MVC framework, and a robust one at that. It is, as you've noticed, quite distinct, especially in the PHP frameworks realm.
Models are PHP classes under app/code/[codePool]/Namespace/ModuleName/. By convention, they are under the Model directory. They come in three general flavors: data models, which conventionally reside directly under the Model/ directory, and resource models & resource collections which conventionally reside under Model/Resource as of Magento 1.6.
Views are PHP classes which conventionally reside under app/code/[codePool]/Namespace/ModuleName/Block/. They may or may not be rendered along with template files (.phtml). Unlike many MVC frameworks, Views in Magento often load their own data independent of route / action.
Controllers are PHP classes which are found under app/code/[codePool]/Namespace/ModuleName/controllers/`.
"If they are attempting to make pretty URLs with all these directories I'm pretty sure they have heard of htaccess."
Not at all. The only thing which connects URLs to action controllers is configuration (this is true of all MVC classes outside of the Mage namespace). SEF URLs are achievable via configuration in multiple ways as well as via database rewrites which may be found in core_url_rewrite table. Magento does use an .htaccess file only as a means of routing appropriate requests to the system entry point, index.php.
"I looked into the phtml files and most of them look like their just calling these XML elements, is it possible to use plain old HTML and PHP to create a theme? Or am I forced to use their XML methods?"
Templates are dumb. They are pointless without the View class in which they are rendered - literally included()ed. The methods and data available to them come from their (often) layout-configured View class. For an example of view configuration, see app/design/frontend/base/default/layout/cms.xml: the <block type="core/template" name="page_content_heading" template="cms/content_heading.phtml"/> line declares an instance of Mage_Core_Block_Template with the cms/content_heading.phtml template from the frontend theme.
"[T]he theme folder at app/design/frontend has two folders base and default which im thinking each of these are interfaces for example a group of themes i would like to use. i modified the design_change db"
It's good that you are investigating these things; an explorer's approach will be helpful as you learn the framework. Themes in Magento are defined by three components: an area (frontend or adminhtml), a package name, and an actual theme name. In the filesystem, these settings map out to two places, as you've noticed. They are ./app/design/AREA/PACKAGE/THEME/ and ./skin/AREA/PACKAGE/THEME/. There are two more aspects to theming in Magento: theme asset type and fallback.
There are four theme asset types: layout, template, translation, and skin. The path that the system uses to find a given theme asset is based on configuration as well as some hardcoded paths. The absolute fallback point for theme assets is the base package's default theme. Appropriate Magento configuration has you first declaring a package (e.g. 'my_package' under System > Configuration > Design. With no theme settings declared, the system will simply look for assets under the default theme; this would map to app/design/frontend/my_package/default/template/. If you were to declare a "Templates" theme in Design configuration (e.g. "my_templates", the system would first look there and then look under the default theme. There is also a "Default" configuration setting which, if set, will be used for all theme asset types (e.g. "my_default"). This is all happening in Mage_Core_Model_Design_Package and it looks like the following; we'll use our example settings and the "cms/content_heading.phtml" param from above:
app/design/frontend/my_package/my_templates/template/cms/content_heading.phtml (if found, use this one, don't look anywhere else)
app/design/frontend/my_package/my_default/template/cms/content_heading.phtml (if found, use this one, don't look anywhere else)
app/design/frontend/my_package/default/template/cms/content_heading.phtml (if found, use this one, don't look anywhere else)
app/design/frontend/base/default/template/cms/content_heading.phtml (if not found here, someone screwed up, and an exception will be logged to the system log at ./var/log/system.log)
This design fallback is used for two reasons: allows failsafe places for developers to store theme assets (base/default) and allows for multistore reuse and DRY overriding of theme assets.
That said, this is not an ideal architecture, and as mentioned, this is going away in Magento 2 - all theme assets will be stored inside their respective module's directory.

Only reading will be able to help you much here. Once you get the hang of it, the xml layouts are pretty handy, it's just a pain learning how they work.
You can indeed ignore a lot of the xml stuff if and just put stuff inside the template files, but as you will read from other sources, it's not always best practice to work this way (though I'm sure every Magento developer does it on occasion).
Your best reference is often the Magento code itself. So long as you never touch anything inside base/default, you will always have a reference of how it's "supposed" to work.
Magento is definitely a Swiss Army Tool. You can get things done in many ways, each of which has it's pros and cons. Sometimes hardcoding stuff into templates/layouts is the way to go... sometimes you need to use static blocks and CMS (if a client wants to be able to edit something, for example).
Again, keep at it.. it is certainly frustrating to learn, but you will eventually pick up on the nuances and will start to feel more comfortable.

Related

New to Zend Framework 2. How to structure modules correctly?

I'm new to MVC and ZF2.
I carried out their tutorial successfully to build a basic app. (http://framework.zend.com/manual/2.1/en/user-guide/overview.html). In that tutorial they create a module called 'Album' to add/edit/delete music albums.
What I want to do is create an application that will have various functions, such as user account administration, system config, etc. I'm aware via reading other posts that you don't need to create a new module for each function, rather grouping them under one using entities.
With that in mind I set out creating my first module 'User' using this structure but I'm not sure if I'm doing it right. Structure I have at the moment is:
/module
/Application
/config
/language
/view
/src
/Application
/Controller
/UserController.php
/Entity
/User.php
/UserTable.php
/view
/user
/user
/index
If you want a look at the code check out the repo at https://bitbucket.org/newvisionjames/zf2-test/overview
Specific questions I have are:
1) I have two 'view' directories at the moment, pretty sure that's wrong..which one is correct, if either?
2) In the ZF2 tutorial they create two php files under /model called Album.php and AlbumTable.php. I have reflected this is my /Entity folder. Is this direct transfer correct? Does having an /Entity directory render the /model not necessary?
Overall what I'm trying to do is get set up with this framework so that it's working and I'll be able to learn from there but right now I'm stuck! Any helpful answers or pointers to useful resources will be much appreciated.
Thanks.
ZF2 follows PSR-0 standard which also improves the ability for other framework modules to interact with ZF2. To learn more about PSR-0 standard, take a look here: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
With your example above mentioning user, you most likely would keep user in it's own module due to the nature of "user". Does the user just contain a class to represent the user or does it include hooks for authorization and authentication etc? Also how is the routes handled? Although user may seem simple at first glance it's usually something that is placed in it's own module.
And that is so you can re-use / share your module with others. Generally whenever I build an app it would be moved into multiple modules depending on where the functionality fits. Then between modules if I need access to another module I will make use of the service locator to access those methods.
For instance under the application module I may want to reference the user's first name, i can call the user module service to then show me the user's details. This simplifies your code a lot.
To answer your questions directly though:
I have two 'view' directories at the moment, pretty sure that's wrong..which one is correct, if either?
Answer:
Based on your posted directory structure only the top level "view" directory looks correct in a "ZFSekeleton" representation.
In the ZF2 tutorial they create two php files under /model called Album.php and AlbumTable.php. I have reflected this is my /Entity folder. Is this direct transfer correct? Does having an /Entity directory render the /model not necessary?
Answer:
Technically you can put your business logic anywhere as long as it follows namespace / psr-0 standards. Beyond that there is no real requirements, although what is important to you use a coder is that you improve readability of your code or you won't get anywhere fast.
I normally like to seperate my src folders like so:
Controllers
Models
Adapters
Services
Entities
Where controllers is obviously the controllers for zf2. Models contains some business logic for controllers or classes. Adapters are authentication adapters, database adapters etc. Services are the service locator classes for other modules and the current module to work from. Entities are my data representations.
To each their own but that just makes sense to me. Hope that helps.
Well-written and nicely formatted question. Don't see that too often.
The higher-level one is right. The one that's at the same level as src. Everything under src will be class files. So they follow the PSR-0 standard, each file contains excatly one class, etc. So you don't want any views there.
Seems pretty good to be, but sice I use Doctrine instead of ZF2's ORM, I can't tell for sure. What I can tell you is that you don't need a model directory and that will probably put all of your entities inside Module\Entity. So that's absolutely right.
Overall I'd tell you this: Stick with the config, src, view folders. That's what ZF2 likes and this is what every other ZF2 developer will expect from a ZF2 module. Don't get too hung up on conventions inside your src folder though. You can pretty much put your stuff whereever you want in there. If you've got a decent IDE (like PhpStorm), it only takes a couple of seconds to move or rename classes later. Just go through some ZF2 modules on GitHub and try to match what groupings or hierarchies you see most often.
And here are some words about the separation of modules: I'd say it's a good practice to try and break your project up into modules as much as possible, as long as you think they could live separately. For example: You have an online shop with a bunch of products and a search function. Now ask yourself the following question: "Do the products need the search function?" No. The products can live without it. So you put the search functionality in its own ProductSearch module. Can blog posts live without their comments? Yes. Create a Blog and a BlogComment module.
The whole project structure is something I was thinking a lot about when I started out with ZF2. So if you have any more questions, just comment and I'll try to update my answer.
You should definitely read this post: http://akrabat.com/zend-framework-2/thoughts-on-module-directory-structure/

The MVC approach to OO-PHP and WordPress plugins

I'm starting to look at Object Oriented PHP. To date I've developed a large number of PHP systems with a procedural approach, but I think it's time to move forward.
One of the projects I'm working on at the moment is a Grade and Handicap Calculation plugin for WordPress. In short, the plugin takes table tennis players' results from uploaded CSV files and works out their grading for handicap tournaments.
I'm using WordPress because my table tennis club's website uses WP and if it works for them I can potentially give it to other clubs/leagues and they too will be able to install the plugin and have access to a fully-fledged grade and handicap system.
Outside of WordPress, I'm reasonably confident that I could develop such a system in OO-PHP using the MVC pattern. It would probably look something like this:
Controller
Create an instance of the Model
Deal with "navigation", i.e. GET/POST requests, and work out which page templates to display accordingly
Model
Deal with uploading and storage of files
Update and select information from database
Host mechanism for working out players' grades
View
Admin pages, i.e. settings and uploading files
Grades page, displaying players' grades and handicaps
Results page, where specific users can see individual players' results (mostly for debugging purposes)
Please correct me if I'm wrong, as I've only learnt this pattern in the past 30 minutes or so, but by my logic that is a true MVC approach to creating this system.
However, once I bring WordPress plugins into the equation, I'm starting to struggle with the following questions:
In the non-WP system, CSS styles would simply be included in the View's PHP pages which I'd then include in the Controller. However, in WordPress, it doesn't work like that - I can't use CSS styles in that way, they have to be enqueue'd. Where would I host the function for enqueueing my CSS files?
When someone first activates the plugin, it will need to create the appropriate database table using WordPress functions to do so. This would then have to be run off a hook, i.e. a register_activation_hook. Where would I host these functions? It would seem sensible to put them in the Controller but at the same time I'd imagine that maybe the Controller needs to be kept as clean and simple to read as possible.
Similar to the above question, I also need to create WordPress admin pages using add_menu_page and add_submenu_page commands. Where do I host these functions?
All of these questions probably have the same answer, and I know it's just semantics, but I'm keen to try and get this right early on so I can truly get my head round the MVC pattern of Object Oriented PHP.
Thanks in advance,
If you are looking for a better place for learning MVC, this would be it.
Hope I'm getting this right.
Can't tell you about CSS, as I just keep those defined in my layout files (view).
Heavy logic can be put into services (external Class), and then being ran in controller. You'll keep your controller 'thin'
Similar to previous one. You can have your menu stored as a model (which doesn't have to be strictly DB related, but also XML/JSON/array data), and then call your add/remove actions in controller.

How to avoid bloat in Zend_Navigation?

I've been researching using Zend_Navigation in combination with Zend_Acl to manage navigation and access permissions in a new app I'm working on.
One thing that really bothers me, is the examples I have seen end up making an enormous XML file that contains every possible nav item in the application. Loading this file on every request seems like major performance bottleneck and there has to be a better way. I realize I could alleviate much of that with the use of memcached or another caching mechanism, but I feel like the application itself should be written in the most optimal way and, only then, do you add caching. It doesn't make sense to make something slow and bloated and rely on caching to clean up my dirty work.
I'm using a modular setup in this ZF app, so each module has a unique bootstrap. I've considered creating module specific nav XML files and loading the specific one, but I'm not sure if that's the best way either.
What is the suggested method of using Zend_Navigation in large application with potentially hundreds of navigation paths?
I wouldn't call this the suggested method it's just how I work with it when I basically had the same question two years ago. In a nutshell: I have all the paths in the XML I need on each and every single page. All other paths are added at run time. Only then I add the ACL.
First, be aware that ACL in Zend_Navigation only manages the presentation of the navigation. It doesn't provide or better guarantee access control to your application. A certain link will be missing in the menu but if the user knows the correct path s/he may access the resource nevertheless. Of course, you can use the ACL information in the navigation object to bolt down your application but I believe there are smarter ways mainly to incorporate ACL directly into controllers and models.
Second and to your main question, my navigation's XML file only contains the most basic structure up to the second level which is the menu I always need. It's also more or less what I have controllers and actions for. Any paths resulting from params are added at run time. Because of that I don't even include the ACL into the XML but inject it at run time. Simply because only then do I have the full extended current branch with all its paths.
I've not used XML to generate navigation. It is possible to add your pages at run-time in php using array notation.
Using modules, you could set up the navigation object in the registry, in each module have a model that adds its pages, and a plugin that calls each modules' navigation model at preDispatch.

What to keep in mind when making Wordpress themes

I have been making Wordpress themes for a year or two and keep running into things I need to keep in mind when trying to make my themes as compatible and flexible as possible with their settings, plugins, etc.
Is there a resource that keeps a checklist of all the "don't forgets" of Wordpress theming? What things do you try to keep in mind when building your Wordpress themes?
Examples:
Checking if the author/admin has disabled comments for a particular post.
Remembering to call wp_head() at the end of the <head> tag.
Remembering to call wp_footer() at the end of the <body> tag.
Using bloginfo() variables instead of setting static values for charset, html type, description, etc. so admins can modify such things in the site settings.
Using function_exists() before calling a function from a plugin so it fails gracefully if that plugin isn't installed.
Wordpress documentation has an interesting topic addressing exactly what you're asking: it's called Designing Themes For Public Release. There's also Theme Development General Guidelines. The Templates article is wonderful too.
I don't know other official resources, but it would be interesting to add more info into those three guides. I'm interested in some other answers we may have in your question to complement them.
I'm so used to Wordpress that the examples you wrote just flows automatically when I'm developing, since using a function that outputs domain information such asbloginfo() instead of static values is a good practice in any web development.
A theme development checklist depends more on the intended audience for your theme. If it's beyond the basic blog and moving towards WordPress-as-CMS territory, you'd want to look into:
custom widgets and dynamic sidebars to make features more portable and flexible
support for custom fields, or plugins like MagicFields that implement the former in a whole new way
routing and creating custom templates for different levels of the site (ex: sub-categories get handled by category-x.php)
using a css framework so whoever gets to modify the styles has a higher chance of understanding it better; make sure to include ie support
custom wp-admin section with its own menus, pages, etc.; this is especially necessary if your theme has custom functionality that can be further customized by the user
use the wp_scripts and wp_styles classes and functions to add styles and scripts; this is especially important for javascript, as it prevents duplicate includes and works with dependency scripts (loads jQuery before your jQ script)
make sure the design of the theme doesn't look boring like everything else out there for WordPress
write a theme class; unless you're planning to support PHP4, use PHP5 classes and objects to make your life easier, in terms of feature inheritance and no naming conflicts. look at CodeIgniter and their singleton pattern; it makes custom globals inside template files a lot easier to manage
if you are (and you should be) making your theme a lot more advanced and more like a plugin, then know how to use the WP_Cache and WP_Rewrite objects so your custom queries with $wpdb (yes, you'll need to do these once in a while to get certain custom functionality) are less expensive, and your new pages (if you're rewriting urls) route correctly and your links are correctly dynamically generated, respectively.
last and most importantly, try your hardest to separate presentation (html) from logic (php); this gets hard as you start running custom WP loops and a good solution is the aforementioned theme class.
Our firm also develops a lot of various WordPress & WordPress MU themes & we haven't found any "Official" resources, but one thing we've done is create a basic set of template files can can be used as a "standard" setup in order to speed up our development process.
Then, whenever a new theme needs to be developed, we basically copy / paste this default set of template files into a new theme folder on the WordPress install. For us, items we've included in this default setup are pre-populated header.php, footer.php, index.php, home.php, single.php, functions.php, comments.php, /images (dir), /functions (dir), style.css, /css (dir), /scripts (dir), and a handfull of other items.
Then we've also used Yahoo Grids or Google Blueprint css frames works to also speed up the css work. There's a few other items / files I'm leaving out, but should give you a general idea of what works best for us in our shop.

For doing CRUD using php, without using any frameworks, cakePHP, Smarty, what's the best way to organize php code into files?

Let's say I have a database table "widgets"
Should there be an index.php with a big switch statement for different actions, like "list_widgets", "edit_widget", "new_widget", "delete_widget"... and then each of those actions in a separate file?
Or, should there be list_widgets.php, edit_widget.php, delete_widget.php....
Or some other way?
EDIT (after reading the first answer). I'm really asking, what are the names of the files on my harddrive. If I were to create a website that just edited a single table of Widgets, what would be the names of the files on my harddrive for that project?
(My motive for avoiding frameworks right now is that this project is a learning excercise for php and mysql, so I don't want anything happening automagically yet)
If this is a learning exercise with PHP, then what exactly are your goals? Do you want to implement a full MVC architecture (just for the sake of the exercise)? Do you want to use a Front Controller that routes requests to specific controllers? Or do you want to build a simple one script site that is capable of only of editing your table of widgets?
If it is any of the former then I would recommend that you read the documentation and source code for one of the frameworks (I particularly like Zend Framework) and then implement your own version of MVC and/or Front Controller. Additionally, you can read this article by Rasmus Lerdorf where Rasmus talks about how to build a simple MVC application without using an existing framework.
If you simply want to accomplish the latter (edit your table of widgets), I would recommend that you keep things simple. So I would:
Create a file (WidgetsTable.php) with functions that interact directly with the table. For example insert(), update(), delete(), fetchAll(), createNew()
Create a file (index.php or widgets.php) that you will interact with directly (in some paradigms this would be the Page Controller). This file will contain functions like createAction(), listAction(), findAction(), showFormAction(). This will be the page to which calls are made and the functions in this page will interact with the functions (or class methods) that you created in the first file.
Create a folder called views or templates and create a corresponding view or template file for each action in widgets.php. For example you would create list.php, showForm.php, create.php.
This will ensure that you have the proper separation of concerns and it will make it easier to adjust the overall project structure later if you find you need to.
Good luck with your learning project! :-)
I'd create a Widget class and give it edit(), new(), and delete() methods. Then you could have a list() function somewhere that builds an array of Widget instances. I'd probably go ahead and create a WidgetList class (WidgetList.php), even if it's just a wrapper around an array initially.
Initially, I'd just have a Widget.php file for the class and an index.php to handle the various requests.
I always make sure the files containing my classes have the same name as the classes themselves (usually one per file). That makes it easier to figure out where things are and makes it easier to use the __autoload function.
Then I'd have a .htaccess file to create friendly urls that send the different types of requests to index.php. Something roughly like this:
Options ExecCGI FollowSymLinks Includes MultiViews
RewriteEngine On
RewriteRule /new index.php?action=new
RewriteRule /edit/([0-9]+) index.php?action=edit&widget_id=$1
How you do the urls depends on a little on how your widgets are actually going to work.
It would probably be easier to view the file structure if it was /widget/edit.php or /widget/new.php
This way you can redirect people to other modules by just knowing the module name and what action they want to do.
Also that will allow you to implement url rewriting a little easier so it would look like widget/edit/2 once you get an index.php and some rewrite rules in place.
I'm sure that this is probably a matter of taste, but I find that creating 3 files (list, add, edit) for 1 table is flexible enough while keeping it easy to understand, especially for developers new at php.
that way, whenever you need to do CRUD on another table, just create another 3 files for it.
...
includes/
views/
add_member.php
edit_member.php
list_member.php
add_widget.php
edit_widget.php
list_widget.php
...
with includes/ folder storing the config and function files and the views/ folder containing various fragment files to be included, such as header, navigation, footer, etc.
Have you ever looked at http://www.phpobjectgenerator.com/
It generates really nicely CRUD formatted objects for database tables.

Categories