Preventing your site from being indexed, the right way

Magento

It keeps amazing me that I keep seeing people use robots.txt files to prevent sites from being indexed and thus showing up in the search engines. You know why it keeps amazing me? Because robots.txt doesn’t actually do the latter, even though it does prevent your site from being indexed.

Let’s go through some terms here:

Indexed / Indexing
The process of downloading a site or a page’s content to the server of the search engine, thereby adding it to it’s “index”.

Ranking / Listing / Showing
Showing a site in the search result pages (aka SERPs).

So, while the most common process goes from Indexing to Listing, a site doesn’t have to be indexed to be listed. If a link points at a page, domain or wherever, that link will be followed. If the robots.txt on that domain prevents the search engine from indexing that page, it’ll still show the URL in the results if it can gather from other variables that it might be worth looking at.

How to add quantity box on product listing page in magento

Magento

To add quantity box on Product Listing Page you need to edit app/design/frontend/default/YourTheme/template/catalog/product/list.phtml file

Find the below given line

1
<button type="button" title="<?php echo $this->__('Add to Cart') ?>" onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>

And just replace it with,

1
2
3
4
5
6
7
<form action="<?php echo $this->getAddToCartUrl($_product) ?>" method="post" id="product_addtocart_form_<?php echo $_product->getId()?>"<?php if($_product->getOptions()): ?> enctype="multipart/form-data"<?php endif; ?>>
 <?php if(!$_product->isGrouped()): ?>
 <label for="qty"><?php echo $this->__('Qty') ?>:</label>
 <input type="text" name="qty" id="qty" maxlength="12" value="<?php echo ($this->getMinimalQty($_product)?$this->getMinimalQty($_product):1) ?>" />
 <?php endif; ?>
 <button type="button" onclick="this.form.submit()"><span><span><span><?php echo $this->__('Add to Cart') ?></span></span></span></button>
 </form>

Working with ajax in magento

Magento

Ajax in Magento can be pretty troublesome.Because you will need to take controllers and layout into account.And I almost used up a whole day trying to make ajax work. Here are some of the steps I’d like to share so that you will not waste lots of your time, before making this work :D .

[UPDATE]
New Module in Magento connect out to help you working in Ajax.

Let’s first know in Magento terms what we need.

Controller: The url on which Ajax will work on, or the request URL. You will have to set up the controller with its frontend router set in config.xml and its corresponding controller class.
Layout: Layout to handle the requested URL and return HTML if required.
Block: The block to call through layout for the above controller.

Now lets be descriptive.

If you want to show a loader while request is being processed just add the following whereever you like in the phtml page.First fetch the Javascript.

1
<script src="<?php echo $this->getJsUrl() ?>mage/adminhtml/loader.js" type="text/javascript"></script>

Then echo the loader which pops up. This loader will be similar to that of the admin.

1
2
3
4
<div id="loadingmask" style="display: none;">
<div class="loader" id="loading-mask-loader"><img src="<?php echo str_replace("index.php/","",$this->getUrl()) ?>skin/adminhtml/default/default/images/ajax-loader-tr.gif" alt="<?php echo $this->__('Loading...') ?>"/><?php echo $this->__('Loading...') ?></div>
<div id="loading-mask"></div>
</div>

Now to Call Ajax, use the following lines

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*Please note that the URL is created in reloadurl. Also see that the response text will be echoed in div with id=output-div*/
var reloadurl = '<?php echo $this->getUrl('router/controller/action') ?>';
Element.show('loadingmask');
new Ajax.Request(reloadurl, {
method: 'post',
parameters: "Params_Here",
onComplete: function(transport) {
Element.hide('loadingmask');
$('output-div').innerHTML = "";
$('output-div').innerHTML = transport.responseText;
}
});

After the Ajax Request is made it goes to your controller’s action, which in turn sees to your layout as follows:

1
2
3
4
5
6
class Namespace_module_frontendController extends Mage_Core_Controller_Front_Action
{
public function actionAction(){
$this->loadLayout()->renderLayout();
}
}

And here is the main part in layout where I spent most of my time in. Since in layout we will have to define reference where the html will echo (Most of the times), i got stuck here, because i need to echo the output on the div with id output-div not in any reference.And the trick is to name the layout as root and output as html. Like the following:

1
2
3
<module_controller_action>
<block type="module/block"  name="root" output="toHtml"  template="module/template.phtml"/>
</module_controller_action>

You are done now! What ever you write or echo in phtml file you will see populated in the DIV. Now you can treat block as normally as you do before.

Happy Coding!!

Referece: http://subesh.com.np/2009/11/working-with-ajax-in-magento/

Creating wholesale solution with magento commerce

Magento

The client want to have a shop where regular customers to be able to see products with their retail price, while Wholesale partners to see the prices with ? discount. The extra condition: retail and wholesale prices hasn’t mathematical dependency. So, a product could be $100 for retail and $50 for whole sale and another one could be $60 retail and $50 wholesale. And of course retail users should not be able to see wholesale prices at all.

Basically, I will explain what I did step-by-step, but in order to understand what I mean, you should be familiar with the basics of Magento.

1. Creating two magento websites, stores and views
(Magento meaning of website of course) It’s done from from System->Manage Stores. The result is:
Website | Store | View
————————————————
Retail->Retail->Default
Wholesale->Wholesale->Default

Both sites using the same category/product tree

2. Setting the price scope
in System->Configuration->Catalog->Catalog->Price set drop-down to Website. Now you could enter prices per store/website and they could be totally different.

3. Get some plugins
Get following plugins from Magento Connect and install them from admin: System->Magento Connect->Magento Connect Manager:
Netzarbeiter_LoginCatalog – User need to login in order to see the store (it will be used for Wholesale site)
Netzarbeiter_CustomerActivation – User need to be approved from site admins in order to be able to login to the site. (again it will be used for wholesale site)

Both plugins need to be activated for wholesale only. Because they are activated when they are installed, you need to disable them for Default/Retail website and to leave enabled to Wholesale. You should know that distinction between sites in System->Configuration is done from top left corner of the config window.

First plugin is enabled/disabled from: System > Configuration > Catalog > Login only catalog
Second one: System > Configuration > Customer > Customer Activation.

4. Setting separate url for Wholesale
Now wholesales need to have separate urls, so regular users will access http://domain.com/, while wholesale will access http://domain.com/wholesale/. I found this solution in the Magento Forum: Thread.

So, following the instructions I created directory wholesale/ and copied .htaccess and index.php files from the root directory. Modifications in the index.php are the same as in the Forum:
Mage::run(); become Mage::run(‘wholesale’);
and
$mageFilename = ‘app/Mage.php’; become $mageFilename = ‘../app/Mage.php’;

5. Change the wholesale paths from the admin
From System->Configuration (select Wholesale website)->General->Web and change the paths by adding wholesale/ (it’s also mentioned in the forum thread).

6. Adding products to both websites
When adding products, you should mark them visible for both sites. This is done from Product page->Websites tab.

That’s it! Now on http://domain.com/ users will see full catalog, they can login without Admin approval and prices will be retail, while on http://domain.com/wholesale only users registered as wholesale and activated from admin will be able to see catalog with wholesale prices.

What’s left…

And this was the easiest part … the rest is to import about 2000 products from the current osCommerce store, and to add another 4000 from the client’s ERP system. After this on regular basis to update prices and quantities from ERP system.

Hopefully this will help someone.

Access denied in Magento admin

Magento

Access denied in Magento admin

30 September 2009 No Comment

Access denied in Magento admin

Some of you may encountered this problem. You install new Magento extension through downloader, try to access its configuration settings and Magento throws “Access denied” page at you. Although you’re administrator of the system.

 

access-denied-in-magento-admin-1

So what happened here? Magento just doesn’t have stored privileges for this new extension.

First just try to logout and login again. If that doesn’t work, you need to reset admin privileges.

Navigate to System->Permissions->Roles and click Administrators role.

access-denied-in-magento-admin-2

Check your Role Resources settings just in case, Resource Access dropdown should be already set to All for administrators.

access-denied-in-magento-admin-3

Without changing anything just click “Save Role” button, so that Magento re-saves all permissions.

You should be able to access your new extension now without problems.

Create An External Database Connection in Magento

Magento

Creating The Connection

To create your connection, create a custom module and add the following to your config.xml. The code below is the bare minimum needed to get the external database connection working.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?xml version="1.0"?>
<config>
    <modules>
        <Fishpig_Externaldb>
            <version>0.1.0</version>
        </Fishpig_Externaldb>
    </modules>
    <global>
        <resources>
            <externaldb_write>
                <connection>
                    <use>externaldb_database</use>
                </connection>
            </externaldb_write>
            <externaldb_read>
                <connection>
                    <use>externaldb_database</use>
                </connection>
            </externaldb_read>
            <externaldb_setup>
                <connection>
                    <use>core_setup</use>
                </connection>
            </externaldb_setup>
            <externaldb_database>
                <connection>
                    <host><![CDATA[localhost]]></host>
                    <username><![CDATA[db_username]]></username>
                    <password><![CDATA[db_password]]></password>
                    <dbname><![CDATA[db_name]]></dbname>
                    <model>mysql4</model>
                    <type>pdo_mysql</type>
                    <active>1</active>
                </connection>
            </externaldb_database>
        </resources>
    </global>
</config>

Clear the cache after creating your module and from now on, each time you load Magento, a second database connection will be created

Accessing The Database

When I initially found out how to create an external database connection, I was using Zend_Db to retrieve all of my information. You can use the following to test your database connection is working:

1
2
3
4
5
6
7
<?php
    $resource   = Mage::getSingleton('core/resource');
    $conn       = $resource->getConnection('externaldb_read');
    $results    = $conn->query('SELECT * FROM tblName');
    print_r($results)

This works fine, however kind of takes the point away from having this connection available in Magento.

Accessing The External Database Using Models

Using models to access the database keeps our code style uniform throughout Magento. Also, it means we can integrate any other CMS or database driven application without learning it’s coding practices. To achieve this, simply add models to your custom module like you would for any other module.

I will attempt to demonstrate how to set up the models and config.xml files now. For this example I will pretend I am integrating Magento with a system that lists books (reading is cool!).

Creating The Model Class Files

Create the following files:

code/local/Fishpig/Externaldb/Model/Book.php

1
2
3
4
5
6
7
8
9
<?php
class Fishpig_Externaldb_Model_Book extends Mage_Core_Model_Abstract
{
    public function _construct()
    {
        $this->_init('externaldb/book');
    }
}

code/local/Fishpig/Externaldb/Model/Mysql4/Book.php

1
2
3
4
5
6
7
8
9
<?php
class Fishpig_Externaldb_Model_Mysql4_Book extends Mage_Core_Model_Mysql4_Abstract
{
    public function _construct()
    {
        $this->_init('externaldb/book', 'book_id'); // book_id refers to the primary key of the book table
    }
}

code/local/Fishpig/Externaldb/Model/Mysql4/Book/Collection.php

1
2
3
4
5
6
7
8
<?php
class Fishpig_Externaldb_Model_Mysql4_Book_Collection extends Mage_Core_Model_Mysq4_Collection_Abstract
{
    public function _construct()
    {
        $this->_init('externaldb/book');
    }
}

That’s the bare minimum needed for your models to be able to access the database!

Adding the Models to The Config

To inform Magento about our models, we need to register them in config.xml. Below is an updated version of config.xml with the models for Book registered.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0"?>
<config>
    <modules>
        <Fishpig_Externaldb>
            <version>0.1.0</version>
        </Fishpig_Externaldb>
    </modules>
    <global>
        <models>
            <externaldb>
                <class>Fishpig_Externaldb_Model</class>
                <resourceModel>externaldb_mysql4</resourceModel>
            </externaldb>
            <externaldb_mysql4>
                <class>Fishpig_Externaldb_Model_Mysql4</class>
                <entities>
                    <book>
                        <table>library_book</table>
                    </book>
                </entities>
            </externaldb_mysql4>
        </models>
        <resources>
            <externaldb_write>
                <connection>
                    <use>externaldb_database</use>
                </connection>
            </externaldb_write>
            <externaldb_read>
                <connection>
                    <use>externaldb_database</use>
                </connection>
            </externaldb_read>
            <externaldb_setup>
                <connection>
                    <use>core_setup</use>
                </connection>
            </externaldb_setup>
            <externaldb_database>
                <connection>
                    <host><![CDATA[localhost]]></host>
                    <username><![CDATA[db_username]]></username>
                    <password><![CDATA[db_password]]></password>
                    <dbname><![CDATA[db_name]]></dbname>
                    <model>mysql4</model>
                    <type>pdo_mysql</type>
                    <active>1</active>
                </connection>
            </externaldb_database>
        </resources>
    </global>
</config>

That’s it, the models should now be registered in Magento!

Testing The Models

Testing them is easy enough, just treat them like normal Magento models.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
    // Load the book with a primary key value of 4
    $_book = Mage::getModel('externaldb/book')->load(4);
    // This would print out the value in the field isbn in the external database
    echo $_book->getIsbn();
    //You can even update records!
    $_book->setName('1984');
    $_book->setAuthor('George Orwell');
    try {
      $_book->save();
    } catch (Exception $e) {
      exit($e->getMessage());
    }

Conclusion

This is one of my first blogs so I probably haven’t written this up as well as I could have, however, I think that using a second database in Magento can be extremely useful. I’ve written a very good WordPress/Magento plugin which gives access to all WordPress post/category/image/link etc information. If you would like to discuss this plugin or would like to use it in one of your sites then please let me know!

Reference: http://fishpig.co.uk/blog/create-an-external-database-connection-in-magento.html