Comparison: WordPress Vs. Joomla Vs. Magento

WordPress Vs. Joomla Vs. Magento

Coding? Not your cup of tea.

Coders are great, they develop websites, applications, etc. for businesses but not everyone is that gifted. What does this mean? As a business owner, you cannot manage your website if you are not a coder. 😲

No, this is not true! You can do that.

You might be wondering “how?”
Content Management System (CMS) is the answer. The platform that allows you to change the website content without changing the code.

Isn’t it amazing? You might be thinking “For which CMS platform you should go?”
At present, the three most popular CMS platforms are WordPress, Joomla, and Magento. All the three come with a bucket full of features, high-end functionalities, and easy-to-use interfaces. All-in-all, all are good and free.
Which one to pick? 🤔. Let me make this task easy for you.

Here in this blog, I am sharing a comparative analysis between the three CMS platforms, i.e., WordPress, Joomla, and Magento. Analyse the features carefully and decide which one will fit your business requirements. I hope that after reading this blog, readers will get some useful insights about all these content management platforms.

I would also like to mention here that I am not recommending any one CMS above other, for me all are good.

So, tighten your seat belts and get ready to take off with me in this comprehensive comparison journey.
Let’s fly high:

WordPress:

Made an appearance in the year 2003!
Want to do blogging? WordPress is here! It is a father of all blogging platforms.

  • Highly-functional, huge plugin library, flexible, and of course are free of cost.
  • What stats say – more than 76 million websites worldwide are trusting WordPress. Yeah! That’s cool.
  • Major players using WordPress – Disney, Facebook Newsroom, Sony Music and more!
  • If you have to start a simple blogging website, WordPress is the right fit for you.

Joomla:

Made an appearance in the year 2005!

  • From personal blogs to massive web content, Joomla never fails to meet the business needs.
  • Powerful, secure, flexible and free.
  • What stats say – more than 2.83 million websites worldwide are using Joomla.
  • A good choice indeed!
  • Major players using Joomla – Linux, MTV Greece, Holiday Inn and more!

If you want to grow your business website with advanced features and customization, choose Joomla.

Magento:

Made an appearance in the year 2008!
Planning to start an e-commerce website? Look no further than Magento.
Easy-to-integrate, a lot of features, highly-customized and free.

  • What stats say – more than 519154 websites are using Magento.
  • Major players using Magento – Ford, Harvey Norman, Land Rover and more!
  • If you are planning to start an e-commerce website, pick Magento.

So, this is a brief idea about the three platforms.

Let us talk about few Pros and Cons of these platforms.
 

        WordPress

Joomla
Magento
Pros:

 

·         Easy-to-use interface
·         Highly flexible
·         Easy Customization
·         Huge plugin library
·         Robust content handling capabilities
·         Friendly interface
·         Strong developer community
·         Mobile responsive
·         Robust security
·         Good SEO capabilities
Cons: ·         Limited security
·         Few design options
·         Partial content handling capabilities
·         Few SEO capabilities
·         Plugin compatibility issues
·         Slow loading time
·         Customization issues

Choice Is Yours!

I have discussed few pros and cons of all the three platforms. Now, the choice is yours. Nobody knows your business more than you do, so analyze your business requirements carefully and decide which one will fit best.

Don’t ask me where to find a good digital marketing company?

Search for the service providers using the internet and that too nearby your location. For instance, people living in Sydney should find the best content marketing agency in Sydney. They are experts and are well-versed with the knowledge of content management systems. Choose the agency whose services suit your business requirements and kick-start your CMS development task today.

I would love to hear from you. Share with me which CMS platform you are using.
Don’t forget to post a comment and tell me how you like this blog.
Have a good day!

Magento 2 track order issue (track order link not working when an order has more than one shipment)

Magento 2 track order issue (track order link not working when an order has more than one shipment)
This blogpost has a fix for core magento issue i.e, track order not working when more than one shipment is placed. Below is the screen you will get when you will place more than one shipment for a single order.

This issue is because in popup.phtml we have called child block to show every shipment details but if you check below code

'shipping.tracking.details.' . $counter 

Above code only has counter which is index of an array of track details and for every shipment it will take counter as 0, thus we will get an issue that block already called or exist. To fix this we have to make it unique so I have added ship id to this. You need to override popup.phtml in your code and replace it with below code:-

<?php
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

use Magento\Framework\View\Element\Template;

// @codingStandardsIgnoreFile

/** @var $block \Magento\Shipping\Block\Tracking\Popup */

$results = $block->getTrackingInfo();
?>
<div class="page tracking">
    <?php if (!empty($results)): ?>
        <?php foreach ($results as $shipId => $result): ?>
            <?php if ($shipId): ?>
                <div class="order subtitle caption"><?php /* @noEscape */ echo $block->escapeHtml(__('Shipment #')) . $shipId; ?></div>
            <?php endif; ?>
            <?php if (!empty($result)): ?>
                <?php foreach ($result as $counter => $track): 
                if(!is_array($track)) {
                ?>
                    <div class="table-wrapper">
                        <?php
                            $block->addChild('shipping.tracking.details.' . $counter . $shipId, Template::class, [
                                'track' => $track,
                                'template' => 'Magento_Shipping::tracking/details.phtml',
                                'storeSupportEmail' => $block->getStoreSupportEmail()
                            ]
                        );
                        ?>
                        <?php /* @noEscape */ echo $block->getChildHtml('shipping.tracking.details.' . $counter. $shipId); ?>
                    </div>
                    <?php if (!empty($track->getProgressdetail())): ?>
                        <?php
                            $block->addChild('shipping.tracking.progress.'. $counter, Template::class, [
                                'track' => $track,
                                'template' => 'Magento_Shipping::tracking/progress.phtml'
                            ]);
                        ?>
                        <?php /* @noEscape */ echo $block->getChildHtml('shipping.tracking.progress.' . $counter); ?>
                    <?php endif; 

                }
                    ?>
                <?php endforeach; ?>
            <?php else: ?>
                <div class="message info empty">
                    <div><?php echo $block->escapeHtml(__('There is no tracking available for this shipment.')); ?></div>
                </div>
            <?php endif; ?>
        <?php endforeach; ?>
    <?php else: ?>
        <div class="message info empty">
            <div><?php echo $block->escapeHtml(__('There is no tracking available.')); ?></div>
        </div>
    <?php endif; ?>
    <div class="actions">
        <button type="button"
                title="<?php echo $block->escapeHtml(__('Close Window')); ?>"
                class="action close"
                onclick="window.close(); window.opener.focus();">
            <span><?php echo $block->escapeHtml(__('Close Window')); ?></span>
        </button>
    </div>
</div>

Configure Code Sniffer With Netbeans (MEQP2 OR Magento 2 standard)

CodeSniffer, an essential code review tool which helps you to make your code clean and consistent, specially when we work with Magento we should make it our habit to use such tools to have better development process. This blogpost is for those who uses NetBeans IDE for Magento 2 development, here are the steps to integrate PHP CodeSniffer with NetBeans IDE using MEQP2 standards.

Note:- Make sure that you have code sniffer already steup as this blogpost only explains code sniffer configuration with netbeans.

Code Sniffer configuration steps in netbeans:

• Open NetBeans IDE (this process is for Netbeans 8.2).
• Go to tools-> Plugin and install the NetBeans plugin ‘phpCS-MD’. You will get it under “Available Plugins” tab. If it does not show then check next step, it will be already setup then.

• Now go to “Tools” -> “Options”->”PHP”->”Code Analysis”.

• Click on the tab “CodeSniffer”.
Here you have to provide the path to phpcs.bat file present under your PHP installation directory. Do this by clicking the “Browse” button there.

• Now you need to select the coding standard for which you want to test your application, in our case it is MEQP2. Select it and click ok to complete configuration.

Testing Code using code sniffer in netbeans:

To test the code just select file or folder from project directory and the go to source > inspect to get the below screen:-

Click on Inspect button to get the list of all issues and warning:-

Hope this helps, just drop in your comment for any issue.

Magento 2 UI Component simplest way to show only time for date column

This is a very short blog, but i wrote this post to provide the quick and best solution to hide time for date column n UI component. For this, you have to simply provide the date format setting without time format as given below in your ui-component.xml file

<column name="salesperson_createddt" class="Magento\Ui\Component\Listing\Columns\Date" >
    <argument name="data" xsi:type="array">
      <item name="config" xsi:type="array">
         <item name="filter" xsi:type="string">dateRange</item>
         <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
         <item name="dataType" xsi:type="string">date</item>
         <item name="label" xsi:type="string" translate="true">Created Date</item>
         <item name="dateFormat" xsi:type="string">MMM d, Y</item>
      </item>
   </argument>
</column>

Magento 2 add complex (aggregate sql function) collection query for grid

This blogpost provides solution to most common problem which we face several time while creating grid. If you have some complex collection query for grid creation specially if you are using aggregate function then you might face issue with filters, export csv functionality.

Magento 2 grid Creation with custom query

For adding custom query we need to override __initSelect function in our collection file as shown in below code:-

namespace Namespace\ModuleName\Model\ResourceModel\SpCommission;

use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;

class Collection extends AbstractCollection {

    protected function _initSelect() {
        parent::_initSelect();
        $ObjectManager = \Magento\Framework\App\ObjectManager::getInstance();

        $this->getSelect()->columns('created_dt as salesperson_createddt');
        $connection = $this->_resource->getConnection(\Magento\Framework\App\ResourceConnection::DEFAULT_CONNECTION);
        $table = $connection->getTableName('i95dev_ar_book');
        $this->getSelect()->join(array('options' => $table), '`main_table`.`i95dev_ar_book_id` = `options`.`primary_id`');
        $this->getSelect()->columns('SUM(salesperson_commision) as total_commission')
            ->group(array('gp_salesperson_id'));
        $this->addFilterToMap('salesperson_createddt', 'main_table.created_dt');
        $this->addFilterToMap('primary_id', 'main_table.primary_id');

    }
}

So above is the way to customize your collection query for grids. Now we will see the tips for some issue you might face:-

Field is ambiguous

Suppose you joined two table and both have same name field and you are using it in filters then ‘field is ambiguous’ is most common issue you will face, to avoid it you need to map field with it alias and use alias everywhere rather than field name.

$this->addFilterToMap('primary_id', 'main_table.primary_id');

total_commission(Aggregate function field) is not a column

Note:- Magento 2 grid are made to work for simple queries with not much complexity

This happens when we do filter because as you can see above we are using ‘group by’ and aggregate function. If you see getSelectCountSql() function in \Magento\Framework\Data\Collection\AbstractDb file

public function getSelectCountSql()
    {
        $this->_renderFilters();

        $countSelect = clone $this->getSelect();
        $countSelect->reset(\Magento\Framework\DB\Select::ORDER);
        $countSelect->reset(\Magento\Framework\DB\Select::LIMIT_COUNT);
        $countSelect->reset(\Magento\Framework\DB\Select::LIMIT_OFFSET);
        $countSelect->reset(\Magento\Framework\DB\Select::COLUMNS);

        if (!count($this->getSelect()->getPart(\Magento\Framework\DB\Select::GROUP))) {
            $countSelect->columns(new \Zend_Db_Expr('COUNT(*)'));
            return $countSelect;
        }

        $countSelect->reset(\Magento\Framework\DB\Select::GROUP);
        $group = $this->getSelect()->getPart(\Magento\Framework\DB\Select::GROUP);
        $countSelect->columns(new \Zend_Db_Expr(("COUNT(DISTINCT ".implode(", ", $group).")")));
        return $countSelect;
    }

Above you can see that our collection column, limit offset, count , order and all other things are being reset to get the count of result. Since column get reset how will magneto know what is total_commission as this is not already created column name in any table thus you need to override this method to make customization according to your own needs.

Aggregate function column Alias is not working with filter due to where clause

Here mapping filter will be a bad suggestion, thus you need to override addFieldToFilter() function and request for having clause rather than where to make your code work.

Magento 2 add custom filter to grid for date (dropdown with value as today, lastweek)

In this blogpost we will look to customize the date filter to provide it more option:-

So as can be seen in above image we need to add a dropdown for date filter. On selection of any date it will make changes to input box, and we can can filter our data according to date.
To achieve this you need to override Magento_Ui/js/form/components/group.js file
In your module add requirejs-config.js file in view/adminhtml folder and write the below code:-

var config = {
    map: {
        '*': {
            'Magento_Ui/js/form/components/group':
            'Namespace_Salesperson/js/form/components/group',
        }
  }
};

Then add the group.js file in your own module on view\base\web\js\form\components\group.js and make changes in initialize function. You need to add a condition specifically for your field and provide the template to which you want to refer it:-

initialize: function () {
            this._super()
                ._setClasses();

                if(this.index == 'salesperson_createddt') {

                        this.template = 'Namespace_Salesperson/group/groupdt';
                }

            return this;
        },

Now add a html file at this <strong>view/base/web/template/group/groupdt.html</strong>

<legend class="admin__form-field-legend">
    <span text="label"/>
</legend>
<div class="admin__form-field" outereach="elems" render=""/>

<div class="salesperson_createddt" style="margin-left:67px;">
    <select id="salesperson_createddt">
    <option value="none"></option>
    <option value="today">Today</option>
    <option value="yesterday">Yesterday</option>
    <option value="this_week">This Week</option>
    <option value="last_week">Last Week</option>
    <option value="this_month">This Month</option>
    <option value="last_month">Last Month</option>
    <option value="last_month_2">Last 2 Months</option>
    <option value="ytd">YTD</option>
    </select>
</div>

Now to make dropdown work, i.e, on click of select dropdown, input box should have values according to selection made
Add your JS file path in layout xml file. Below is the code to add in your JS file:-

require(['jquery', 'jquery/ui'], function ($) {

    $(document).on('change', '#salesperson_createddt', function () {
        rangeSelect($(this).val(), "salesperson_createddt[from]", "salesperson_createddt[to]");
        $("input[name='salesperson_createddt[from]']").trigger('change');
        $("input[name='salesperson_createddt[to]']").trigger('change');
    });
    function rangeSelect(value, from, to) {
        from = "input[name='" + from + "']";
        to = "input[name='" + to + "']";

        if (value == "today") {
            var today = new Date();
            var dd = today.getDate();
            var mm = today.getMonth() + 1; //January is 0!
            var yyyy = today.getFullYear();
            today = mm + "/" + dd + "/" + yyyy;

            $(from).val(today);
            $(to).val(today);
        } else if (value == "yesterday") {
            var today = new Date();
            var dd = today.getDate() - 1;
            var mm = today.getMonth() + 1; //January is 0!
            var yyyy = today.getFullYear();
            today = mm + "/" + dd + "/" + yyyy;

            $(from).val(today);
            $(to).val(today);
        } else if (value == "this_week") {
            var curr = new Date();
            var firstDay = new Date(curr.setDate(curr.getDate() - curr.getDay()));
            var lastDay = new Date(curr.setDate(curr.getDate() - curr.getDay() + 6));

            firstDay = (firstDay.getMonth() + 1) + "/" + (firstDay.getDate()) + "/" + firstDay.getFullYear();
            lastDay = (lastDay.getMonth() + 1) + "/" + (lastDay.getDate()) + "/" + lastDay.getFullYear();

            $(from).val(firstDay);
            $(to).val(lastDay);
        } else if (value == "last_week") {
            var curr = new Date();
            var firstDay = new Date(curr.setDate(curr.getDate() - curr.getDay() - 6));
            var lastDay = new Date(curr.setDate(curr.getDate() - curr.getDay() + 6));

            firstDay = (firstDay.getMonth() + 1) + "/" + (firstDay.getDate()) + "/" + firstDay.getFullYear();
            lastDay = (lastDay.getMonth() + 1) + "/" + (lastDay.getDate()) + "/" + lastDay.getFullYear();

            $(from).val(firstDay);
            $(to).val(lastDay);
        } else if (value == "this_month") {
            var date = new Date(), y = date.getFullYear(), m = date.getMonth() + 1;
            var firstDay = m + "/" + 1 + "/" + y;
            var lastDay = new Date(y, m, 0);
            var lastDayWithSlashes = (lastDay.getMonth() + 1) + "/" + (lastDay.getDate()) + "/" + lastDay.getFullYear();

            $(from).val(firstDay);
            $(to).val(lastDayWithSlashes);
        } else if (value == "last_month") {
            var date = new Date(), y = date.getFullYear(), m = date.getMonth();
            var firstDay = m + "/" + 1 + "/" + y;
            var lastDay = new Date(y, m, 0);
            var lastDayWithSlashes = (lastDay.getMonth() + 1) + "/" + (lastDay.getDate()) + "/" + lastDay.getFullYear();
            $(from).val(firstDay);
            $(to).val(lastDayWithSlashes);
        } else if (value == "last_month_2") {
            var date = new Date(), y = date.getFullYear(), m = date.getMonth() - 1;
            var firstDay = m + "/" + 1 + "/" + y;
            var lastDay = new Date(y, m + 1, 0);
            var lastDayWithSlashes = (lastDay.getMonth() + 1) + "/" + (lastDay.getDate()) + "/" + lastDay.getFullYear();
            $(from).val(firstDay);
            $(to).val(lastDayWithSlashes);
        } else if (value == "ytd") {
            $(from).val("");
            $(to).val("");
        } else {
            document.getElementById(from).value = "";
            document.getElementById(to).value = "";
            $(from).val("");
            $(to).val("");
        }
    }
});
NOTE:- Replace salesperson_createddt with your field name