What should be required for createBlock - magento

I want to create a block and add that block to my template via
$this->_addContent($this->getLayout()->createBlock("device/device"))
Right now, it is not displaying anything.
What are the points to be Noted so that my block will get rendered (what are the files to be aware off?)
Note:
COMPANY NAME: Abc
MODULE NAME: Device
Also, createBlock("device/device") returns "false"

The device/device string that is being passed to createBlock is a class alias. Class aliases give the Magento developer a way to refer to classes without using the actual class name. This indirection allows for one class to be substituted (or rewritten in Magento terminology) for another without having to change any code which instantiates and uses the class.
You start by defining the prefix for your classes in your module's config.xml file as follows (note: add this code into any existing tags, rather than just dropping it in at the bottom of the config.xml):
<config>
<global>
<blocks>
<device>
<class>Abc_Device_Block</class>
</devicer>
</blocks>
</global>
</config>
When building the class name for a block, the part of the xml is the part which comes before the / in the alias, and is substituted for the contents of the tags when generating the class name. The / is then replaced with an _ and the remaining part of the class alias is appended to the class name. So with the class alias device/device, and the above XML, the following class name will be built Abc_Device_Block_Device, which Magento will expect to find in Abc/Device/Block/Device.php. It will search folders in the order specified in the include_path, which is normally app/code/local, then app/code/community, followed by app/code/core and finally `lib.
The same basic logic also applies to model and helper classes.
Alan Storm's indispensable CommerceBug extension has a great tool for testing what model/block/helper class aliases map to in terms of class names and file locations.
The other parameters on this method are a name which can be used to refer to the block (and modify it) from layout XML files, and an array of other attributes which could be found in the layout XML.

That was an excellent answer Jim. Adding a point to it, the priority is the
Local
Community and then comes
Core if I was not wrong .

Related

What is the correct structure to set the source model for magento attribute

I'm trying to add an attribute to my magento products that relies on custom functionality to provide the options for this attribute.
For this I have created a source model in MyNamespace/MyExtension/Model/Product/Attribute/Source/MyAttribute
Then I tried telling Magento to use my model by setting the source_model for this attribute, when I kept getting the following error:
Source model "mynamespace/myextension_product_attribute_source_myattribute" not found for attribute "vendor"
I believe I tried all possible combinations, like:
myextension/product_attribute_source_myattribute
mynamespace_myextension/product_attribute_source_myattribute
mynamespace/myextension_model_product_attribute_source_myattribute
and so on, without any luck. Then I used the classname:
MyNamespace_MyExtension_Model_Product_Attribute_Source_MyAttribute
which to my surprise actually works. However, I would still like to know what structure using the magento convention is the way to go - i.e., magento uses:
catalog/product_attribute_source_countryofmanufacture
to load Mage_Catalog_Model_Product_Attribute_Source_Countryofmanufacture class
After some struggling with the implementation of other modules and their configuration I finally found the answer.
The modules configuration file defines the base namespace for models, under which multiple model classes can be loaded:
<global>
<models>
<mynamespace_myextension>
<class>MyNamespace_MyExtension_Model</class>
</mynamespace_myextension>
</models>
</global>
Now, when loading a module, you state the xml definition you use as namespace before the slash, then omit namespaces already given in the class tag and add the specific structure for the model:
mynamespace_myextension/product_attribute_source_myattribute
You can load additional models under the same namespace without having to add them specifically to your xml

Are helper classes mandatory for all Magento extensions?

Many extensions (including the one's I've written) include a helper class that just extend the abstract base class without adding any functionality. The helper usually looks like this:
class MyCompany_MyModule_Helper_Data extends Mage_Core_Helper_Abstract {
}
The extended class is therefore just used for things that the abstract class provides, especially for translations. On the other hand, all Block and Controller classes in Magento inherit the __() method for translations - and in an extension I'm currently developing I don't have the need to call the helper class even once.
Can I just delete the helper class and remove it from config.xml? I've tried it and the extension seems to work fine without, but due to Magento's complexity I'm always a bit worried that there are implications I'm not aware of.
If you're creating a module from scratch, helper classes aren't strictly necessary. I usually skip creating one until it's needed.
However, if any XML file uses the module attribute to specify a translation module, that attribute needs to resolve to a valid helper. For example, in this core file
<!-- File: app/code/core/Mage/Catalog/etc/system.xml -->
<tabs>
<catalog translate="label" module="catalog">
<label>Catalog</label>
<sort_order>200</sort_order>
</catalog>
</tabs>
There's module="catalog". By specifying this attribute, the Magento system code that translates the label will look something like this
Mage::helper('catalog')->__('Label');
So, removing the helper from the catalog module would break parts of Magento.
(The single part class alias catalog is automatically converted to Mage::helper('catalog/data') by Magento system code)
This "helper to group translations" feature is used in many of Magento's XML files, not just system.xml (layout, widgets, etc.). Additionally, there are some systems in Magento that will infer and/or require the existence of a helper module for translations (Access Control, external API system,etc. )
Long Story Short: If you're creating a module from scratch, feel free to leave the helper out until you start getting errors that Magento can't instantiate a helper. Never remove an existing helper from a module, and if you want to make sure you're 100% compatible with assumptions other people might make, always include a Data.php helper class.
Magento's Helper classes contain utility methods that will allow you to perform common tasks on objects and variables. http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-1-introduction-to-magento#6
Assuming that the Helper file is empty with no custom methods eg.
<?php
class MagePal_SomeModule_Helper_Data extends Mage_Core_Helper_Abstract
{
}
Then some of things that may still be affected are:
system.xml - blank screen for your module in admin -> system -> config
$this->__('') - error in your .phtml template (for internationalization/translation)
So if your helper is empty, without a system config section and no translation then it 'maybe' ok to delete.

Magento 1.7 Override Pdf Classes

I tried to override Pdf classes for making changes toInvoice/Shipment/Creditmemo pdf but it doesnt seem to reflect.
I created a module with following in the Mymodule/etc/config.xml
<config>
<modules>
<Mymodule_Printtemplates>
<version>0.1.0</version>
</Mymodule_Printtemplates>
</modules>
<global>
<models>
<sales>
<rewrite>
<order_pdf_abstract>Mymodule_Printtemplates_Model_Order_Pdf_Abstract</order_pdf_abstract>
<order_pdf_invoice>Mymodule_Printtemplates_Model_Order_Pdf_Invoice</order_pdf_invoice>
<order_pdf_creditmemo>Mymodule_Printtemplates_Model_Order_Pdf_Creditmemo</order_pdf_Creditmemo>
<order_pdf_shipment>Mymodule_Printtemplates_Model_Order_Pdf_Shipment</order_pdf_shipment>
</rewrite>
</sales>
</models>
</global>
Then I created following Model classes in Mymodule/models/
as Abstract.php, Invoice.php, Shipment.php, Creditmemo.php
abstract class Mymodule_Printtemplates_Model_Order_Pdf_Abstract extends Mage_Sales_Model_Order_Pdf_Abstract
class Mymodule_Printtemplates_Model_Order_Pdf_Invoice extends Mymodule__Printtemplates_Model_Order_Pdf_Abstract { ... functions here ...}
class Mymodule_Printtemplates_Model_Order_Pdf_Shipment extends Mymodule__Printtemplates_Model_Order_Pdf_Abstract{ ... functions here ...}
class Mymodule_Printtemplates_Model_Order_Pdf_Creditmemo extends Mymodule__Printtemplates_Model_Order_Pdf_Abstract{ ... functions here ...}
The module is enabled - I have checked it through System>Configuration>Admin>Advanced but it doesn't seem to reflect the changes
On the other-hand, if I copy paste Mage/Sales/Model/Order/Pdf/*.php into local and change, changes are reflected. I know this is not a recommended method but the method via rewriting classes doesnt seem to work.
Any help for the first method via class rewrite would be appreciated.
Thanks,
Loveleen
The real problem was a Syntax in error in etc/config.xml [see Capital C in ending tag]
Mymodule_Printtemplates_Model_Order_Pdf_Creditmemo
I used the following to debug the issue: Drop this in the bottom of your index.php, similar to Alans Module List but a quick code copy/paste approach. Remember all of Magento's XML's get combined into one XML tree.
header("Content-Type: text/xml"); die(Mage::app()->getConfig()->getNode()->asXML());
Taken from the answers of: How do I know whether my Config.xml file is working in Magento?
Here are a couple of things that I am seeing.
What are the file paths to each of your overridden files? They should be: Mymodule/Printtemplates/Model/Order/Pdf/Invoice.php, for example. The class name should match the file name.
Rewrites do not affect abstract classes, unless the abstract class is called with a factory method (not recommended). The way that a rewrite works is through the factory methods (Mage::getModel('')). Using the factory method allows Magento to look through the system to see if another class is needing to be used. However, when a class is hard-referenced (e.x. Mage_Sales_Model_Order_Pdf_Abstract), it does not go through the factory method, and thus no rewrites will occur on that.
I would consider making each of your classes extend their original class (e.x. Mage_Sales_Model_Order_Pdf_Invoice, etc). If you have extra common functions, you would possibly put those into a Helper.
To see if the code is even being called, put a known code error in the file. PHP will complain, and that tells you that your file is being loaded.
I used the following to debug the issue:
Drop this in the bottom of your index.php, similar to Alans Module List but a quick code copy/paste approach. Remember all of Magento's XML's get combined into one XML tree.
header("Content-Type: text/xml");
die(Mage::app()->getConfig()->getNode()->asXML());
Taken from the answers of: How do I know whether my Config.xml file is working in Magento?

Is it possible to use CamelCase class names in Magento models?

Let's say you have a class name Space_Module_Model_LongModelName and you want to reference it as:
Mage::getModel('module/longmodelname');
This seems to work in some development environments, but doesn't seem to work in all environments. Probably has to do with a file system case sensitivity setting.
The error that you get in environments where it doesn't work is that the include() for Space/Module/Model/Longmodelname.php failed.
You have a config-node in your config.xml called global/models/yourpackage in which you save your Prefix for your class models.
When you call Mage::getModel('packagename/classname') Magento fetches this config node e.g. Company_Yourmodule_Models adds a _ and then the classname with uppercase first letter:
Company_Yourmodule_Models_Classname
if you have cAMElcaSe classnames, it is the same way. So let's say your class' name is ClassName then you have to call Mage::getModel('packagename/className') and magento resolves it to: Company_Yourmodule_Models_ClassName
Take a look at app/code/core/Mage/Core/Model/Config.php specifically getGroupedClassName(); as you'll notice uc_words is used in the method when building the $className, which will capitalize every other word in the class name string.
So your class name of LongModelName will become Longmodelname for the include.
You could easily extend this to work the way you want but since its such a main piece of Magento's factory generation personally I would not touch it in fear of breaking other 3rd party modules, and live with the non-camel case namespace.
The reason ImportExport works is because it is the module name and not a class name. I've run into the same issue before and as annoying as it is I tend to just keep class names non-Camel cased.
For sure there is possibility to use camelcase - you can see module e.g. ImportExport in Magento core. I think all is about setting correct (with camel cases) names in xmls
Four years later, another note:
If you want to use camelCased classnames in addition to filenames, make sure the following part of your {moduleName}/etc/config.xml is camelCased as well:
```xml
<global>
<models>
<ProbablyYourCompanyOrModuleName>
<ModuleName_resource>
<entities>
<!-- "longModelName" below should be CamelCased, but prob the first letter will be lowercased -->
<longModelName>
<table>your_db_table_name</table>
</longModelName>
</entities>
</ModuleName_resource>
</ProbablyYourCompanyOrModuleName>
</models>
</global>
```
The portion should be camelCased with the first letter lowercased. Otherwise, you'll get an exception of Can't retrieve entity config: yourmodule/longModelName
(see Mage_Core_Model_Resource::getTableName())

Magento-module renamed, but Magento keeps asking for the old helper class

Magento, versions CE 1.4.2, 1.5.0.1, 1.5.1.0
I have had to adapt a payment module for Magento, following all recipes, config.xml, system.xml, etc/module/Mycompany_Mypaymentmodule.xml, which all work fine.
But recently, I've double checked and found an error:
in my config.xml, I had put:
<config>
<modules>
<Mage_Mycompany>
<version>0.1.0</version>
</Mage_Mycompany>
</modules>
...
That's because originally, the module was supposed to be placed inside the community-folder.
Following the guidelines, I've rewritten classes, xml's et cetera to reflect the local codepool. That too went well (except for an error that I had debugged).
However, inside the config.xml, I have renamed the modules-tag, like so:
<config>
<modules>
<Mycompany_Mypaymentmodule>
<version>0.1.0</version>
</Mycompany_Mypaymentmodule>
</modules>
The strange thing is that Magento now keeps asking me for the old Helper-class-file when I go to the Payment Methods in the backend, resulting in:
Fatal error: Class 'Mage_Mycompany_Helper_Data' not found in path\to\app\Mage.php on line 520
In other words, Magento keeps asking for a helper class of my old, pre-renamed module, which of course is nowhere to be found.
I've done an extensive search in all files, but nowhere is the string Mage_Mycompany to be found, so my guess is Magento is trying to load this helper class out of a database table. Of course, I've cleared the cache and rebuilt all indexes multiple times, and removed all cache files. I also checked practically all database tables, but to no avail.
Second, when I create the helper class by hand in app/code/community/Mage/Mycompany/Helper/Data.php, all goes well, which to me sounds strange, because the class itself should not be called (since it is never mentioned in any config.xml).
I must be missing something, and perhaps the class name is generated on the fly, but I really do not know how to avoid it or to fix it... so any help is appreciated!
Step one, of course, is to clear your cache.
If clearing cache doesn't work.
Step 2: The data helper class is used to translate strings for a module. That is, each data helper has a method
$helper->__('Translate this symbol');
that will translate a string per that module's helper file.
Throughout the system, there are several XML files where you may want certain nodes to be translated. The syntax looks something like this.
<dhl translate="label" module="usa">
<label>The Label</label>
</dhl>
Here you're telling magento to translate the "label" node enclosed in dhl, and to use the usa module to do it. That is, use the helper instantiated like
$Mage::getModel('usa/data');
//same thing as above, helpers default to data
Mage::getModel('usa');
to translate the label
$helper->__('The Label');
My guess is one of your XML files still has your old module configure for translation
<sometag module="mycompany" translate="someothertag" />
which makes magento look for a helper that's no longer there, and boom, there's your error.
Tha Data helper is loaded when you call the translation helper, ie: Mage::helper('modulename')->__("some string to translate").
In your config .xml, have you declared the module's helper class?:
<config>
...
<global>
...
<helpers>
<yourmodule>
<class>Yourcompanyname_Yourmodule_Helper</class>
</yourmodule>
</helpers>
...
</global>
...
</config>

Resources