Developing First Magento 2 Module

In this article I’m going to discuss how to setup a basic magento 2 module with simple routing. Let’s do this with practical work. Ns_Email module is implemented in order to continue this discussion with practical work. Bellow is the necessary steps to set up a module structure (Note : Magento Enterprise 2.1.3 version is used to creating this module)

Creating Folder Structure

If you are used to develop magento 1 modules, you may familiar with codepools which resides in app/code folder. There are no more codepools in magento 2. Modules are grouped by namespace and placed directly in the app/code folder. So, lets create following folder structure first

  1. app/code/Ns
  2. app/code/Ns/Email
  3. app/code/Ns/Email/etc

The Ns folder is the module’s namespace, and Emial folder is the module’s name.

Note: code folder may not have in magento fresh installation inside app folder. If so, please create it manually.

Now we have the folder structure ready for our module.

Module Declaration file

Magento 2 looks for configuration information for each module in that module’s etc directory. module.xml configuration file is created in etc directory in order to provide those information.

app/code/Ns/Email/etc/module.xml

and content for that file would be…

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Ns_Email" setup_version="2.0.0">
    </module>
</config>

With this file we register our module with Ns_Email and set the version as 1.0.0

Registering the module with registration.php

All magento 2 modules needs to be registered through magento 2 ComponentRegistrar class. registration.php class will be created at module’s root directory

app/code/Ns/Email/registration.php

and the content for that file would be…

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Ns_Email',
__DIR__
);

Enable the module

By finishing above steps an empty module is created. It can be tested whether this module has recognized by magento, by running bellow magento shell command (Note: navigate to magento root before you run the magento shell command)

./bin/magento module:status

or

php bin/magento module:status

if you have not set classpath properly.

If everything has done properly, bellow message will be appeared at the end of the resulting text

List of disabled modules:
Ns_Email

Magento confirms that the setup module is recognized by the Magento and is ready to install by giving above result. Following shell command will be used to install the built module

php bin/magento module:enable Ns_Email

Following result will be appeared on command line, if everything ran properly

The following modules have been enabled:
- Ns_Email

Or else, if you run

setup:upgrade

it will enable all the modules which are not installed

Create a Router

An URL in magento2 can be identified in 4 specific parts.

< BASE_URL>/< router>/< controller>/< action>

let me explain it by an example

https://example.com/module_example/hello_world/say_hello

https://example.com – BASE_URL
module_example – router
hello_world – controller
say_hello – action

Router in Magento 2 specifies the controller which should called when a certain URL is accessed. routes.xml is used to specify the routers in magento 2

app/code/Ns/Email/etc/frontend/routes.xml1
<p>And the content for above file is</p>
1
<p>So far we have achieved up to this part of the URL</p>
1http://www.example.com/nsmail/

Create Controller and Action

The next aim is to display a simple message on the browser. Let’s assume the URL is http://www.example.com/nsmail/index/sayhello. Therefor the controller file should be

app/code/Ns/Email/Controller/index/SayHello.php

The content of the above file will be as bellow

<?php
namespace Ns\Email\Controller\Index;


use Magento\Framework\App\Action\Action;
use Magento\Framework\App\ResponseInterface;

class SayHello extends Action
{

    /**
     * Dispatch request
     *
     * @return \Magento\Framework\Controller\ResultInterface|ResponseInterface
     * @throws \Magento\Framework\Exception\NotFoundException
     */
    public function execute()
    {
        echo "Hello World";
        exit();
    }
}

Well, everything is ready now. If all the above mentioned steps are followed correct, “Hello World” message should be displayed on browser if http://example.com/nsmail/index/sayhello URL is accessed. Caches will have to be removed prior to access the URL. Caches can be flushed by running following console command

php bin/magento cache:flush

Add New Page Layout – Magento

In most of the magento themes I’ve developed, I used a custom layout for home page because usually there are lots of home page specific units in it. If an existing page layout is customized to match the home page design, it woudl effect to other pages too. Therefor the best option is to create a new page template for home page. So, in this article I’m going to explain how a new page template can be added to a magento website.

This involves creating a new module in magento. Let me call it as Muaw_HomeLayout. Ok, enough talks, lets start. Here are the steps.

Create Module Config File

Define your new module in a config file. For that, Create Muaw_HomeLayout.xml file in following location.

app/etc/modules/Muaw_HomeLayout.xml

Here is the code.

<?xml version="1.0"?>
<config>
    <modules>
        <Muaw_HomeLayout>
            <codePool>local</codePool>
            <depends>
                <Mage_Page/>
            </depends>
            <active>true</active>
        </Muaw_HomeLayout>
    </modules>
</config>

2. Create actual layout file

Create actual layout file in the following location. It would be enough to copy and rename default one to test the module.

app/design/frontend/<package_name>/<theme_name>/template/page/custom-home-page.phtml

. This file will contain all the codings to render the page and childHtml calls.

3. Define Config File

Module config file should be defined in the mentioned location bellow.

app/code/local/muaw/HomeLayout/etc/config.xml

Here is the code.

<?xml version="1.0"?>
<config>
    <modules>
        <Muaw_HomeLayout>
            <version>0.0.1</version>
        </Muaw_HomeLayout>
    </modules>
    <global>
        <page>
            <layouts>
                <new_cms_layout module="page" translate="label">
                    <label>Home Page</label>
                    <template>page/custom-home-page.phtml</template>
                    <layout_handle>lookbook</layout_handle>
                </new_cms_layout>
            </layouts>
        </page>
    </global>
</config>

Congratulations! you have added a new page layout to your magento website. Clean cache and reload admin area. And navigate to CMS->Pages and select a page. Select “Design” Tab. You will see “Home Page” in the “Layout” dropdown.

Managing WordPress Revisions

wordpress-revisions

WordPress revisions are kind of automatically taken backups of your wordpress post or page. This feature is very much useful if you lost your page content by mistake, or you couldn’t save your changes due to sudden restart etc.

wordpress-revisionsRevisions are automatically store for all the post types ( page, post, media and all the custom post types ). But by default this is visible only on default wordpress post types (page, post, medea etc). If you are defining a new post type, you will explicitly have to define the support of revisions.

Enable revisions for custom post types

Revisions are not enabled for custom post types by default. Hence enabling revisions should define for each custom post type. To do that ‘revisions’ should be added to ‘supports’ array of the custom post type args.

'supports' => array( 'title', 'editor', 'revisions' );

Limiting wordpress revisions

WordPress itself stores up-to 25 revisions per each post by default. Old revisions will be deleted automatically and new revisions will be stored. But we can define how many revisions we need wordpress to store for us. It can be done by adding bellow code on wp-config.php

define('WP_POST_REVISIONS', 3);

Comparing Revisions

To compare any reviews, just click on “Brows” link showed in the above screenshot and you will see a comparison. Two change which revision to be compared, you can slide the bar at the top. Newly added contents are marked in green and deleted content marked in red. See the picture bellow

revision-comparing

Jquery autocomplete passing additional parameters

Sometimes you may need to use jquery autocomplete function passing additional parameters. I had a such requirement  in one of my recent project. I searched here and there to find the right solution and it was quite hard. So, I thought to share what I did to get it success here.

Why additional parameters should pass to autocomplete?

Lets think of a situation where searching a certain term in a field of database table. You may need to use extra condition which relevant with a client side variable like input value of a form. In such case, that particular input value is to be passed to the script processing search functionality in addition to the search term. This is where you need a functionality to pass additional parameter to jquery autocomplete function.

This is the syntax for pass additional parameters to jquery autocomplete.

$("selector").autocomplete({
    source: function(request, response) {
        $.getJSON(url, { key1:value1, key2:value2 }, response);
    },
    minLength: 2
 });

If this syntax is used, the search term should pass as one parameter. And any number of additional parameters can be passed. Here is one practical example where I passed additional parameters to jquery autocomplete.

$("#account-number").autocomplete({
    source: function(request, response) {
        $.getJSON(SITE_NAME + '/bankaccount/getaccounts/', { bank_code: $('#bank-code').val(), term : request.term }, response);
    },
    minLength: 2
});

Think you found something useful reading this article. Thank you for reading

Add favicon to wordpress front end and admin area

In this article I’m going to describe how to add favicon to wordpress front end and admin. First of all we should have a favicon image created. So, lets go ahead and create an image with these dimension.

  • 16px x 16px   or
  • 32px x 32px

and save it in png format with ‘favicon.png’ as the name. And upload it to somewhere inside the theme. I stored inside ‘images’ folder inside my theme folder. Well, now we have to do the coding.

Setting up favicon can be done in many ways. Let me go through one by one. Favicon can be set up either using theme or developing a custom plugin.

1. Add favicon to wordpress Using Theme

There are two ways to add favicon to wordpress using the theme code. You can hard code the content in head section or you can add a function into the functions.php and call it using a hook.

a) By hard coding in theme files

In order to add favicon to wordpress website, use the following code inside <head> tag in your header.php file of the activated theme.

<link rel="shortcut icon" href="<?php echo get_template_directory_uri(); ?>/images/favicon.ico" />
 get_template_directory_uri(); 

code is used to get the correct path to the wordpress theme directory.

Usihg this method, favicon will only be appeared in front end. There is no way to add favicon to admin area, hard coding the above code in header.php

b) By adding to the theme dynamically

In this method, the coding is done in functions.php file.

show_my_favicon();

function will be used to show favicon and it will be fired using following hooks

wp_head //for front end
admin_head //for admin area

ok, this is the full code to include in functions.php in order to show the favicon in front end and back end.

function show_my_favicon() {
   $ficon_url = get_template_directory_uri() . '/images/favicon.png';

   echo '<link rel="shortcut icon" href="' . $ficon_url . '" />';
}

add_action( 'wp_head', 'show_my_favicon' ); //front end
add_action( 'admin_head', 'show_my_favicon' ); //admin end

Add favicon Using a plugin

You can add favicon to your site by your own plugin. The advantages using a plugin to add a favicon are
1. Favicon will remain even if you change the theme of your website.
2. You can re-use this code as plug-and play in any wordpress website you develop in the future.

So, in order to develop a plugin, create a directory inside wp-content/plugins/ and name it with what ever you prefer. Then create a plugin php file inside that directory. In my case the full path to plugin file is ROOT_DIR/wp-content/plugins/my-favicon-plugin/my-favicon.php. Here is the content for my-favicon.php

<?php
/**
 *Plugin Name: New Favicon Plugin
 *Description: Adding a favicon to front end and admin area of my site.
 */
function show_my_favicon() {
   $ficon_url = plugins_url('/favicon.png', __FILE__);

   echo '<link rel="shortcut icon" href="' . $ficon_url . '" />';
}
add_action( 'wp_head', 'show_my_favicon' ); //show favicon on front end
add_action( 'admin_head', 'show_my_favicon' ); //show favicon on admin area

copy above code to your plugin file and activate the plugin on wordpress admin area. Thats it, you should see the favicon in title bar after you follow either of method described above.

Remove woo image from sidebar of showoff

Recently I had to customize “Showoff” woo theme for a customer. And one of his requirement was to remove woo image from sidebar and the copyright text from footer and add a custom copyright text. I spent hours finding from which file I can do that. Finally I found that it can be easily done on theme options page in wordpress admin area. Here is the way you can do it if some one interested.

Setting Custom Copyright Content

There is an option to select “Enable Custom Text Area” at the bottom of the theme options page’s Settings->Layout tab. Tick it and enter your custom content in the text area bellow to that with “Custom Text” as the label.

copyright-showoff

Think this would helpful for you in any kind. Thank you very much for following this article

Develop Simple PHP MVC framework

Pointing all the requests to a central location

.htaccess file can be used to do that. Here is an example where all the requests to a certain website is pointed to index.php in the root directory.

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l

RewriteRule ^([^?]*)$ index.php?url=$1 [NC,L,QSA]

place the .htaccess file in your root directory and create a file index.php in the same directory with some dummy content. And access the site using different urls like

your-domail.com/
your-domail.com/about/us
your-domail.com/product/234/view

You will still see that all the requests to the website goes directly to the index.php

Process all URL’s from a single file

Processing all the requests to the website using a single file/function is required. Routes.php is used in this example.

<?php
class Router{
    function __construct(){
        if(isset($_GET['url'])){
            $raw_url = $_GET['url'];
            $urlTrim = rtrim($raw_url, "/");
            /** making an array of parts of url ( seperated by / ) */
            $url = explode("/", $urlTrim);
            $controller_name = $url[0];
            if(file_exists(ABSPATH."Controller/".$controller_name.".php")){
                /**
                 * if controller file is there, mc-autoload.php will load it
                 * here the controller is actually created/instantiated
                 */
                $controller = new $controller_name();
                /**
                 * if 2 or more string phrases available in the url,
                 * pass 2nd and later strings as parameters to the action
                 */
                if(isset($url[2])){
                    $action = $url[1];
                    /**
                     * removing 0th and 1st elements from $url array
                     */
                    array_shift($url);
                    array_shift($url);
                    $data = $url;

                    /**
                     * check whether action function exists
                     */

                    if(method_exists($controller, $action)){
                        $controller->{$action}($data);
                    } else {
                        $controller = new Error();
                    }
                } else {
                    if(isset($url[1])){

                        /**
                         * check whether the action function exists
                         */
                        if(method_exists($controller, $url[1])){
                            /**
                             * calling the action with no parameters
                             */
                            $controller->{$url[1]}();
                        } else {
                            $controller = new Error();
                        }
                    } else {
                        /**
                         * calling to home page, if there is no action specified
                         */
                        $controller = new Error();
                    }
                }
            } else {
                /**
                 * If controller file is not found, the error/404 page is loading
                 */
                require_once (ABSPATH."Controller/error.php");
                $controller = new Error();
                return false;
            }
        } else {
            /** if url/controller is not set, load home page */
            require_once(ABSPATH.'Controller/index.php');
            $controller = new Index();
        }
    }
}

Remove p tags from Contact Form 7

It is better to have full control of styling everything when we are coding a custom wordpress theme. Contact Form 7 is a widely using form generation plugin over the wordpress community. All the input elements of Contact Form 7 are coming with wrapped paragraph element. If you view source or inspect element on your browser, you’ll see

tag although we have not added it when we creating the form. If you ever wanted to remove this automatically added p ( paragraph ) tag, here is the answer for that.

To do this, you’ll have to have FTP access to edit the file. Here are the steps you’d have to follow.

    1. Login to wordpress installation directory via FTP client or SSH.
    2. Locate this directory /wp-content/plugins/contact-form-7
    3. Open wp-contact-form-7.php file to edit
    4. Find the following code, and set that option to false
if ( ! defined( 'WPCF7_AUTOP' ) ) {
define( 'WPCF7_AUTOP', true );
}

Thats it. If you view source of the form after re-fresh the browser, you would not see <p> tag around each input fields.