Professional Documents
Culture Documents
Lets mimic this and add a new line somewhere inside the same block tag.
Good. Now we told Magento that new structural block exists with the name newreference. Magento still doesnt know what to do with it.
TRUNCATE `sales_order_entity_datetime`; Lets assume we wish the newreference block to be placed TRUNCATE `sales_order_entity_decimal`; below 2 columns, but above the footer. In this case, our TRUNCATE `sales_order_entity_int`; updated file could look like this: TRUNCATE `sales_order_entity_text`; TRUNCATE `sales_order_entity_varchar`; <!-- start middle --> TRUNCATE `sales_order_int`; <div class="middle-container"> TRUNCATE `sales_order_text`; <div class="middle col-2-right-layout">< ?php getChildHtml('breadcrumbs') ?> TRUNCATE `sales_order_varchar`; <!-- start center --> TRUNCATE `sales_flat_quote`; <div id="main" class="col-main"><!-- start global messages --> TRUNCATE `sales_flat_quote_address`; < ?php getChildHtml('global_messages') ?> TRUNCATE `sales_flat_quote_address_item`; <!-- end global messages --> TRUNCATE `sales_flat_quote_item`; <!-- start content --> TRUNCATE `sales_flat_quote_item_option`; < ?php getChildHtml('content') ?> TRUNCATE `sales_flat_order_item`; <!-- end content --></div> TRUNCATE `sendfriend_log`; <!-- end center --> TRUNCATE `tag`; TRUNCATE `tag_relation`; <!-- start right --> TRUNCATE `tag_summary`; <div class="col-right side-col">< ?php getChildHtml('right') ?></div> TRUNCATE `wishlist`; <!-- end right --></div> TRUNCATE `log_quote`; <div>< ?php getChildHtml('newreference') ?></div> TRUNCATE `report_event`; </div> <!-- end middle --> ALTER TABLE `sales_order` AUTO_INCREMENT=1; ALTER TABLE `sales_order_datetime` AUTO_INCREMENT=1; Step 3: Populating structural block ALTER TABLE `sales_order_decimal` AUTO_INCREMENT=1; ALTER TABLE `sales_order_entity` AUTO_INCREMENT=1; We have the block properly placed, but unfortunately nothing ALTER TABLE `sales_order_entity_datetime` AUTO_INCREMENT=1; is new on the frontsite. Lets populate the new block with ALTER TABLE `sales_order_entity_decimal` AUTO_INCREMENT=1; something. We will put new products block there as an ALTER TABLE `sales_order_entity_int` AUTO_INCREMENT=1; ALTER TABLE `sales_order_entity_text` AUTO_INCREMENT=1; example. Go to appropriate layout XML file and add this block ALTER TABLE `sales_order_entity_varchar` AUTO_INCREMENT=1; to appropriate place. ALTER TABLE `sales_order_int` AUTO_INCREMENT=1; ALTER TABLE `sales_order_text` AUTO_INCREMENT=1; <reference name="newreference"> <block type="catalog/product_new" name="home.product.new" ALTER TABLE `sales_order_varchar` AUTO_INCREMENT=1; template="catalog/product/new.phtml" /> ALTER TABLE `sales_flat_quote` AUTO_INCREMENT=1; </reference> ALTER TABLE `sales_flat_quote_address` AUTO_INCREMENT=1; ALTER TABLE `sales_flat_quote_address_item` AUTO_INCREMENT=1 Thats it. I hope it will help someone ALTER TABLE `sales_flat_quote_item` AUTO_INCREMENT=1; ALTER TABLE `sales_flat_quote_item_option` AUTO_INCREMENT=1; There are 15 comments ALTER TABLE `sales_flat_order_item` AUTO_INCREMENT=1; ALTER TABLE `sendfriend_log` AUTO_INCREMENT=1; ALTER TABLE `tag` AUTO_INCREMENT=1; ALTER TABLE `tag_relation` AUTO_INCREMENT=1; ALTER TABLE `tag_summary` AUTO_INCREMENT=1; ALTER TABLE `wishlist` AUTO_INCREMENT=1; ALTER TABLE `log_quote` AUTO_INCREMENT=1; You got a Magento project to develop, you created a Magento ALTER TABLE `report_event` AUTO_INCREMENT=1;
theme, you placed initial products and categories and you also placed some test orders to see if Shipping and Payment methods work as expected. Everything seems to be cool and the client wishes to launch the site. You launch it. When you enter the administration for the first time after the launch, you will see all your test orders there. You know those should be deleted. But how?
If you try to delete orders in the backend, you will find out that you can only set the status to cancelled and the order is still there. Unfortunately, Magento doesnt enable us to delete those via administration, so you will not see any Delete order button. This can be quite frustrating both to developers and the merchants. People coming from an SAP world find the inability to delete to have some merit but there should be a status that removes the sales count from the reports i.e. sales, inventory, etc.
SET FOREIGN_KEY_CHECKS=0; TRUNCATE TRUNCATE TRUNCATE TRUNCATE `sales_order`; `sales_order_datetime`; `sales_order_decimal`; `sales_order_entity`;
-- reset TRUNCATE TRUNCATE TRUNCATE TRUNCATE TRUNCATE TRUNCATE TRUNCATE TRUNCATE TRUNCATE TRUNCATE TRUNCATE TRUNCATE TRUNCATE TRUNCATE TRUNCATE ALTER ALTER ALTER ALTER ALTER ALTER ALTER ALTER
customers `customer_address_entity`; `customer_address_entity_datetime`; `customer_address_entity_decimal`; `customer_address_entity_int`; `customer_address_entity_text`; `customer_address_entity_varchar`; `customer_entity`; `customer_entity_datetime`; `customer_entity_decimal`; `customer_entity_int`; `customer_entity_text`; `customer_entity_varchar`; `log_customer`; `log_visitor`; `log_visitor_info`;
`customer_address_entity` AUTO_INCREMENT=1; `customer_address_entity_datetime` AUTO_INCREMEN `customer_address_entity_decimal` AUTO_INCREMENT `customer_address_entity_int` AUTO_INCREMENT=1; `customer_address_entity_text` AUTO_INCREMENT=1; `customer_address_entity_varchar` AUTO_INCREMENT `customer_entity` AUTO_INCREMENT=1; `customer_entity_datetime` AUTO_INCREMENT=1;
Created using zinepal.com. Go online to create your own zines or read what others have already published.
-- Reset all ID counters TRUNCATE `eav_entity_store`; ALTER TABLE `eav_entity_store` AUTO_INCREMENT=1; SET FOREIGN_KEY_CHECKS=1;
< ?php if (!empty($result)): ?> <table id="relatedProductsList"> < ?php foreach ($result as $item): ?> <tr class="productInfo"> <td><a href="<?php echo $storeUrl ?>/< ?php echo $item->url_ <td>< ?php _e('Starting at') ?> $ < ?php echo floatval($item </tr> < ?php endforeach; ?> </table> < ?php endif; ?>
After you have it executed, the test orders will not be in the database any more. Keep in mind that this will delete ALL orders, in the database. So, you should execute this queries immediately after launch.
Hope some of you find this useful. Especially those who refuse to use Web Services for connecting different systems. Download connect2MAGE WordPress plugin.
Custom checkout cart - How to send email after successful checkout in Magento | Inchoo
Recently I have been working on a custom checkout page for one of our clients in Sweden. I had some trouble figuring out how to send default Magento order email with all of the order info. After an hour or so of studying Magento core code, here is the solution on how to send email after successful order has been made. Not sure how useful this alone will be for you, so Ill throw a little advice along the way. When trying to figure how to reuse Magento code, separate some time to study the Model classes with more detail. Then tapping into and reusing some of them should be far more easier.
Lets create a file called latest_news.phtml in app/design/frontend/default/[your_theme]/template/ callouts/latest_news.phtml $result = array(); Now we will create a PHP block that will display the list if(!empty($entityIds)) of articles from RSS feed. We will use Inchoo RSS for { demonstration purposes. In your scenario, replace it with your $entityIds = $entityIds[0]; $sql = "SELECT `e`.*, `_table_price`.`value` AS `price`, own valid RSS URL. IFNULL(_table_visibility.value, _table_visibility_default.va
$entityIds = get_post_custom_values(get_option('connect2MAGE_CustomFieldName')); $result = $MAGEDB->get_results($sql); var_dump($result); }
<div class="block block-latest-news"> <div class="block-title"> else <h2>< ?php echo $this->__('Latest News') ?></h2> { </div> echo '<p class="relatedProductInfo">No related products available...</p>'; <div class="block-content"> }
Created using zinepal.com. Go online to create your own zines or read what others have already published.
<ol id="graybox-latest-news"> use the http://somestore.domain/catalogsearch/ < ?php foreach ($channel as $item): ?> partnumber as a link <li><a href="<?php echo $item->link; ?>">< ?php echo $item->title; ?></a></li> < ?php endforeach; ?> show only custom_partnumber field on the search form </ol> </div> First, we have to see where does the /advanced come from. </div>
Step 2 Now, we should decide where to place it. I assume you already know how Magento blocks and references work. Lets assume you would like to place it in right column by default for whole catalog. In this case open your app/design/frontend/default/ [your_theme]/layout/catalog.xml file and under default tag update right reference with something similar. Thats it. You should be able to see the list of articles from RSS feed with the URLs. Hope this will help someone.
app\design\frontend\default\default\template \catalogsearch\ there you will see the /advanced folder. Make a copy of that entire folder, in the same location, and name it to something like /custom. Now your /custom folder should have 2 files: form.phtml and result.phtml. Next in line is the /layout folder in our template. You need to open catalogsearch.xml file. Go to line 64. Do you see the <catalogsearch_advanced_index> tag there. Make the copy of it (including all of the content it hold with the closing tag also). Put the copy of that entire small chunk of code right below. Now rename all of the occurrences of advanced to custom there like on code below: <catalogsearch_custom_index> <! Mage_Catalogsearch > <reference name=root> <action method=setTemplate><template>page/2columnsright.phtml</template></action> </reference> <reference name=head> <action method=addItem><type>js_css</ type><name>calendar/calendar-win2k-1.css</ name><params/><!<if/ ><condition>can_load_calendar_js</condition>></ action> <action method=addItem><type>js</ type><name>calendar/calendar.js</name><!<params/ ><if/><condition>can_load_calendar_js</condition> ></action> <action method=addItem><type>js</ type><name>calendar/lang/calendar-en.js</name><! <params/><if/><condition>can_load_calendar_js</ condition>></action> <action method=addItem><type>js</ type><name>calendar/calendar-setup.js</name><! <params/><if/><condition>can_load_calendar_js</ condition>></action> </reference> <reference name=content>
Created using zinepal.com. Go online to create your own zines or read what others have already published.
<block type=catalogsearch/custom_form name=catalogsearch_custom_form template=catalogsearch/custom/form.phtml/> </reference> </catalogsearch_custom_index> Do the same for <catalogsearch_advanced_result> tag. Now go to the app\code\core\Mage\CatalogSearch\Block folder. And make a copy of /Advanced folder naming it /Custom. Open /Custom/Form.php and replace class name Mage_CatalogSearch_Block_Advanced_Form with Mage_CatalogSearch_Block_Custom_Form, then open /Custom/Result.php and replace class name Mage_CatalogSearch_Block_Advanced_Result with Mage_CatalogSearch_Block_Custom_Result. Inside Form.php there is getModel() function. DO NOT replace the Mage::getSingleton(catalogsearch/advanced); with Mage::getSingleton(catalogsearch/custom);. The point is to use the default advanced search logic here. Same goes for getSearchModel() function inside Result.php file. Next in line, controllers. We need to make the copy of AdvancedController.php and name it CustomController.php, then open it and replace the class name Mage_CatalogSearch_AdvancedController with Mage_CatalogSearch_CustomController. Inside this CustomController.php there is a function called resultAction(). You need to replace the ( Mage::getSingleton(catalogsearch/advanced) ) string catalogsearch/advanced with catalogsearch/custom. This is the one telling the browser what page to open. Now if you open your url link in browser with /index.php/ catalogsearch/custom instead of /index.php/catalogsearch/ advanced you will see the same form there. And for the final task As we said at the start, the point of all this is to 1) get more custom link in url and 2) display only one custom searchable attribute field in form. Therefore, for the last step we need to go to the template\catalogsearch\custom folder and open form.phtml file. Inside that file, there is one foreach loop that goes like <?php foreach ($this->getSearchableAttributes() $_attribute): ?> as
This might not be the best method of reusing already written code, however I hope its any eye opener to somewhat more elegant aproach. Enyoj.
Related products
There are three types of product relations in Magento: Up-sells, Related Products, and Cross-sell Products. When viewing a product, Upsells for this product are items that your customers would ideally buy instead of the product theyre viewing. They might be better quality, produce a higher profit margin, be more popular, etc. These appear on the product info page. Related products appear in the product info page as well, in the right column. Related products are meant to be purchased in addition to the item the customer is viewing. Finally, Cross-sell items appear in the shopping cart. When a customer navigates to the shopping cart (this can happen automatically after adding a product, or not), the cross-sells block displays a selection of items marked as cross-sells to the items already in the cart. Theyre a bit like impulse buys like magazines and candy at the cash registers in grocery stores.
Upsells
This is the example of the Up-sell. Ideally, the visitor is supposed to analyze those products as they should be relevant to the one that is just loaded.
All we need to do now is to place one if() condition right below it. If your custom attribute name (code) is my_custom_attribute then your if() condition might look something like <?php foreach ($this->getSearchableAttributes() $_attribute): ?> <?php if($_code == my_custom_attribute): ?> <?php endif; ?> <?php endforeach; ?> And you are done. Now you have somewhat more custom url, and only one custom field displayed on that url. as
Created using zinepal.com. Go online to create your own zines or read what others have already published.
Mage::getSingleton(catalog/session) on view.phtml file we would retrieve an array with some useful data in it. Do not get confused with me mentioning the view.phmtl file, its just he file i like to use to test the code. Using Mage::getSingleton(core/session) would retrieve us some more data. You get the picture. Test, test, test Whats great about the whole thing is that naming in Magento is perfectly logical so most of the time you will probably find stuff you need in few minutes or so.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
Mage_Catalog_Block_Product_View::canEmailToFriend(); Now all you need to do is to replace Mage_Catalog_Block_Product_View with $this like $this->canEmailToFriend(); And youre done. All of this may look like why do I need this. What you need it a smart IDE, one that can figure out the context of $this by it self and call the methods accordingly. No IDE currently does that, if Im not missing on something. For now I see no better solution to retrieve the object context of $this across all those Magento files. If you need some help setting up Krumo with Magento you can read my other, somewhat detailed article on activecodeline.com. Hope this was useful for you.
Default order takes the first value available. So, all you have to do is to either: reorder it if you want to have a selection in the Toolbar or set only one value of choice if you will remove the selection from the toolbar I hope this will help somebody.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
The love and the passion for beautiful home interiors translates into a high-quality product with a sophisticated style manufactured in the USA. Pebblehill Designs has assembled some of the most popular styles of custom upholstered furniture to offer to our customers. All styles are available in every fabric shown or you can provide your own fabric. You can customize the furniture collection to express your own unique style made with the highest quality materials and craftsmanship available.
Magento part of the site can be viewed if you click at Shop by Vehicle or Shop by Brand tabs from the main menu, but you will notice that some blocks seamlessly integrate between two solutions.
We developed this site as the Surgeworks team. The design was created by one of out top designers, Rafael Torales. We hope you enjoy it and feel free to post your comments.
The Best Shopping Cart :: Trend analysis of osCommerce, Magento, ZenCart and CRE Loaded | Inchoo TeraFlex PLUS, another Magento + Wordpress duo
After we launched TeraFlex Suspensions website few months ago, we created a new similar website for Teraflex PLUS. Although the name is similar, this is not the same company. The primary goal of this site is to help Jeep owners to upgrade their pets with parts and accessories for any type of adventure. The secondary goal is to create a Jeep enthusiast community in Utah, USA and surroundings. The site is powered by Wordpress and Magento combination. Magento is a superb Shopping Cart, but it lacks some of the CMS features. Wordpress is a superb CMS, but it fails to provide the needs for the eCommerce goals. The combination of these can create a very powerful website. We present you TeraFlex PLUS : Jeep Adventure Outfitters http://www.teraflexplus.com/ As you can see, osCommerce still remains the most popular eCommerce platform. However, you can notice that this
Created using zinepal.com. Go online to create your own zines or read what others have already published. 8
If you try to ask this question on some forum or newsgroup, you will surely get many replies. Everyone will present you his favorite. My first developed online store was created with standard osCommerce platform. After three or four projects, I started to work with CRE Loaded and used it frequently for years. Although it was also an osCommerce fork, it had many advantages. I switched to Magento early this year and this is my final choice. Google Trends is a great tool to check some platforms popularity by comparing it to the competition. For my short analysis, I compared:
popularity is fading. ZenCart is stable for the past two years. And my previous favorite, CRE Loaded (much better solution than ZenCart in my opinion), is very low. Its popularity is also fading even after their team put great effort into a new website and identity. Now, take a look at blue line. My prediction is that sometime in Q1 2009, Magento will become most popular eCommerce platform. It will surely kick osCommerce off the throne where that fat duck was sitting for many years. It was about time. First of all, let me inform you that this article is for those of you who are just starting with Magento. If you are a Magento expert, you will probably know this. Consider it just a reminder for those who use Magento for first time. There are three common mistakes that most people do when they try to use Magento for first time, so read this article and you wont be one of them.:) More experienced PHP developers will first read Magento Designers Guide before they try to style Magento, but others wont and thats the mistake number two. Since Magento has great theme fallback system there is really no need to touch default theme. Although easiest way to make new theme for new Magento is top copy the whole theme to a new folder, dont do that. Copy only the files you will need: from / design/frontend/default/default/ directory to /design/ frontend/default/YOUR_NEW_THEME directory. Do the same thing with /skin/frontend/default/default/ Congratulations, you have your own theme just like that. All that left is to apply new theme (System>Configuration->Design) and you are ready to do with your theme files whatever you want. Third mistake is modifying Magento core files. What files are core ones? All what is in app/code/core folder. If you have a need to modify some of those ones, you just need to duplicate that file in the same directory path to app/ code/local. For example, if you need to modify the file app/code/core/Mage/Checkout/Block/Success.php copy it to app/code/local/Mage/Checkout/Block/Success.php and leave the core file intact. This way your Magento will be more bullet-proof to future updates.
also tutorial about this on Magento Wiki. However i dont like approach of duplicating and overriding Mage files from /local, if it can be avoided, so i decided to write this small and useful example of adding or overriding default Magento settings through separated config files. And yes, Magento values can be overridden this way. Default layouts config can be found in app/code/core/Mage/Cms/etc/config.xml along with used xml code structure, so check it out. Thank you for listening!
... global $language ; $lname = ($language->language == null) ? 'en' : $language->l $storeView = null; if($lname == 'de') { $storeView = '?___store=german&amp; ??>
Note the $storeView variable; GET ___store holds the value of code name of the view you assigned in Magento, while GET ___from_store variable is used as helper to Magento inner workings. You can basically omit the other one. Your links to Shop from Drupal to Magento should now activate the proper language, the same one you have active on Drupal side.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
So what happened here? Magento just doesnt have stored privileges for this new extension. First just try to logout and login again. If that doesnt work, you need to reset admin privileges. Navigate to System->Permissions->Roles Administrators role. and click
Check your Role Resources settings just in case, Resource Access dropdown should be already set to All for administrators.
Database diagrams and documents found in this post are intended to mirror the database schema as defined by Varien. Table relationships depicted in the diagrams represent only those relationships explicitly defined as Foreign Keys in the Magento database. Additional informal/undiagrammed table relationships may also exist, so when modifying the schema or directly manipulating data it is important to identify and evaluate possible changes to these tables as well (and the tables they relate to, and the tables they relate to). The author of Database Diagram is Gordon Goodwin, IT Consultant. You can see his info in the PDF.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
Magento has this great feature, rss feed for orders. You can access it via link http://myshopsite/rss/order/new. It requires authentication, so you need to provide Magento user and pass to access this link. Idea I wanted to play around was how to get this info in my windows app. Its really, really simple. Below is the screenshot of this little app for you to see what Im talking about.
And here is the application it self simpleorderpreview and full source code (Visual Studio 2008 Express C#, entire solution project) acmnewproducts. When you un-archive files from simpleorderpreview there is only one thing you need to do prior to running .exe file. You need to open ACMNewProducts.exe.config and set username, password and url of your own Magento shop. Thats it. Now you can run the app. One click on Magento icon inside the taskbar executes show order process, while double cliking the icon closes the application. I will not go into the details in this post on how this works. Basicaly its simple XML parser. Most important part is the HTTP authentification, which you can see in code source code. Hope you find this usefull, something to play with.
Technically, we create a simple products and after that a grouped products. When we edit the grouped product, we will associate simple products to it.It works very fine, but some of you might have issue if a simple product has custom options. If thats the case, and if costum options are set as required (default way), the simple product will not be associative to the grouped product. Lets see what needs to be changed in that case. On Magento site, there is a nice tutorial how to create a grouped product. Please read it first to become familiar with the process. If you dont have to assign simple products with custom options to a grouped product, that tutorial will be enough.
Associate simple product with custom options in grouped product in Magento | Inchoo
Does the title sound complicated? Grouped Products display several products on one page. For example if youre selling chefs knives and you have the same knife in four sizes, you can make a grouped product to display all four sizes. Customers can select the size(s) they want and add to cart from this page. Another example would be a themed bedroom set you can create a grouped product and sell the sheets, comforter, and pillow cases all from the same page.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
11
One of the things that caught my eye and made me wonder about the consequences is the Observer and override functionality that probably most of the serious custom made Magento modules will utilize. Utilizing Observers enables you to observe and execute some action inside the customer work flow or even some admin stuff. Such functionality is heavily known is systems like WordPress and its called hooks. Besides hooking, another useful an very powerful feature which is actually related more to the OOP concept itself is the overriding. Personally i find the combination of observers and overrides to be the coolest and most powerful stuff in Magento module development. So where is the issue? As of time of this writing, the latest Magento version is 1.3.1. Lets look at the previous major release prior to that one, version 1.2.1.2. Here is a prepareForCart method signature from app/code/core/ Mage/Catalog/Model/Product/Type/Abstract.php (line 239, Magento version 1.2.1.2): Notice the difference? Although this might not look like that big of a deal suppose you had implemented override functionality like In the above code, we override the prepareForCart method to to some custom stuff for us. This peace of code would work perfectly fine in version 1.2.1.2, but when client decides to upgrade the shop to 1.3.1 or newer he would get the error like To me, stuff like this is a serious downside towards building advanced modules. Changing core files and core functionality can have serious impact on custom made modules each Magento upgrade. Therefore, one should keep an eye open on what modules he will throw into the shop. Personally I consider online stores very serious and have strong feelings about each store owner having somewhat of dedicated developer that will be in charge even for stuff like adding new modules. Just consider the financial loss for a store owner of any more serious web shop if he decides to download the and install module himself just to realize that for incompatibility reasons this new module made his shop fully nonfunctional.
2. Configure Sitemap
Sitemap can be configured from the interface System -> Configuration -> Catalog->Google Sitemap. If you are not sure what does it all mean, check XML Tag definitions section from Sitemaps XML format document.
How to transfer large Magento database from live to development server and other way round
I have been involved in Magento development for almost a year now. God knows I had (and still have) my moments of pain with it . If you are in professional, everyday, PHP development that focuses mainly on Magento then your life probably isnt all flowers and bees. Magento is extremely rich eCommerce platform, but its main downside IMHO is its size and code complexity. If you download Magento via SVN, you will sound find out it has around 11 600 and more files. This is no small figure. Transferring that much of files over the FTP can be a real night mare. Luckily we have SSH and tar command to handle this really neat. But what about database. Today I worked on database with more than 20 000 products in store and with extremely large number of categories. What seemed like easy database
12
Created using zinepal.com. Go online to create your own zines or read what others have already published.
transfer from live site to local developer machine to do a test and fix on few issues tunerd out to be an issue for itself. Without further delay, here is my favorite tool to handle all database related work from now on: Navicat. Among my favorite features is the Data transfer. Directly moving one database to another among different MySQL servers works like a charm. I find yourself strangled among often database recommended action I suggests you test the trial version of this tool. Here are some screenshots of Navicat Data transfer in Action.
Affiliates for all, are modules I consider loosely related to core. They are in one or another way connected to Magento but they are self standing, independent, applications. Installation of Affiliate module is a trivial task. It mostly comes down to extracting downloaded archive file to a web accessible directory (to your server, hosting) and configuring the config.inc file. (For security reasons, try renaming the config.inc to config.inc.php, plus changing the /lib/ bootstrap.php on line 23 to include config.inc.php). After importing affiliates.sql into the database our installation is done. To configure Magento part, one needs to copy required files form /carts directory of Affiliate module and then (turn off Cache) go to System > Configuration and set the required options. After that you can go back to your Affiliate For All application, upload some banners and set their url links to point to your Magento shop. When you test banner the links (click on one of them to get you to Magento store, then Magento store url should have a little GET variable in url like ?ref=someNum). Now when you do the entire checkout process, order info gets recorded to Affiliate For All application. If you wish to play with Affiliate For All without installing it, you can check out the demo (just use Admin both for user and password).
Created using zinepal.com. Go online to create your own zines or read what others have already published.
13
Magento community member Ross gave a good review comment: This is a great theme to use for wire-framing or as a base for developing a custom theme! It looks like a lot of work has gone in to slimming down the HTML and CSS, which makes it much easier to work with compared to the default theme. I particularly appreciate the well structured and commented CSS. The only things I would want different at this stage is for the callouts to be taken out (and removal of associated media images), and for this theme to be included in the main Magento download (I would even like it to be the default). 5 stars from me! Take a sneak peak of how does product info page looks line with no styling, but in finished layout. Im sure that the CSS wizards will find this invaluable.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
14
After this is done we go to the code part. There are three things you need to do here. Upload the jQuery and save it into the /js/jquery/jquery.js. One important note on jQuery; for some reason I had to use jQuery 1.2.3 to get this example working. Latest version 1.2.6 (as of time of this writing) did not work. You can see the exact error it gave me on my screencast. Now you need to modify /template/page/html/head.phtml file to include the jQuery script (or any other if you can code the same logic into it) and write down few lines of JS to do the switching (you can download my version of file here head.phtml) And finaly, you need to modify the /template/catalog/ product/view/media.phtml file to grab all of the product images and dump them into some div. Here is my sample (media.phtml) so just copy paste the code. And some additional screenshots for you to see final result
After some additional styling you can get some impressive results for this. Hope you find it useful. You can see complete screencast at: http://activecodeline.com/wp-content/uploads/videos/ MagentoProductColorChooser.swf
Created using zinepal.com. Go online to create your own zines or read what others have already published.
15
Alternative 1: SVN
In the Downloads tab on Magento website, you will notice SVN page link: http://www.magentocommerce.com/svn You can see how short this page is. You have 2 commands you can run at SVN. You can chack latest work in progress or you can checkout latest stable version. If you are starting to develop a real project, you will probably want a stable version. Lets look at the original command: svn checkout http://svn.magentocommerce.com/ source/branches/1.1 This is probably not the exact command you wish to run on the server. It will place the files in trunk folder. I will assume two things: 1. You will want the clean code 2. You will want to specify the folder where you wish Magento to be installed If those are correct assumptions, you will want to run a command similar to this one: svn export --force http:// svn.magentocommerce.com/source/branches/1.1 shop svn This is the command export - The difference with checkout is that with an export, you get a clean copy of the code, and none of the subversion metadata, so it cant be used to svn up or make further changes. force you will overwrite all of the folders and files if they exist http://svn.magentocommerce.com/source/ branches/1.1 - this is SVN URL. Leave it intact.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
16
shop - the name of the folder you wish to place the files into. You may set the folders name to your likings. Read more about SVN at Wikipedia SVN Page and Subversion official site.
After youre done with setting your new templates save the configuration by clicking on the Save config. Thats it. Wise thing to do now would be to check how the emails look when received so make a test purchase to verify everything is the way it should be.
Notice the type attribute. I used core/template which means you can place this code anywhere in your site and it will work. Code does not inherit any collection objects from controllers since it has none. All that is necessary for the bestseller.phtml to work is defined in that single file.
One more thing: If you study the code in bestseller.phtml file you will see, at the very top of the file, the part that says: $this>show_total.
17
Created using zinepal.com. Go online to create your own zines or read what others have already published.
Support for Downloadable Products. (to see this new product type in action visit the Magento Demo Store. We added an example of an MP3 product and an eBook ) Added Layered Navigation to site search result page, with control on the attribute level to include or exclude attributes used on the search results page. Improved site search to utilize MySQL fulltext search Added support for fixed-taxes on product level for such taxes as State Environmental Fee in the USA and WEEE/DEEE in the EU. Upgraded Zend Framework to the latest stable version 1.7.2 Added a Layered Navigation Cache for improved performance of large catalogs (currently in beta and is NOT recommended for production use). If you need to upgrade existing Magento version through the Magento Connect Manager to 1.2.0.1, follow this steps:
in my home page, then $this would be assigned property show_total with a value of 12.
Therefore, the provided bestseller.phtml file provides the option of setting the number of products you wish to see listed. Here is the bestseller.phtml packed in bestseller.zip. Hope you find this useful.
Do NOT use your live or production site. We suggest making a copy of your site and upgrading that copy first. Backup your index.php and .htaccess files (if modified) Log into your Magento Connect Manager. Select the Setting tab. Change the Preferred State to Stable, and save settings. For the Mage_All_Latest package select upgrade. Click on the Commit Changes button. The upgrade should start. After upgrade is complete click on the Refresh button. Copy your original index.php and .htaccess files back (if needed) Log into your admin and rebuild search index You should now have Magento 1.2.0 installed. Happy Magentizing
Created using zinepal.com. Go online to create your own zines or read what others have already published.
simply create a promotion rule and say something like Set all the products in Category X to be on sale. I provided few screenshots at the bottom of this article to provide a closer look at what Im talking about. I will not go into too much details here since this is a bit more advanced HOW TO, but here is the process in a nutshell: First, create a copy of /catalog/product/list.phtml file and name it onsale_list.phtml. Here is my version of onsale_list.phtml file. Second, activate this new file. There are few ways you can do this. Lets say you wish to assign this onsale_list.phtml on one of our categories, named On Sale, for instance. We then go to Categories > Manage Categories > On Sale select Custom design and under Custom layout update, place the following: product_list_toolbar If you now go to your category On Sale, it should only show products you have assigned to category On sale that have a special price set to them. If you now wish to apply Promotion rules to entire On sale category, then you simply assign a rule to one item, and all the items assigned to the same On sale category (covered by promotion rules) will be automatically listed in the grid. Basically, the magic is in one simple IF statement < ?php if(($_product->special_price !== null) or ($_product>_rule_price !== null)): ?> for each block that lists products. Check out the screenshots, they explain a lot.
Hope you find a way to try this out. Feel free to provide some feedback or additional suggestions.
Magento
After many weeks of work, our 1st Magento project hit the Web: TeraFlex Suspensions. As the purpose of the site
Created using zinepal.com. Go online to create your own zines or read what others have already published. 19
in not primarily selling, but also branding and community development, we decided to use Wordpress and Magento combination to accomplish the clients goals.
I know that this is not some breakthrough article, but I will certanly create contact CMS page on all of my future Magento projects. The Magento portion is visible at http://www.teraflex.biz/ products/. We created an original and custom theme from scratch since we did not want it to look like the default one or to have a feel similar to the default one. It was not an easy task as the learning curve for Magento template system is quite steep compared to other solutions. However, it is worth the time. We added featured products to products page, the lightbox to products info page, and numerous styles that made this store quite unique.
Wordpress
All the menu elements outside Products tab are run by Wordpress. We have stuff like: All of these elements turn Wordpress into a feature-rich CMS suitable for larger projects. How do you like the new site? Feel free to post a comment.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
Bed Room (4) Notice the url link above It wont work if you put it like http:// somesite.domain/furniture/living-room/?price=1%2C199 It wont work like that because by default you do not have price filter functionality covering second subcategory level. What this means is that following link wont work http://somesite.domain/furniture/living-room/? price=1%2C199 Since the first subcategory level is Furniture, and second are Living Room and Bed Room, by default the following url will work with or withoutindex.php. url: price=1%2C199 http://somesite.domain/furniture/?
Most of this is quite selfexplanaory so, for those who need this kind of functionality across some special pages, hope you integrate it withouth any problems.
url: http://somesite.domain/index.php/furniture/? price=1%2C199 You could therefore create simple HTML like <select onchange=setLocation(this.value)> <option value=http://somesite.domain/all/? price=1%2C10000> <! Here you place your own ranges > 0,00 10 000,00 </option> <option value=http://somesite.domain/all/? price=2%2C10000> <! Here you place your own ranges > 10 000,00 20 000,00 </option> <option value=http://somesite.domain/all/? price=3%2C10000> <! Here you place your own ranges > 20 000,00 30 000,00 </option> </select> And put it into some of the static block. Notice the links in above HTML code. The /all part of the url is the url key of the All category in which we added all of our products. Last, but not least is understanding of the price= parametar. 1%2C10000 where 1 stands for first range of 10000 (last number) or 2%2C10000 where 2 stands for second ranfge of 10000, (first would be 0-10000). So if we were to write something like 3%2C10 it would be the price range from 20-30, where 3 stands for third range of tens (number 10). Firs is from 0-10, second 10-20, third 20-30.
Hi, I like your work with Magento, and i see that yre not affraid of experimenting. My question is relative to http:// www.raspberrykids.com. I like the layout, especially folder tab with Description, Tags etc. I didnt find such a feature in Magento. Can you explain it on Inchoo web (in some article), of course, only when it isnt company secret ) Thankx. Have a nice day. Online stores on magentique.com are not only our works. Magentique is the gallery that lists all Magento sites and not only our portfolio. Regarding blog topics, we try to write about the things we work on. However, we can not cover all Magento possibilities. Hope you agree.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
21
Can an online store have only one product? Sure it can and we give you the one that just launched. Kapitol Reef was founded to develop, perfect, manufacture and market a new breed of snorkels based upon pressure-balanced breathing in the aquatic environment. The entire focus for this company is to deliver best-of-class products, starting with the snorkel. Kapitol Reef is in the market for many years and this week they published a new site. Similar to our work on Teraflex project, we used Wordpress and Magento platforms for the development. The request was to have an extensive online store solution with multiple customers groups. Those groups should have different product prices and different payment options. Magento seemed like a great solution for such a request, although the initial concern was if it might be an overkill considering the fact we only have one product to start with? When the development started to roll out, the concern was no more. This will work superbly. We give you the new Magento store that uses a combination of Wordpress and Magento. Magento portion of the site is visible from the Online Store tab.
<label for="lastname">< ?php echo $this->__('Last name') ?> <input id="lastname" name="lastname" class="<em/><strong>inp
<label for="useremail">< ?php echo $this->__('Email') ?> <sp <input type="text" name="useremail" id="useremail" class="<e
<input type="submit" name="submit" value="<?php echo $this-/ </form>< ?php /* END OF my-custom-form */?>
<script type="text/javascript"> //< ![CDATA[ var customForm = new VarienForm('<em><strong>my-custom-form< //]]> </script>
You will notice all of the input fields have one common class name, required-entry. Im not gonna go over all of the available class names here. To find available class names, try going to One page checkout page, where you have checkout form, then simply view source and look for class names next to input, radio select and other fields. Most important thing besides assigning class names is that little piece of JavaScript below the form. Remember to pass form id into the new VarienForm object. Basically thats it. Constructing the form this way, automaticaly makes your form reuse already existing validation code, the one that the rest of the shop is using.
You may also notice a styled color switcher feature we developed for this project. As this product comes in various colors, we decided to spice up the product info page and style the color choosing to replace the default select box.
<form name="<em><strong>my-custom-form</strong>" id="my-custom-form" action="" method="post"> <label for="firstname">< ?php echo $this->__('First name') ?> <span class="required">*</span></label><br /> <input id="firstname" name="firstname" class="<em/><strong>input-text required-entry</strong>" />
Created using zinepal.com. Go online to create your own zines or read what others have already published.
22
Magento Connect
One of the first things that really confused me when i start using Magento is Magento connect. I just started learning things, so i was looking for some plugin examples. I visited Magento connect page with extensions and looked for download button, instead i found Get extension key one. If i recall correctly their What is this? explanation wasnt the same back then .. or i was just so terrified of Magento at start that i didnt understand anything at that point I knew i need to paste that key somewhere, in something they called my Magento connect manager or Magento downloader, but i didnt understand where it is. Visit Magento connect page. There are really some great extensions there and many of them are free. Find extension that interest you, click Get extension key, agree with license agreement and get key. Pay attention to Stability description field (stable, alpha, beta).
This really depends on your server configuration, however its always good to restore permissions to defaults if they are changed to 777, just to be sure.
If you click Settings tab of your connect manager you will see Preferred State option there. If youre installing extension with different stability or you get something similar to you should change this option to appropriate one. You should of course be careful with alphas and betas and know what youre doing. If you are developer or just interested, ftp to downloader/ pearlib/download after you install extension and youll find packed downloaded extensions there. After you use the downloader do you need to change the folder permissions back for security reasons or is it OK just to leave them at 777?
Created using zinepal.com. Go online to create your own zines or read what others have already published.
23
wonder where did I pool the number 11 from? If you open your database (with any tool), and go to sales_order table, you will notice entity_type_id column. Each and every entry in sales_order table has the same value for entity_type_id column. In my Magento installation, this value is 11. Keep in mind that this does not have to mean yours will also be the same. To confirm everything went ok, just Search the database for the inchoo_custom_info (or whatever you used for attribute name). Ok, now that we added new attribute (property) to Order object, we will go on to Observer part. We will create a hook that will watch for successfull checkout process and trigger appropriate code execution. In my example I needed to add some extra info to order upon its successfull creation. Meaning as soon as checkout process is successfully executed, order is stored in database with some extra info I saved in its previously created field inchoo_custom_info. Here is my Observer file, I called it Observer.php and its saved under app/code/local/Inchoo/HookSystem/Model/ Observer.php.
< ?php class Inchoo_HookSystem_Model_Observer { /** * Event Hook: checkout_type_onepage_save_order * @param $observer Varien_Event_Observer */
public function hookToOrderSaveEvent() 'text', { '', /** '', * NOTE: 'Extra info', * Order has already been saved, now we simply add some stuff 'textarea', * that will be saved to database. We add the stuff to Order '', * called "inchoo_custom_info" '', */ Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE, $order = new Mage_Sales_Model_Order(); true, $incrementId = Mage::getSingleton('checkout/session')->getLa false, false, $order->loadByIncrementId($incrementId); '', false, $extraInfo = array( false, 'shirt_color' => 'Freakin cool blue color', false, 'developer_is_freak' => true, true, 'coded_by' => 'Branko Ajzele, Web Application Develop false, ); false, $extraInfo = serialize($extraInfo);
Basically you can copy-paste some existing attribute that suites you the most and just change the array key name. Run this code only once (you can place it inside any file, like index.php or view.phtml or any other that you will execute) then uncomment or remove this code.
NOTE: In code above, note the line $setup>addAttribute(11, $AttrCode, $settings). You probabily
$settings = array('position' => 1, 'is_required' => 0); $setup->addAttribute('11', $AttrCode, $settings); < ?xml version="1.0"?> <config>
this is a module, we also need to add some config Here is the content of my app/code/local/Inchoo/ HookSystem/etc/config.xml
Created using zinepal.com. Go online to create your own zines or read what others have already published.
24
avoid editing the default one). You can download Admintheme module here. Important: Our colour highlighting plugin on this site seems to lower-case some tag names on xml code, so keep that in mind if you experience some trouble with sample code. Huh, we are done! Final result is shown on image. Cheers
And for the final step, open the app/design/adminhtml/ default/mytheme/template/sales/order/view/tab/ info.phtml file and add the following to it:
< ?php /** START CUSTOM Coded by Branko Ajzele | branko.ajzele@surgeworks.com me ?>message today: One of our clients wrote */ a < ?php I have put www.mydomain.com in a bad spot. /** I changed the base URL to {{base_URL}} and * NOTE: * 'inchoo_custom_info' assumes you have added new attribute/property to Sale/Order entity error on both now im getting a 500 server * Please use serialize and unserialize with 'inchoo_custom_info' the front end and the admin panel. I have */ looked through the database and cannot find $extraInfo = $_order->getData('inchoo_custom_info'); the right field to change this value back. Can ?> you point me in the right direction? < ?php if($extraInfo != null or !empty($extraInfo)): ?> < ?php $extraInfo = unserialize($extraInfo) ?> The client went to System> Configuration> Web> Unsecure <div class="entry-edit"> and placed an invalid value for Base URL field. Beware of this <div class="entry-edit-head"> <h4 class="icon-head head-products">Extra order info</h4> field. Unfortunately, Magento just updates it without any pre</div> warnings, but change of this specific value can cause Magento </div> to crash. <div style="height: 30px; padding: 10px; border: #ccc 1px solid; margin-bottom: 20px;"> <pre> Usually, we get an error that looks like this: < ?php print_r($extraInfo) ?> The server encountered an internal error or </pre> </div> misconfiguration and was unable to complete <br /><br /><br /><br /><br /><br /><br /> your request. <div class="clear"></div> < ?php endif; ?> Please contact the server administrator, < ?php /** END CUSTOM Coded by Branko Ajzele | branko.ajzele@surgeworks.com */ ?> webmaster@mysite.com and inform them of
Feel free to remove all my comments. One thing to keep in mind here, the url path has the mytheme pointing to my custom theme. Usefull if you do not wish to edit default admin tempate files. Cooworker and friend of mine, Ivan Weiller, wrote a nice little plugin for switching the admin themes (to
the time the error occurred, and anything you might have done that may have caused the error. More information about this error may be available in the server error log.
25
Created using zinepal.com. Go online to create your own zines or read what others have already published.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request. The client was on right path to find a solution. We need to open MySQL (usually via php MyAdmin) and find core_config_data table. Once there, manually update 2 rows: 1. config_id:3 web/unsecure/base_url www.mydomain.com/ 2. config_id:4 web/secure/base_url www.mydomain.com/ => => http:// https://
One of the projects I was assigned few weeks ago had a great amount of products, total of 46 268 to be more precise. Most of these are simple products with Visibility:Nowhere and are used strictly as Associated products in some Configurable products. Configurable products are for the most part shown to the user on frontend. All in all, there is a handful of Configurable products in the system, each holding couple of thousands Associated product. There are two issues here. First and most annoying issue I came across in this WTF configuration is the performance. Complete collapse of any reasonable execution time. Loading a page that holds this kind of Configurable product takes from 3-9 minutes, both on frontend and backend. Im talking about 3-9 minutes on local machine with maximum resource settings for PHP and MySQL. Second issue here is obvious misunderstanding of Magento product types and how to use them. I have already done Magento project with the approximately same total number of products in system. Number of products itself does not impose that much noticeable performance drop if the products are used the smart way. By smart way I think in terms where you have wast amount independent Simple products. Magento can handle that quite well. However, having large amount of relations like those Configurable Products > Associated Products can kill your store to usability equals zero. Here is where I draw the line on developers part. If you are lucky enough to get working on a new Magento related project from scratch you are obliged to recognize these kind of issues and react on time. Change the approach to the way how products need to be presented in the system and so on. It is unacceptable to create thousands of Associated products just to make them affect the final price of Configurable product. If you need to come up with solution like this, try developing a custom module to work around the issue not go with it. Performance drop is guarantied in cases like above. So if the client comes with the idea like I have a lot of products that kind of fall into the category of Configurable products that can use this and that as Associated product to stay dynamic in that and that selection you need to stop, think twice how this will affect store as whole and then propose the solution. No need to blindly go with clients (owners) suggestions. His prime wish is to get his store working and selling with least amount of budget as possible. Now lets look at the owners (clients). Ive noticed a lot of owners have special request for Magento store. Lot of them have products that kind of fit under the category of Grouped, Bundled and Configurable products. This is great actually, since all of these come out of the box in Magento. Whats not so great is that their wishes can sometimes be quite unreasonable. Lets look at the color switcher functionality lot of people ask to be implemented. This kind of functionality is mostly done by JavaScript where one hides select box that Magento would normally show under product options, and so on.
Magento site owners: Get serious, focus on what matters the most
For the last year or so I have been actively involved in online store development based on Magento ECOMMERCE platform. Everyone involved in Magento development can tell you that Magento extensively uses OOP approach. Although not everyone will agree, I like the way platform has been architectured in the backend. Layouts and config files enable you great deal of power without even writing a line of PHP code. Its not perfect, but what is. I believe most of you heard the cliche: With great power comes great responsibility. Lets discuss this in regards to Magento. There is a plain and simple message I wish to shout to current and future owners of Magento powered online stores: Get serious, focus on what matters the most!. Now what exactly did I have (and still have) in mind with statement like this? Unlike WordPress and Drupal (no offense, I use them, I respect them) not everyone can develop quality modules (extensions) for Magento. Platform itself requires developer a decent amount of knowledge from PHP OOP and other fancy object related concepts. As mentioned in one of my previous articles, Observers and overrides are among my favorite concepts (approaches) in Magento module development.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
26
We realize there are already dozens of sites related to snippets and code sharing, but none for Magento development. Site is built on Drupal CMS. There are still lot of styling left to do at the present time, but the site is usable. Branko hopes that you will not find the site too ugly since he designed it We all love the simplicity of it that makes the code snippets highly usable. What makes these code snippets special is that little drop down field next to each snippet entry where you mark down the version of Magento for which snippet has been tested for. The search functionality is planned soon. Hopefully this project will become handy in those situations where you find yourself with broken Magento code for some reason. The next step for you is to register and share a feedback. Help the community by adding your own examples of code. Here is one Snippi example:
Sure it looks great, its looks cool but the real question is How much will it improve your selling?. I realize the usability can be as much as important as functionality. By now, there are even some color switcher modules you can buy. However, most of magento modules require additional work to be properly implemented in order to fit the owners wishes. Due to the complexity of Magento platform, sometimes even the smaller changes require lot of time and effort on developer part. This would all be great and shinny if everything would work after the upgrading Magento store when the new version appears. All this leaves entire development process focused on the little things. I say, why not style the theme to the end with the default Magento page setup. Why change the output of product view page? Why not leave it default, just fully style it to match your design. This kinf of approach would be far more safer in terms of upgrades and in terms of bringing the project to the end in as much as possible short timing. What Im trying to say, Magento comes extremely feature rich out of the box. Development time is not free, and to my opinion it should be focused on either building fresh, new features for the store or at other parts of the system like Promotions, Catalog price rules, Shopping cart price rules, Customer groups. The latter one seem to be relatively ignored in the big picture. Adding features like color switcher could be left for latter phase of development, the one after the site goes live. The one you are sure your store is working the way it should, its stable, nicely styled, optimized for best performance, and quite well structured so its relatively bullet prof on updates. Then you can start adding modules, fancy usability tweaks and so on.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
27
google charts so its trying to connect to that, but everything else will work fine.
Display Promotion
There are two unused product list blocks in Magento which can be very useful if you push a few buttons, edit few layouts .. 1. Promotion Block located in app\code\core\Mage\Catalog\Block \Product\List\Promotion.php This is basically built in featured product functionality. It reacts to promotion attribute which needs to be created, so lets click Catalog->Attributes->Manage Attributes->Create New Attribute
CoffeeFreak Blank Magento extension for building main admin menu with sidebar and tabs
My previous article, CoolDash Blank Magento extension for building admin system configuration area, was about blank start-up extension for building System > Configuration admin area. I used a lot of funny attribute names so that get around gets some speed. This extension is somewhat similar to previous one, except its meant to be a blank start-up extension for building items under main admin menu with sidebar and tabs. Keep in mind that, once again, extension name is something I popped out of my head while I was making myself a coffee:). Below are two screenshots for you to see final result. In short, this extension demonstrates the use of controllers (router definition under config file) and widgets in Magento. Download Inchoo_CoffeeFreak extension for Magento. Hope you find it useful.
Attribute Code: promotion Scope: Global Catalog Input Type for Store Owner: Yes/No
Label: Promotion (second tab) Other params can be left alone, but its up to you of course. I also labeled it Promotion just for this article. Now we need to add created attribute to attribute set, so navigate to Catalog->Attributes->Manage Attribute Sets select attribute set youre using and drag promotion to General group for example.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
28
<block type="catalog/product_list_random" name="product_random" template="catalog/product/ list.phtml"/> since it also extends product_list block, however, since it is random product listing, that toolbar has no purpose here, so create phtml that will suit your shop needs, based on catalog/ product/list.phtml. For example, im using similar Random block to display random products in sidebar. So long, take care, im off
CoolDash Blank Magento extension for building admin system configuration area
Now when youre editing your products, there is new Promotion option under General tab. In order to speed things up with building admin sections under System > Configuration area in Magento I wrote a little blank extension. Hopefully its a step or two beyond Hello world level. I named the extension CoolDash, short from CoolDashboard. Name holds no special meaning, just something I popped out of my head. First thing you might notice when you open config.xmls and system.xml is the attribute naming. I intentionally used names like somecooldashmodel2. I found it extremely difficult, error prone and annoying to get around in scenarios where different areas of config files use same names for attributes with different meaning, like customer, catalog and so on. Hopefully my funny naming scheme in config files will give you a better overview on where everything goes. Below are few screenshots to see the result.
Products on which you select Yes will be shown on promotion block which can be displayed through layouts with <block type="catalog/product_list_promotion" name="product_promotion" template="catalog/product/ list.phtml"/> or as cms content with {{block type='catalog/product_list_promotion' template='catalog/product/list.phtml'}} This attribute should really be included in default attribute set or in Magento sample data. 2. Random Block located in app\code\core\Mage\Catalog\Block \Product\List\Random.php This block loads random product collection from current store. The fastest way to display it would also be something like
Created using zinepal.com. Go online to create your own zines or read what others have already published.
What we want to do is to add new functionality to that class, so lets make new module. Call it Inchoo_Wishlist. Create app/code/local/Inchoo/Wishlist/model/ directory and copy app/code/core/Mage/Wishlist/Model/Item.php there. Now, rename class Mage_Wishlist_Model_Item Inchoo_Wishlist_Model_Item. Add this line:
var_dump(get_class($this)); exit();
Its free. This one is a no-brainer, you dont need to invest any money in it. Its fast. You dont need to wait for it to be finished, you just download it and use it. It works. Most of the free Magento themes work just fine with Magento out of the box. However, truth be told, I believe the cons of having a free Magento theme give you enough reason to go for custom design: Its unprofessional. A visitor (your potential buyer) might realize youre using a free theme. This will make him wonder, can he really trust your website? Is it a real company standing behind this online store? Can I really give my credit card to these guys? They probably arent a serious company if they dont have money for the design that fits their companys identity. There might be no support. If something goes wrong, there might be no one to help you. Magento can change a lot at upgrade and some themes might start showing errors. There might be no support for new features. Magento is constantly developing ecommerce platform and new features will always be presented. Some of the free templates might not keep up with Magentos development and youll end up without the ability to use some of the cool new features that rolled out, wile your competitors with custom design will have this advantage. The free theme probably isnt really optimized for best conversion rate. Some free themes are done with conversion rates in mind, however, the conversion rate optimization usually depends on your niche and targeted audience. A design and layout that works for a certain company might not be so good in converting visitors into sales in your niche.
to
in loadByProductWishlist method Now, lets create Inchoo_Wishlist.xml in app/etc/modules/ Put this code there:
< ?xml version="1.0"?> <config> <modules> <inchoo_wishlist> <active>true</active> <codepool>local</codepool> </inchoo_wishlist> </modules> </config>
You are done! Try to add something to wishlist! =) Play with other models as well! Cheers ^_^
Created using zinepal.com. Go online to create your own zines or read what others have already published.
Unique features. Your online store is specific, you are a member of some niche. Most niches will require some additional functions that Magento doesnt support by default to make the best out of your online store. If you choose to work with experienced development company, they will be able to provide you with development solutions for your problems. This is something you cant get with free or premium Magento themes.
They determine how we will set up our method. Keyword is inchoocustom. In folder app/code/core/Mage/Shipping/etc/ we need to edit system.xml and config.xml in order to enable our new shipping method. system.xml:
public function collectRates(Mage_Shipping_Model_Rate_Request $request) <inchoocustom translate="label"> { <label>Inchoo Custom Shipping Method</la if (!$this->getConfigFlag('active')) { <frontend_type>text</frontend_type> return false; <sort_order>2</sort_order> } <show_in_default>1</show_in_default> <show_in_website>1</show_in_website> $freeBoxes = 0; <show_in_store>1</show_in_store> if ($request->getAllItems()) { <fields> foreach ($request->getAllItems() as $item) { <active translate="label"> if ($item->getFreeShipping() && !$item->getProduct()->isVirtual()) { <label>Enabled</label> $freeBoxes+=$item->getQty(); <frontend_type>select</frontend_ } <source_model>adminhtml/system_c } <sort_order>1</sort_order> } <show_in_default>1</show_in_defa $this->setFreeBoxes($freeBoxes); <show_in_website>1</show_in_webs <show_in_store>0</show_in_store> $result = Mage::getModel('shipping/rate_result'); </active> if ($this->getConfigData('type') == 'O') { // per order <name translate="label"> $shippingPrice = $this->getConfigData('price'); <label>Method name</label> } elseif ($this->getConfigData('type') == 'I') { // per item <frontend_type>text</frontend_ty $shippingPrice = ($request->getPackageQty() * $this->getConfigData('price')) - ($this->getFreeBoxes() * $ <sort_order>3</sort_order> } else { <show_in_default>1</show_in_defa $shippingPrice = false; <show_in_website>1</show_in_webs } <show_in_store>1</show_in_store> $shippingPrice = $this->getFinalPriceWithHandlingFee($shippingPrice);
</name> <price translate="label"> <label>Price</label> if ($shippingPrice !== false) { <frontend_type>text</frontend_ty $method = Mage::getModel('shipping/rate_result_method'); <sort_order>5</sort_order> <show_in_default>1</show_in_defa $method->setCarrier('inchoocustom'); <show_in_website>1</show_in_webs $method->setCarrierTitle($this->getConfigData('title')); <show_in_store>0</show_in_store> </price> $method->setMethod('inchoocustom'); <handling_type translate="label"> $method->setMethodTitle($this->getConfigData('name')); <label>Calculate Handling Fee</l <frontend_type>select</frontend_ if ($request->getFreeShipping() === true || $request->getPackageQty() == $this->getFreeBoxes()) { <source_model>shipping/source_ha
Created using zinepal.com. Go online to create your own zines or read what others have already published.
31
<sort_order>7</sort_order> </specificerrmsg> <show_in_default>1</show_in_default> </fields> <show_in_website>1</show_in_website> </inchoocustom> <show_in_store>0</show_in_store> </handling_type> config.xml: <handling_fee translate="label"> <inchoocustom> <label>Handling Fee</label> <active>0</active> <frontend_type>text</frontend_type> <sallowspecific>0</sallowspecific> <sort_order>8</sort_order> <model>shipping/carrier_inchoocustom</model> <show_in_default>1</show_in_default> <name>Inchoo Custom Shipping Method</name> <show_in_website>1</show_in_website> <price>5.00</price> <show_in_store>0</show_in_store> <title>Inchoo Custom Shipping Method</title> </handling_fee> <type>I</type> <sort_order translate="label"> <specificerrmsg>This shipping method is curr <label>Sort order</label> <handling_type>F</handling_type> <frontend_type>text</frontend_type> </inchoocustom> </sort_order><sort_order>100</sort_order> <show_in_default>1</show_in_default> Now we <show_in_website>1</show_in_website> need to enable our new shipping method in admin <show_in_store>0</show_in_store> panel (System->Configuration->Shipping Methods)
<title translate="label"> <label>Title</label> Enjoy coding. <frontend_type>text</frontend_type> <sort_order>2</sort_order> There are <show_in_default>1</show_in_default> 11 comments <show_in_website>1</show_in_website> <show_in_store>1</show_in_store> </title> <type translate="label"> <label>Type</label> <frontend_type>select</frontend_type> Latest version of Magento, as of time of this writing, is 1.3.2.3. <source_model>adminhtml/system_config_source_shipping_flatrate</source_model> <sort_order>4</sort_order> Latest, as well as previous versions come with half-packed <show_in_default>1</show_in_default>for TinyMCE editor. There are however few bugs and support <show_in_website>1</show_in_website> few steps that need to be handled in order to enable wysiwyg <show_in_store>0</show_in_store> editing in CMS pages. Personally I am not that big of a fan </type> of wysiwyg editors, mostly because I am developer and like to <sallowspecific translate="label"> <label>Ship to applicable countries</label> down. know what I write <frontend_type>select</frontend_type> However, most of the store owners are not developers or even <sort_order>90</sort_order> not that much technically savvy people (not that this is a <frontend_class>shipping-applicable-country</frontend_class> <source_model>adminhtml/system_config_source_shipping_allspecificcountries</source_model> bad thing) and they could use wysiwyg editors when adding, <show_in_default>1</show_in_default> content. modifying <show_in_website>1</show_in_website> <show_in_store>0</show_in_store> Here I will walk you trough few simple steps that will make </sallowspecific> you enable wysiwyg editing by using TinyMCE. You can see <specificcountry translate="label"> the screenshots of final result below. <label>Ship to Specific countries</label> <frontend_type>multiselect</frontend_type> Step 1: Download and unpack TinyMCE to root /js folder. <sort_order>91</sort_order> Two things to keep in mind here. Download regular version <source_model>adminhtml/system_config_source_country</source_model> (not jQuery version) of TinyMCE. This is due to the fact that <show_in_default>1</show_in_default> Magento <show_in_website>1</show_in_website> uses Prototype, so we need to avoid conflicts. Second, <show_in_store>0</show_in_store> watch out for unpack location. Your tiny_mce.js file should be </specificcountry> accessible on js/tiny_mce/tiny_mce.js path. <showmethod translate="label"> Step 2: Open the <label>Show method if not applicable</label> app/code/core/Mage/Adminhtml/Block/ <frontend_type>select</frontend_type> Cms/Page/Edit/Tab/Main.php file. Locate the <sort_order>92</sort_order> <source_model>adminhtml/system_config_source_yesno</source_model> $fieldset->addField('content', 'editor', array( <show_in_default>1</show_in_default> 'name' => 'content', <show_in_website>1</show_in_website> 'label' => Mage::helper('cms')->__('Content'), <show_in_store>0</show_in_store> 'title' => Mage::helper('cms')->__('Content'), </showmethod> 'style' => 'height:36em;', <specificerrmsg translate="label"> 'wysiwyg' => false, <label>Displayed Error Message</label> 'required' => true, <frontend_type>textarea</frontend_type> )); <sort_order>80</sort_order> <show_in_default>1</show_in_default> and change it to <show_in_website>1</show_in_website> <show_in_store>1</show_in_store> $fieldset->addField('content', 'editor', array(
Created using zinepal.com. Go online to create your own zines or read what others have already published.
32
file. If you are using store that does not have url rewrites this is something that needs to be done because your javascript file would not be found if you go trough link like http://store.local/index.php/js/tiny_mce/tiny_mce.js. Then you would get TinyMCE shown on CMS page but it would be disabled. As you can see, there were only three minor changes needed (download, modify, modify) to get the TinyMCE editor working. Hope this helps. Cheers.
As you can see, here we changed on existing attribute (wysiwyg) value and added new attribute theme. Step 3: Open the /lib/Varien/Data/Form/Element/ Editor.php file and locate the method getElementHtml(). Here we change
$html = ' <textarea name="'.$this->getName().'" title="'.$this->getTitle().'" id="'.$this->getHtmlId().'" class="textarea '.$th <script type="text/javascript"> //< ![CDATA[ /* tinyMCE.init({ I was playing with some of the Magento controller functions mode : "exact", theme : "'.$this->getTheme().'", today, when I saw my coworker Vedran Subotic struggling elements : "' . $element . '", with turning the Path hints in On and Off every few minutes. theme_advanced_toolbar_location : "top", Idea cross my mind, and here is the result Inchoos Magento theme_advanced_toolbar_align : "left", Developer Toolbar prototype. theme_advanced_path_location : "bottom", extended_valid_elements : "a[name|href|target|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|hei < ?php theme_advanced_resize_horizontal : "false", theme_advanced_resizing : "false", class Inchoo_Hints_IndexController extends Mage_Core_Control apply_source_formatting : "true", { convert_urls : "false", force_br_newlines : "true", public function init() doctype : \'< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict. { });*/ //]]> } </script>';
to
public function indexAction() { $hints = $_storeBaseUrl = str_replace('index.php', '', Mage::getBaseUrl()); $this->getRequest()->getParam('hints'); //Just to test retrieved url //echo '$_storeBaseUrl: '.$_storeBaseUrl;
$_db = Mage::getSingleton('core/resource')->getConnection('c
if($hints) { $html = ' if($hints id="'.$this->getHtmlId().'" class="textarea '.$th <textarea name="'.$this->getName().'" title="'.$this->getTitle().'" == 'on') { <script language="javascript" type="text/javascript" src="'.$_storeBaseUrl.'/js/tiny_mce/tiny_mce.js"></script> $_db->query("UPDATE core_config_data SET value = '".$_SERVER <script type="text/javascript"> $_db->query("UPDATE core_config_data SET value = 1 WHERE pat //< ![CDATA[ $_db->query("UPDATE core_config_data SET value = 1 WHERE pat Event.observe(window, "load", function() { } tinyMCE.init({ mode : "exact", if($hints == 'off') theme : "'.$this->getTheme().'", { elements : "' . $element . '", $_db->query("UPDATE core_config_data SET value = '' WHERE pa theme_advanced_toolbar_location : "top", $_db->query("UPDATE core_config_data SET value = 0 WHERE pat theme_advanced_toolbar_align : "left", $_db->query("UPDATE core_config_data SET value = 0 WHERE pat theme_advanced_path_location : "bottom", } extended_valid_elements : "a[name|href|target|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|hei } theme_advanced_resize_horizontal : "false", theme_advanced_resizing : "false", $_url = Mage::getUrl(''); apply_source_formatting : "true", convert_urls : "false", if(isset($_SERVER['HTTP_REFERER'])) $_url = $_SERVER['HTTP_R force_br_newlines : "true", doctype : \'< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict. $this->getResponse()->setRedirect($_url); }); } }); //]]> </script>'; public function cleanCacheAction() { $_url = Mage::getUrl('');
As you might noticed, I used $_storeBaseUrl in this other chunk of code to get the valid path to my TinyMCE javascript
Created using zinepal.com. Go online to create your own zines or read what others have already published.
33
the WordPress and Magento. Probably everyone in web development has heard about WordPress. Personaly I like them, from Joomla, Drupal, Wordpress But there is that $this->getResponse()->setRedirect($_url); little something that makes WordPress far more loving in the } eyes of the client. Not to start a flame here, lets get back to public function cleanPhotoCacheAction() the topic. Due to the lack of the proper content management { in Magento those who use WordPress can easily manage the $_url = Mage::getUrl(''); (home page in this case) content trough WordPress and make it accessible in if(isset($_SERVER['HTTP_REFERER'])) $_url = $_SERVER['HTTP_REFERER']; Magento CMS page (that you can set to home page in Magento).
try { Mage::getModel('catalog/product_image')->clearCache(); } catch (Exception $e) { } $this->getResponse()->setRedirect($_url); } } < ?php //START INCHOO DEVELOPER TOOLBAR ?>
When would you like to do so? Imagine you have Magento installed in root of your site and WordPress under some folder like /articles. By default WordPress is accessed via http://mysite.domain/articles and Magento is accessed trough http://mysite.domain. Our goal is to have WordPress Page (that we will title home) to be accessible on http://mysite.domain. Here are the necessary steps involved:
< ?php $_inchoo_db = Mage::getSingleton('core/resource')->getConnection('core_write'); page named home (under url like Create a WordPress $hints_are_on = $_inchoo_db->fetchOne("SELECT value FROM core_config_data WHERE path = 'dev/debug/template_hints'"); http://mysite.domain/articles/wp-content) ?>
<div style="line-height: 24px; font-size: 10px; font-family: Arial, Verdana; background: #004400; border-bottom:solid design/frontend/default/ <div> yourtheme_or_default_theme/template/inchoo/ <span style="font-weight: bold; margin-right: 10px; margin-left: 10px;">INCHOO TOOLBAR</span> folder < ?php if($hints_are_on): ?> <a style="text-decoration: none; color: #bbbbbb;" href="<?php Create $this->getUrl('inchoohints/index/index/hints/off') echo a Magento CMS page (if it already does < ?php else: ?> not exist) name it anyway you want and then <a style="text-decoration: none; color: #bbbbbb;" href="<?php echo $this->getUrl('inchoohints/index/index/hints/on') add {{block type=core/template template=inchoo/ < ?php endif; ?>
<a style="text-decoration: none; color: #bbbbbb;" href="<?php echo $this->getUrl('inchoohints/index/cleanCache') ?>"> echo $this->getUrl('inchoohints/index/cleanPhotoCache') <a style="text-decoration: none; color: #bbbbbb;" href="<?php Set the newly created Magento CMS page as home page for Magento under Magento Admin System > </div> </div> Configuration > Web > Default Pages > CMS Home Page < ?php //END INCHOO DEVELOPER TOOLBAR ?> < ?xml version="1.0"?> <config> <modules> <inchoo_hints> <version>1.0.0</version> </inchoo_hints> </modules> <frontend> <routers> <ihints> <use>standard</use> <args> <module>Inchoo_Hints</module> <frontname>inchoohints</frontname> </args> </ihints> </routers> </frontend> </config>
Below is the code you need to copy paste into the cmswp_home.phtml file mentioned in above steps.
< ?php
/** * Pulls the content of post named 'home' from WordPress 'wp_ * @author Branko Ajzele * @license GPL */
//Set query that retrieves the home page content //THIS GOES IF YOU HAVE WORDPRESS AND MAGENTO IN SAME DATABS $_findHomePage = "SELECT post_content FROM wp_posts WHERE po
//Set default value of home page to null, then do a safe che $_homePageContent = null;
How to use WordPress home page in Magento home page (CMS page)
Simple : ) -Ok, lets get down to business. This one is really, really simple, but powerful. In all it greatness Magento lacks the good content management solution (CMS features). Lot of people are heading down the road of integrating
try { /* //IF YOU HAVE WORDPRESS AND MAGENTO INSTALLED EACH IN ITS OW $conf = array( 'host' => 'localhost', 'username' => 'wordpress_db_username', 'password' => 'wordpress_db_password', 'dbname' => 'wordpress_db_name' );
Created using zinepal.com. Go online to create your own zines or read what others have already published.
34
$_resource = Mage::getSingleton('core/resource'); visitors are able to subscribe to your newsletter via Magento //Create new connection to new server and new databse Newsletter subscription form in sidebar. $_conn = $_resource->createConnection('place_some_free_random_resource_name_here', 'pdo_mysql', $conf); */ Besides newsletter subscribers, all of your stores registered $_homePageContent = $_conn->fetchOne($_findHomePage); } catch (Exception $ex) { //SEND EXCEPTION INFO TO ADMIN?
users will also appear in your Magentos newsletter e-mail database. This database also contains information on different store views, allowing you to easily send multiple variations of your newsletter to different store view subscribers. This feature is extremely useful when dealing with multiple language web shops.
/* * USE $emailSmtpConf, $transport and $mail->send($transport); in case you need to specify SMTP manualy $emailSmtpConf = array( Newsletter Template: 'auth' => 'login', The process of sending out Magento Newsletter starts 'ssl' => 'tls', 'username' => 'some_email@gmail.com', with creation of Newsletter Template. Once you create this 'password' => 'some_pass_here' template, the template will remain there even after you send );
your newsletter to subscribers, allowing you to change it and use it multiple times. $transport = new Zend_Mail_Transport_Smtp('smtp.gmail.com', $emailSmtpConf); You can create multiple newsletter */ templates with different styling and test them to see which one attracts the most response from subscribers.
$_sendTo_email = 'ajzele@somemail.com'; $_sendFrom_email = 'branko.ajzele@somemail.com';
//Notify each item author about purchase $mail = new Zend_Mail(); $mail->addTo($_sendTo_email, 'Branko Ajzele'); $mail->setFrom($_sendFrom_email, 'Branko Ajzele'); $mail->setSubject('Invalid HOME PAGE on site detected'); Simply click on Add new template button on the right and $mail->setBodyHtml(' <h1>Invalid HOME PAGE on site detected</h1> start creating your first newsletter template. You will see a <p>There seem to be some issues with home page on your site. Please5 take aAll of the fields are required. You will also screen with fields. look at it.</p> <p>Could be that WordPress page has been disabled and this made the query for page return null.</p> notice that the largest field (Template content field) already '); has some sort of code inside. Do not remove this code. This try { //Try to send email code will generate the unsubscribe link for your newsletter. //$mail->send($transport); Make sure that whatever you do this code remains on the $mail->send(); bottom. } catch (Exception $ex) { When creating newsletter template for Magento, note that //echo $ex->getMessage(); you can actually use HTML in it. This means that if youre } } ?>
< ?php if($_homePageContent): ?> < ?php echo $_homePageContent ?> Newsletter Queue: < ?php else: ?> If you open this tab in the newsletter top menu, you will <h1>Home page unavailable</h1> <p>Seems like home page is unavailable at the moment. We notice that for the inconvenience.</p> queue. In order to apologize there are no newsletters in < ?php endif; ?> queue a newsletter you need to open Newsletter Template
not a tech savvy person, you can simply use some WYSIWYG editor and copy / paste the code it creates into your newsletter template once youre done. In addition, if you wish to have WYSWYG editor inside your magento, check out our article on how to use TinyMCE with Magento.
Thats it. If you wish to have more control over what is outputted take a look $_findHomePage variable and the query behind it. Hope you find this useful. Cheers.
screen once again and in the action box next to your template choose Queue Newsletter. This action will bring up the Edit Newsletter screen. Notice that you can choose which store view subscribers are going to receive the newsletter. To select multiple store views, hold Ctrl key and left click on store views you wish to use. (this will only be necessary if youre using more then one store view).
Magento Newsletter
If youre using Magento you probably noticed by now that you have integrated newsletter system with it. By default,
Created using zinepal.com. Go online to create your own zines or read what others have already published. 35
You also need to set a Queue date start. Notices that the date and time you set are in fact server date and time, not your date and time. If you wish to send your newsletter immediately, you need to set it to your current server date and time or set it into past. Newsletter Subscribers Export: If you wish to use some other service for sending your newsletter you can easily export your Magento newsletter subscribers via admin panel. Access the Newsletter Subscribers screen via top menu. On the top right you will see select box with options to export your newsletter subscribers in form of CSV or XML. Export it in a form that best fits the import options of your other newsletter solution. Cant send Magento newsletter? Here are some common problems: Your server time is different then your local time and youve actually queued the newsletter to be sent a few hours in future and thats why its not sent right now. Magento sent only small part of emails? Dont worry, it will send them out. Magento has integrated limit on the number of emails it can send at once. Eventually, all of your emails will be sent. You might need to activate your cron job as its often a case cron job is causing you problem. This means you will need to visit this address insertyour-magento-store.com/cron.php manually with your internet browser.
and we dont want SIDs to appear to those visitors. Most important: We dont want that search engines index the URLs with SIDs.
2. Open the Authorize.net module and update the title as you see fit. Enter your NaviGate username and transaction key, which you generate under Profile & Settings in the NaviGate interface. 3. Change the Gateway URL to: https:// gateway.merchantplus.com/cgi-bin/PAWebClient.cgi 4. Enable Credit Card Verification, if you want to use the CVV code. 5. Then, go to your source code and open the file: /app/ code/core/Mage/Paygate/Model and find the string setCardCodeResponseCode . Change the line to: >setCardCodeResponseCode($r[38]); Save the file and you should be good! To assist your integration, MerchantPlus created the following developer tools (you will not need them in our case): For more information on the connection Authorize.nets AIM documentation. API, see
Created using zinepal.com. Go online to create your own zines or read what others have already published.
36
amfPoint is a Magento Extension that enables you to serve interactive flash widgets containing your products wherever and whenever you need them on your Magento store.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
37
mediaDirective htmlescapeDirective storeDirective blockDirective layoutDirective Ill start with easier and most commonly used and continue with advanced ones in part two of this article. 1. skinDirective Description: Used to retrieve path of skin folder and its files, theme fallback respected Example: {{skin url=images/image.jpg _theme=blank}} Synonym: $params) Params: url = empty or relative file path _theme = alternative theme, fallbacks if file not exist _package = alternative package _area = alternative area(frontend,adminhtml) _type, _default etc. = nothing useful, somebody please correct me if im wrong 2. mediaDirective Description: Used to retrieve path of root/media folder and its files Example: {{media url=image.jpg}} Synonym: Mage::getBaseUrl(media) . $params['url'] Params: url = empty or relative file path 3. htmlescapeDirective Description: Used to escape special html chars Example: {{htmlescape href=www.inchoo.net>inchoo</a><b>inchoo</ b><i>inchoo</i> allowed_tags=b'}} var=<a Mage::getDesign()->getSkinUrl($params['url'],
Example: {{store url=customer/account _query_a=8}} Synonym: Mage::getUrl($params['url'], $params); Params: url = magento routers url direct_url = normal url, appended to baseurl _query_PARAMNAME = adds query param, for example _query_a=8 adds a=8 to url _fragment = adds fragment, for example #comments _escape = escapes ,,<,> custom = if using magento route url param, every custom param added will be appended like /a/8/b/10 I probably missed something in this last one, but its very late and im tired of poking through Magento To be continued ..
Magento FLIR
Facelift Image Replacement (or FLIR, pronounced fleer) is an image replacement script that dynamically generates image representations of text on your web page in fonts that otherwise might not be visible to your visitors. Lets see how it behaves in Magento. 1. Download FLIR from FLIR homepage. I was using latest 1.2 stable for this article because of simplicity, but if you try youll find out that 2.0 beta also works great but requires little more configuration. 2. Unpack FLIR content (cache,fonts,etc.) inside skin/ frontend/default/default/facelift I think it makes perfect sense to put it into skin folder. 3. Open app/design/frontend/yourpackage/yourtheme/ template/page/html/head.phtml and append <script language=javascript src=<?php >getSkinUrl(facelift/flir.js) ?>></script> <script type=text/javascript> document.observe(dom:loaded, function() { FLIR.init({ path: <?php echo $this->getSkinUrl(facelift/) ? > }, new FLIRStyle({ mode: wrap }) ); FLIR.auto(); }); </script> If your php error reporting isnt disabled add error_reporting(0); somewhere on top of config-flir.php. This echo $this-
Synonym: Mage::helper(core)->htmlEscape($params['var'], $params['allowed_tags']) Params: var = string to escape allowed_tags = comma-separated list of allowed tags 4. storeDirective Description: Used to build magento routes and custom urls
Created using zinepal.com. Go online to create your own zines or read what others have already published.
38
is main config file from which you can define options and custom fonts, so examine it. Refresh your Magento store and you should see the result. flir.js can also be alternatively included from layout files inside head block <reference name=head> <action method=addItem><type>skin_js</ type><name>facelift/flir.js</name></action> </reference> There is nice Quick Start Guide and Documentation available from FLIR homepage, so i wont go in details on some advanced FLIR settings, but here are few examples: //pass selectors as comma separated list FLIR.auto(h5,h4); //pass an array of selectors FLIR.auto( [ 'h4', 'h5' ] ); //replace manually with custom options FLIR.replace( div.box h4 , new FLIRStyle({ mode: wrap , css: {font-family:'arial} }) ); //prototype way $$(div.box h4).each( function(el) { FLIR.replace(el); } ); Cya.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
39
All of those and more are questions that one has to take into consideration when doing raw database queries. It makes no sense to create query that fetches product and all its public function indexAction() { appropriate info (price, quantity, description) if that product //Get current layout state is disabled or assigned to category that is disabled. For $this->loadLayout(); instance, if you need featured product functionality and you manually create raw query that extracts one featured $block = $this->getLayout()->createBlock( product to lets say home page. There you create nice block 'Mage_Core_Block_Template', 'my_block_name_here', holding all the necessary info of the product with a link for lets array('template' => 'activecodeline/developer.phtml') say Add to cart or View product. Clicking one of those two ); link would give you most likely 404 if the product is disable $this->getLayout()->getBlock('content')->append($block); or any other condition that enables the product to be shown is disabled.
//Release layout stream... lol... sounds fancy $this->renderLayout(); }
Most IMPORTANT thing to keep in mind here is the error handling. If you assign a invalid block to ->append(), you will not (most likely) see an error but nothing happend situation. Anyhow hope the attached module (extension) will save you some headaches. I know it took me few hours of tracing and testing to get the grip of it. Download ActiveCodeline_CustomOutputs extension. Cheers.
So basically, raw SQL queries in Magento are a no no for most of the time. Too much work and you never know what they will change in future upgrades. Which brings me to this new trend of theirs which I like to call Escape from EAV.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
40
custom script I wrote. After that i noticed the data in flat tables got rebuild as well. This of course took several hours. Magento EAV model seems OK on paper, but with store that holds large number of products it simply does not work, at least not in way in which their collection objects are built. Changes introduced in form of flat tables in versions 1.3 should, to some extent, improve work with stores that have large numbers of products. However this improvement seems to come in form of copy all data from scattered tables to single flat table. Solutions like these are nightmare when it comes to upgrading the store that already has large number of products in. System is expected to handle part of the job transparently but it failed, leaving the client with corrupted database. So, a word of advice for upgrading an existing Magento store: NEVER do it on live site. Let professional developer transfer live site and database to his dev machine, or make a copy on some sub folder on live site. Magentos extreme out of the box feature rich capabilities, open source philosophy and good marketing have made it extremely popular but be careful, free is such a a loose term. I am really anxious to see the future path of EAV vs Flat model in Magento. EAV, also know as Entity Attribute Value was suppose to bee (or is) the next big thing in OOP. Anyhow, Magento and his way of EAV have two huge downfalls called LACK OF DOCUMENTATION and WHAT WILL THEY CHANGE IN NEXT UPGRADE. The other day I was working on a Magento shop that had 22 000 products. Almost all of them were simple products, just about 600 were grouped. The store was initially installed on Magento 1.2 version. Site was pretty much 95% complete from both graphic and development perspective. Anyhow, Magento version 1.3.1 was released and on client demand we decide to to upgrade. Important thing to keep in mind is that in version 1.3 Magento introduce change in philosophy concerning the EAV model. Altough EAV sounds great (and really is great for most of the time), it can really slow things down with all those JOINS executed on database. So the Magento team decided to do a little flat tabling. Basically we now have massive data duplication in MySQL where data is taken from various tables and copied int one, the flat table. Flat tables were introduced for both Products and categories, in regards to various website and store views. Basically Magento has the power to on the fly create tables and do the magical copying of data from various tables to the flat tables. I assume they were looking for a faster way to assemble Product objects in Magento which in turn should boost the speed of collection object i grew so found about. I can live with duplicated data in database, I mean I am not the one writing them down. But let me get back to real world scenario. As I mentioned, store I have been working on had more than 20 000 products. Due to limitations of both MySQL and PHP failed to do Rebuilt that you can find in System > Configuration > Cache management. This failure caused corrupted data in database. This manifested with empty attributes (attributes not showing up in Layered navigation). I resolved the issue by re saving all of the 20 000 product with
< ?php if($this->getProduct()->isConfigurable()){ $_product = Mage::getModel('catalog/product')->load($this->g Mage::getBlockSingleton('catalog/product_view_type_configura $_configurable = Mage::getBlockSingleton('catalog/product_vi $_cdata = json_decode($_configurable->getJsonConfig()); $_current = array(); foreach((array)$this->getOptionList() as $_option) { $_current[$_option['label']]=$_option['value']; } foreach($_cdata->attributes as $attribute) { ?> <strong>< ?php echo $attribute->label; ?></strong> <select style="width:150px;" name="cart[<?php echo $_item->g < ?php foreach($attribute->options as $option) { ?> <option <?php echo ($_current[$attribute->label]==$option->l < ?php } ?> </select> < ?php } } else { // THIS IS PLACE WHERE EXISTING CODE from [*] goes } ?>
Now you are done with template and you can style it as you wish as soon as you do few additional steps.
< ?php class YOUR_FIRM_MODULE_NAME_Model_Card { public function update($e)
Created using zinepal.com. Go online to create your own zines or read what others have already published.
41
* The best part * Opens the activecodeline_custom_email1.html, throws in th if (!$item) continue; * and returns the 'parsed' content that you can use as body if (!isset($itemInfo['option']) or empty($itemInfo['option'])) continue; */ $processedTemplate = $emailTemplate->getProcessedTemplate($e foreach ($item->getOptions() as $option){ if($option->getCode()=='info_buyRequest'){ $unserialized = unserialize($option->getValue()); $unserialized['super_attribute'] = $itemInfo['option']; $option->setValue(serialize($itemInfo['option'])); }elseif ($option->getCode()=='attributes'){ $option->setValue(serialize($itemInfo['option'])); } } $item->save(); } } } ?>
/* * Or you can send the email directly, * note getProcessedTemplate is called inside send() */ $emailTemplate->send('john@someemail.com','John Doe', $email ...
And here we go again, nothing without xml files -In order for above piece of code to work, you need to add an entry to your config.xml file like shown below.
... <global> <template> <email> <custom_email_template1 module="SampleModule1"> <label>ActiveCodeline custom email module</label> <file>activecodeline_custom_email1.html</file> <type>html</type> </custom_email_template1> </email> </template> </global> ...
P.S. Yes, I know before clicking on update cart, we should have some JavaScript price changer, but this is all I have at this moment since I needed this on card that is autosubmited on dropdown change.
And lets not forget the email template itself, app/locale/ en_US/template/email/ activecodeline_custom_email1.html.
<!--@subject ActiveCodeline custom email module @-->
<div> <h1>ActiveCodeline custom email example by Branko Ajzele</h1 <p>Hi there {{var myvar1}} {{var myvar2}} from {{var myvar3} </div>
Due to the complexity of Magentos xml files, developers can waste great amount of time on unnecessary things. When I say complexity I say it with purpose. XML files are not so complex by them selves, but due to extreme lack of Here is how. documentation and changes Magento pumps in every new ... major release, people are lost among things that should /* really be sideways. Anyway, in this little article I will show you * Loads the html file named 'custom_email_template1.html' from how to create basic, startup structure for your module to get it * app/locale/en_US/template/email/activecodeline_custom_email1.html shown under Magento Admin main top menu. */
$emailTemplate = Mage::getModel('core/email_template') ->loadDefault('custom_email_template1'); //Create an array of variables to assign to template $emailTemplateVariables = array();
As you can see on the picture below, I am creating a menu item with title ActiveCodeline_SampleModule1.
Created using zinepal.com. Go online to create your own zines or read what others have already published.
42
My module is called SampleModule1 and it consists of just a few files. As you go over the provided config.xml file you will see that I used BigLettersSmallLetters style. I do this intentionally because this naming convention is another great pitfall for developers when it comes to constructing xml files. I know I too still struggle with what must be the lowercase question. Here is my example of config.xml file
< ?xml version="1.0"?> <config> <modules> <activecodeline_samplemodule1> <version>0.1.0</version> </activecodeline_samplemodule1> </modules> <global>
My admin controller is extremely simple, just an indexAction() method. However it does tell a lot. Below is a code of indexAction() method.
... public function indexAction() { // "Fetch" display $this->loadLayout();
// "Inject" into display // THe below example will not actualy show anything sinc $this->_addContent($this->getLayout()->createBlock('core // echo "Hello developer..."; // "Output" display $this->renderLayout();
} <helpers> ... <samplemodule1> <class>ActiveCodeline_SampleModule1_Helper</class> are all the files required for this Admin And below </samplemodule1> module to work. </helpers> </global> Note this is only example, DO NOT USE on live site.
example
Cheers <admin> <routers> There are 2 comments <samplemodule1> <use>admin</use> <args> <module>ActiveCodeline_SampleModule1</module> <frontname>samplemodule1</frontname> </args> </samplemodule1> I have been working on a project, in my own time, that involves </routers> </admin> Flex Magento communication. I decided to test Adobes
<adminhtml> AMF server as an extension in Magento. <menu> <menu1 translate="title" module="SampleModule1"> So, where to we start? <title>ActiveCodeline SampleModule1</title> <sort_order>60</sort_order> The idea is to have special Url which will act as AMF endpoint. <children> Since Magento is built on top of Zend, this is extremely easy <menuitem1 module="SampleModule1"> to do. <title>Menu item 1</title> <action>samplemodule1/example</action> For your module to act as a basic AMF server you need </menuitem1> only 3 files. MyCompany_MyModule.xml that goes under </children> the /app/etc/modules/ folder. Then IndexController.php that </menu1> goes under the /app/code/local/MyCompany/MyModule/ </menu> controllers/IndexController.php. And last but not least <acl> <resources> the config.xml file that goes under the /app/code/local/ <admin> MyCompany/MyModule/etc/ folder. <children> <menu1 translate="title" module="SampleModule1"> I will not go into the details and show you the full <title>ActiveCodeline SampleModule1</title> content of each of those files. Important thing is to focus <sort_order>60</sort_order> on IndexController.php and config.xml files. Inside your <children> IndexController.php file you will actualy hold the code for your <menuitem1> AMF server (Zend_Amf). <title>Menu item 1</title> </menuitem1> Here is an example of indexAction from my </children> IndexController.php file: </menu1> </children> </admin> ... </resources> public function indexAction() </acl> { </adminhtml> //Create AMF server instance
AMF format. In this article I will show you how easy is to create
Created using zinepal.com. Go online to create your own zines or read what others have already published.
43
develop a feature for Magento than for some other system out there.
//$server->setClassMap("SomeTypedObjectVO", "MyCompany_MyModule_Model_SomeTypedObjectVO"); site which had usual problem of slow $server->setClassMap($className, $class); //Run the AMF server echo $server->handle();
//Just in case so that Magento does not pass anything beyond this point Magento has built in predifined system of block output die; caching. Its block abstract has Zend_Cache caching } capabilities that can be modified for your own needs. Im ...
The above example is the simplest form of Zend AMF server i can think of, but it should be enough to get your AMF server responsive to AMF requests. And to make all of this accessible via Url, we need to add entry to congig.xml file. Below is the partial example of my config.xml file.
... <frontend> <routers> <mymodule> <use>standard</use> <args> <module>MyCompany_MyModule</module> <frontname>myamfserver</frontname> </args> </mymodule> </routers> </frontend> ...
showing here an example of caching whole product view block, however this is just a specific example of how things works, problems are different and requires different approach and solution. I will start with some external reading and example itself. There is great article on Magento Wiki about this topic, along with category cache example on Magento forums. With my Inchoo_BlockCaching.rar example module things should be little easier to understand. Magento block caching depends of three things: cache_lifetime => cache lifetime in seconds cache_tags => cache type identifiers primarly used for deleting right cache at the right time cache_key => cache identyfier You can simply inject this data into construtor of any Magento block
Above piece of code sets access to AMF server on Url like http://server/store/index.php/myamfserver. Thats it.
protected function _construct() { $this->addData(array( 'cache_lifetime' => 3600, 'cache_tags' => array(Mage_Catalog_Model_Product::CACHE_ 'cache_key' => $this->getProduct()->getId(), )); }
or if you need some conditional approach like i did in this example define equivalent functions
public function getCacheKey(){} public function getCacheLifetime(){} public function getCacheTags(){}
because constructor approach isnt enough in most scenarios. There is a general misassumption about cache_lifetime. If you set it to false, Zend cache will get default value of 7200 seconds!! If you want infinite never expired cache set it to 9999999999, which is Zend_Cache maximum value, or something else big enough. I believe that best way to activate this is to rewrite specific block with our own with caching enabled, like shown in example. You should always try to avoid modifying core files, even copying modified Mage classes to local, because things get really messy on updates.
44
Created using zinepal.com. Go online to create your own zines or read what others have already published.
Generated cached files can be found in usual subfolders of / var/cache folder. Two files are generated, first metadata file which contains serialized cache data and second one which is cached html output itself. In my example: mageinternal-metadatasPRODUCT_INFO_STORE +ID_PRODUCT+ID magePRODUCT_INFO_STORE+ID_PRODUCT+ID Note that Blocks HTML output option needs to be enabled in Cache Management for this to work. Many things in Magento can be cached in similar way and there are predefined mechanism waiting for you to use them. Its possible that well see more of this implemented in future Magento versions.
Thats it. You should now be free of product comparison for ever and ever
This issue is also easily fixed by use of rel canonical. Simply put a rel cannonical on all of the products with SID in URL, pointing back name="right.reports.product.viewed" template="r <block type="reports/product_viewed" before="right.permanent.callout"to the products original URL. Step 2 catalog.xml Open app/design/frontend/deafult/Your Theme layout/catalog.xml and delete the following line: name/
Save the files and refresh the page you were checking. Product comparison should not be there but if you click on any of the products you ll see that the Add to compare text link is still there. The way to remove it: Step 3 addto.phtml Open up app/design/frontend/default/Your Theme name/ template/catalog/product/view/addto.phtml and delete the following line:
< ?php if($_compareUrl=$this->helper('catalog/product_compare')->getAddUrl($_product) ): ?> <li><span class="pipe">|</span> <a href="<?php echo $_compareUrl ?>">< ?php echo $this->__('Add to Compare') ?></a></ < ?php endif; ?>
Oh, of course theif you dont want to actually delete the code can always use the following:
Created using zinepal.com. Go online to create your own zines or read what others have already published. 45