When is it time to fire your agency mid-project?

It happens to the best companies – a web development project starts going off the rails. 25% of web projects fail, according to New Bamboo (now Thoughtbot) research cited by ZD Net.

When it starts happening to your company’s digital commerce project, there are inevitably questions about what to do. Here are some of the things to look for.

Have they created a plan and stuck to it?

Agile methodology allows for some twists and turns, but each sprint should bring you closer to the goal of having a functioning web site. From proposal to sprint planning, there should be agreement on what’s expected, what the costs will be, and even how deviations from the plan will be handled. Allowing for some give and take on this, there should be a shared, consistent vision of the site’s objectives and progress.

If the agency you’re working with is constantly surprising you, and not in a good way, about budget and consistent progress, it may be time to make a change.

When problems arise, can they explain what’s going on?

All projects hit bumps in the road. If you are expressing dissatisfaction, it’s a good sign if they can quickly articulate the problem as well as you can as the product owner, and/or help you define the problem. If they can’t, it may be time to start looking.

Obscure explanations are often a bad sign. Keep asking questions until you’re either clear on the issue or it’s clear that they don’t know themselves. Sometimes this takes a little research on your part to understand the explanations; it can be well worth it to evaluate whether they make sense.

When there are challenges, can they quickly set milestones toward a resolution?

A key part of the agile process is that complex issues should be broken down into bite-size, understandable tickets as they approach completion. When unexpected problems come up, a similar approach should prevail. For example, if a developer quits during a sprint, there may be no way to make up the shortfall for that 2 week sprint, but the project manager should inform you promptly, discuss your highest priorities to work on, and have a plan for getting the team back up to full strength by the next sprint or two.

Can you agree with them on what “done” means?

This sounds like a pretty simple question, but when you work with an agency on various project issues, you should be satisfied that there is alignment on what it means to have an issue closed. There may not be an easy, instant answer, but an honest, detailed discussion on what it means to have an issue resolved will force both parties to critically evaluate the answer and come to a common understanding. If you can’t reach alignment on that, you need to start looking.

Are they stuck on technical objectives?

Magento is hard. That’s why we specialize in it, and why we take pride in being a Magento Professional Solutions Partner. Agencies that do a great job with WordPress and other platforms sometimes find that Magento builds are just beyond their capabilities, especially when custom features must be added or built from scratch.

How can we avoid starting all over?

This is often the toughest question of all. You can see that things aren’t going well, but the idea of losing all the work you’ve done so far is pretty hard to think about.

It may not be as bad as it seems. Often the design work can be salvaged (provided you like the design and UX work that’s been done), and even the Magento core installation is often fine. Jamersan has done a number of project rescue interventions, and with some creative thinking we’ve been able to make the most of the work that’s been done already, build on it, and make your site the commerce machine it needs to be.

If you’ve got a project that needs to be rescued, contact us – the sooner you change course, the sooner you’ll be where you want to be.

Thanks to our Senior Project Manager, Shane Rodgers, for key ideas for this post.

Selecting the Right Magento Implementation Partner

It’s not easy being a digital commerce merchant these days. Competition is everywhere, technology is rapidly changing, and customer acquisition/retention is a daily battle. Merchants need partners and a support system to navigate these complexities.

Arguably, the selection of an implementation partner is the most important decision that a merchant faces. To borrow a metaphor from home building, the implementation partner will play the role of general contractor while you, the merchant, are the homeowner. The importance of this general contractor role can’t be overstated. Your implementation partner will sit near the top of the decision tree – helping you to navigate all of the tool, service, and vendor evaluations that come along with building any home (solution). They have to be a trusted partner.

With this in mind should price be the determining factor when selecting an implementation partner? It certainly should be a factor but given what’s at stake not the factor. So what are the key criteria when evaluating candidate implementation partners? Here are some questions to ask:

  1. Without ever having worked with someone before, how do I know they are trustworthy?
    Trust is something that is earned, right? So how does this happen before the relationship even starts? Checking references is an obvious way. But when doing so you might want to ask “did they have your back?” This question typically yields a level of thought and insight that is a good indicator of trustworthiness. Look for clues in conversations with your prospective partner as to whether they have your best interest in mind. A good partner will keep things focused on you and your needs.
  1. How do I know if they are the right fit for the type of house I want to build?
    You probably wouldn’t want a log cabin specialist building your luxury mansion. Just because they are both (technically) a house doesn’t mean that any homebuilder should tackle the job. The right experience lends itself to efficiency and better decision-making. Apart from the obvious step of looking at past work of similar scope there are other ways to evaluate: are they asking relevant questions that I haven’t thought of? This is a sure sign of the right experience. Also, can they tell me what the common roadblocks or decisions that will likely present themselves based on their experience?
  1. Am I comfortable with the communication?
    As with most things that involve the complexity of a software implementation project, there will be problems. Count on it. The only way to effectively overcome them is with solid communication. There are two parts to this: 1) In the selection process, evaluate how the candidate partners are communicating with you. Do you feel they will be honest and forthcoming in delivering news that you may not want to hear? Is their communication style something that you can understand and relate with? Are you receiving information in a way that is clear and actionable? 2) Be sure to ask what the communication protocol will be during the project. This includes frequency, method, parties involved, etc. Does the protocol meet your needs and expectations?

The selection of an implementation partner is an important decision. When it’s all said and done it is the one factor that has the most significant impact on success or failure for your implementation project. Make sure you are armed with the right criteria before you begin the selection process.

Magento Meetup in Birmingham at Avondale Brewing – May 16

Jamersan and Simple Helix went to Imagine in Las Vegas last month, and there are lots of cool things to talk about in the Magento Community. We’ll talk new product announcements and developments, along with Magento’s increasing resources as we move into the Magento 2 era!

The venue is Avondale Brewing Company’s amazing tap room. In addition to the cash bar, we’ve brought in Post Office Pies with an amazing selection of mini-meatballs, pizza and soft drinks.

So come hungry, get ready to find out more about Magento, and meet some of your fellow Magento developers in the Magic City!

Click here to register


Imagine 2017: What did we learn?

Did you make it to Magento’s Imagine show in Las Vegas this April? What you really need now is a way of converting the barrage of information, brochures, and of course LinkedIn requests into a plan to improve your eCommerce fortunes.  If you’re a merchant who attended Imagine and now wonder what you should be doing next, here’s our take:

Magento introduces new or improved products at Imagine, and all of them run on Magento 2

TJ Gamble, CEO of Jamersan, at Imagine Partner Summit
photo credit: Sean Barnes

2016 was a record year for Magento in their quest to modernize eCommerce. Magento Enterprise Edition 2 came of age after a late 2015 stable launch. But it didn’t stop there.

Magento also acquired RJ Metrics, the leading data analytics software-as-a-service (SaaS) offering to small-to-mid-market businesses. This product is now branded as Magento Business Intelligence.

Magento Commerce Order Management, another late 2015 announcement, came on strong in 2016. It promises to help solve a vexing issue that cuts across most industries: how do you deliver your brand experience to all your customers, regardless of what channels they prefer to use?

Magento Enterprise Cloud Edition was also announced at last year’s Imagine show. It’s already powering many of the latest Magento builds, and will continue to be a popular option.

In 2017, there are even more new products and services coming down the pipeline.  These new products from the past 18 months or so are maturing and will dominate the conversation in 2017.

For example, Magento Social and Magento Shipping were announced at Imagine. Magento Social allows you to connect your store to popular social media outlets to bring customers directly to your store from your social posts. Magento Shipping addresses your biggest headache as a merchant – shipping the goods and keeping carrier information, tracking, and rates organized.

Magento B2B will be released later this year and will allow you to support your sales and distribution channels with negotiated pricing, more sophisticated account management tools, and enhanced inventory and order management.

If you’re running Magento Enterprise Edition 1.x, the time is now to be planning your upgrade journey.

Gary Smith, COO of Jamersan at Imagine Partner Summit
photo credit: Sean Barnes

Imagine builds the Magento Community of Technology Partners and Systems

presentation on tech partner ecosystem at Imagine Partner Summit
photo credit: Sean Barnes

Magento is built on community, and that community is working together better than ever. Magento has made a number of new hires to support the business development and marketing functions. Systems integrators like Jamersan have more resources to help take the worry out of your Magento new build or upgrade. At Imagine, we met with several of our Magento contacts. We also met with technology partners like Dotmailer, to cement these relationships. This means that we can help you cut through the clutter and make the best decisions on extensions, middle-ware, and hosting options to make your site a success.

Digital commerce is more critical to your business than ever

According to Forrester research, almost 50% of commerce depends on digital. Whether you think of yourself as a “high tech company” or not, figuring out your digital presence is more crucial than ever. Buyers are increasingly “loyal” only to the company that can provide them the best online shopping experience.  Fortunately, Jamersan is here to help. We’ve got the training and experience to enhance your online offering, whether you need a simple upgrade or a complete re-imagining (no pun intended). Contact us and let’s talk.

Thanks to Sean Barnes and Magento for allowing use of photos from Imagine.


New Magento B2B Simplifies Digital Commerce for B2B Merchants & Manufacturers

Historically the market for digital commerce platforms has given a lot of love to the B2C community. The last few years have seen rapid innovation aimed to deliver better shopping experiences in order to satisfy expectations and behaviors of the digital savvy consumer.

While many of these B2C innovations have applicability to the B2B market, not much of this innovation has been specific to B2B. Let’s face it, despite their similarities, there are distinct capabilities required to support the needs of B2B buyers and sellers. To be clear, there are a few B2B commerce platforms available today. However, many of them are not within budget reach for manufacturers or sellers – especially those who are still in the early stages and need to prove business cases for more investment.

As a result many of these B2B commerce managers have found themselves either getting by on a B2C platform or have decided to invest in customization to meet those needs. As a firm that specializes in B2B digital commerce, we here at Jamersan have had the opportunity to work with companies that have gone both routes and are always on the lookout for advances that will benefit our clients.

The good news is that B2B merchants are about to get some love. While at Magento Imagine 2017, we had the opportunity for a “deep dive” into the soon-to-be-released B2B module for Magento 2 Enterprise.

Here’s a summary of capabilities that we found particularly interesting:

  • Tiered buyer accounts within an organization. Your customers are now able to setup an organizational structure consisting of individual buyer accounts with granular control over buying permissions.
  • Custom product catalogs (and pricing) for entities/departments within an organization.
  • Quote process to support complex products that require offline configuration. Many B2B sales transactions can’t be completed without some back and forth between buyer & seller – these interactions can all be handled within the platform now.
  • Sales rep capabilities. Ever wanted your sales reps to place orders, create catalogs, respond to quotes, or establish pricing for their accounts? Check, this has it.
  • Designed with ease of use in mind. Magento has ensured that even the most complex tasks are not complex to perform. For example, the organization builder is a simple drag and drop UI.

Perhaps the most compelling fact is that these B2B capabilities are all included within Magento 2 Enterprise. Why is this important? It means that B2B merchants can be assured that they will reap the benefits of continual innovation across the “core” Magento 2 platform (and partner ecosystem) and will never outgrow it.

While a closed B2B beta is currently underway, Magento 2’s B2B capabilities are expected to be available in Q3 this year. Reach out to us if you are a manufacturer or distributor who is ready to advance your digital commerce program on the Magento 2 platform.

Magento 2 Extensions – The Good, The Bad, The Ugly

When you are choosing Magento 2 extensions, the right choices can make (or literally break) your site. Extensions are needed to add custom features and to make connections to other services. For example, you might be using Dotmailer‘s email automation or TaxJar‘s sale tax filing. They sometimes need to be custom-written to meet specific business or integration requirements, like adapting eCommerce to your proprietary business model or grabbing the inventory data from that AS400 you’re still running.

Finding Magento 2 Extensions – The Good:

Finding modules used to be a process of “googling it,” reading reviews, asking around, and hoping for the best. In Magento 2 (M2), the process has become a little more curated. The new Magento Marketplace features a stronger process for vetting and testing, but Magento 2 is new enough that reviews are still a little sparse.

Magento 2 extensions for solid services like Dotmailer, TaxJar, and many others will generally be fine, as they’re backed by reputable companies that only make money on their services when they work well with your site. However, there can still be conflicts when you’ve got other extensions on your site, as there is no way for them to test every possible combination and configuration.

Magento Marketplace for Magento 2 Extensions

The Bad (and the Ugly):

Fellow Magento partners Fooman wrote a great blog post about some limitations to relying on reviews.  They point out that reviews are not always trustworthy. Sometimes they’re written by competitors (or the developers themselves) Surprise! They give some tips to stack the odds in your favor when relying on those reviews.

The Solution:

Jamersan has been developing in Magento for about a decade. We also have access to Magento resources as a Professional Solutions Partner.  Our Magento 2 knowledge can help take the worry out of adding functionality to your site. We can help you choose well-written extensions, code review your extension selection for quality, or write custom extensions when quality options don’t exist. Contact us for a proposal on your site!

Three Major Reasons To Upgrade To Magento 2

Magento 2 was released in 2015, and is delivering on its promise of being a much improved and optimized version of the Magento 1 platform.   Magento 2’s improved performance and new features provide your customers with a faster, easier shopping experience.   

Magento 1 will continue to be officially supported with security issues patched until November 2018, although no new features will be added.   This means that if you are making major changes to your Magento store, you should seriously consider upgrading to Magento 2 as part of those changes.   In this document, we will outline some of the major benefits of Magento 2 that you can instantly take advantage of once you upgrade that make the costs of doing so well worth it.   


Magento 2 was redesigned with performance in mind.   Page loads in Magento 2 are 30% to 50% faster.   Studies show that Magento 2 can handle up to 39% more orders per hour with 66% faster add-to-cart times than Magento 1 and with the proper hosting setup can deliver nearly instant server response times for catalog browsing.   Performance that fast means more user interaction with your site, more products added to your site’s cart, and more sales with fewer abandoned carts.    

The comparison shopping site Shopzilla saw a 25% increase in page views and a 9.5% increase in revenue after moving to Magento 2 with Varnish.

Magento 2’s better functionality means it can also handle more traffic. Magento 2 can manage 10 million page views an hour; Magento 1 can only process 200,000. At checkout, Magento 2 CE can handle 50,000 orders an hour; Magento 2 EE handles 90,000 in the same time.

How does Magento 2 provide such an improvement in performance and reduction in server load?  Some of the highlights of Magento 2’s performance enhancements are as follows: 

    1. Ajax Cart:  Out of the box, without installing a module, Magento 2 now includes an Ajax Cart.   Ajax Carts use javascript to add items to the shoppers cart without reloading the entire page.   That puts less load on your hosting hardware and results in a more responsive experience for your shoppers.  
    2. Cache:  Caching systems store commonly accessed page elements to serve them faster to your visitors. Magento 2 has a much improved caching system and now includes native support for caching technologies like Varnish (Varnish is a popular HTTP accelerator).
    3. PHP 7:  PHP is the programming language that Magento is built with.  Magento 2 is optimized for PHP 7, which provides superior performance to previous PHP versions.
    4. Hosting Environment Improvements:  Magento 2, especially Enterprise Edition, includes new features and functionality that allow you to more easily spread the demand on your hosting infrastructure over multiple servers and thus more easily handle large traffic spikes. 

Administrative Improvements:

You are busy and your time matters.  Magento 2 has quite a few improvements to make the job of administering your site simpler and more efficient.    

    1. Improved Product Creation:  The new step-by-step product creation tools allow you to more quickly and accurately add products to your store.   This tool makes adding products up to 4 times faster in Magento 2.
    2. Improved Data View and Filtering:  Magento has added a very robust data grid view to the admin of Magento 2.   This grid gives you the ability to customize what attributes are shown in a grid view (such as a product list) without the need to get a developer involved.   Each administrator can customize their data views to suit their individual needs.    These leads to clean, uncluttered interfaces and guarantees that you can see the data that you need to see.   Magento has also added the ability to quickly filter data based on any of the attributes that you have enabled in your data view.  
    3. Admin Navigation Improvements:  The admin interface is cleaner and less cluttered.   Menus are more organized so that finding the page and functionality that you are seeking is much simpler.   These improvements lead to a smaller learning curve and quicker productivity for administrators.  
    4. Data Safeguards:   Magento 1 was designed for a single admin user to be manipulating product data at a single time.   This is troublesome for larger sites that might have multiple administrators.   Magento 2 has added safeguards for product data that allow multiple administrators to work on product data simultaneously thus making your team more efficient and allowing you to more easily keep your store’s products up to date.
    5. Product Videos:  Adding videos from Vimeo or Youtube are now very simple and supported natively by Magento 2.  This offers a great opportunity to properly merchandise your products.   

Improved Customer Experience:

Magento has made huge strides in improving customer experience and cutting down on shopping “pain points” that lead to abandoned carts, especially on mobile devices.    These improvements make shopping much simpler for your customers and will result in more sales from your store.   Below are some of those improvements:

    1. Improved Checkout:  The checkout process is much smoother and simplified compared to Magento 1.   Making checkout as simple as possible is vital in having high conversion rates and getting the most from your site when shoppers have such low tolerances for complications.

      • They simplified registration by allowing customers to create an account after ordering instead of during the checkout process.  
      • Checkout now includes order details on every step to help put your customers at ease.
      • Fewer confusing choices (like registering for an account) and fewer forms means a significant increase in conversions as customers focus on what matters:  finishing the checkout process.  
      • Improved PayPal Integration:  Magento 2’s integration with PayPal has been improved by not requiring additional needless information such as a billing address that is handled by PayPal.  
      • Order Summary Photos:   The order summary in Magento 2 now includes product photos.  This reduces ordering errors which cuts down on returns and increases buyer confidence that leads to higher conversions.
    2. Improved Search:  Magento 2 has much needed search improvements to allow customers to more quickly and efficiently find products.   The default search engine has been switched to ElasticSearch for Enterprise Edition.   Configuration and customization of ElasticSearch is simpler and faster, resulting in better search results and fewer development costs. 
    3. Mobile Browsing Enhancements:  50% of online transactions are now performed on mobile devices.   Magento 2 utilizes many of the enhancements mentioned above to greatly improve user experience on mobile.  Browsing is much more complicated and slow on mobile, so many users rely heavily on search.   By improving the search capabilities in Magento, your mobile users greatly benefit.   Combining that with a much more streamlined mobile-friendly checkout and faster performance will result in a much higher conversion rate for your mobile shoppers.   

All businesses currently running Magento 1 will benefit from migrating to Magento 2 because the performance improvements and new functionality in both the Enterprise and Community editions make migration worthwhile.

Because of the improvements listed above, conversions and therefor revenue should increase from upgrading to Magento 2.  Shopzilla’s experience is noteworthy here: a 25% increase in page views and a 9.5% increase in revenue. For most businesses, increases on this scale will quickly recoup the investment in migration to the new and future platform.

Changing the customer trends will make migration more important in coming years: as we see more and more mobile use of the internet, e-commerce sites need to be able to meet the demands of those users. Magento 2 with its responsive, HTML5 front end and the new, streamlined checkout process meets those needs and can make your business more effective in a small screen world than ever can be managed with the current Magento platform.

Magento 1 will not be supported after 2018. So any investment that your business makes into the old platform will be essentially short term in nature.

How Does the Upgrade Process Work?

Unlike Magento 1 upgrades with their relatively straightforward upgrade process, migration from Magento 1 to Magento 2 is considerably more complicated. Since Magento 2 is a completely new platform, most businesses will require a serious commitment to the planning and implementation of the process.

Magento has implemented a data export/import tool to aid with migrating data between the two platforms, but you’ll still have other considerations:

  • You’ll need to check that your server meets the requirements for Magento 2. and you’ll most likely need to upgrade to a new server.
  • Your developers will need to check that all third-party extensions installed on your site have compatible Magento 2 versions.
  • You’ll need to have any incompatible extensions coded from scratch or purchase an alternative extension.
  • Your site’s theme(s) will need to be rebuilt from the ground up since Magento 2 has a totally different structure from Magento 1.
  • If any core tables were altered when you installed Magento 1, data migration will be more complex.

The amount of work your migration requires will largely depend upon the amount of customization you’ve done to your Magento 1 store. Custom modules will need to be modified extensively but Magento 2 versions of most third party extensions are available or will be available in the near future. If you’ve been using Magento 1 for some time, this may be a good opportunity to improve user experience or even redesign your entire site.

How Jamersan Can Help

Migration to the new Magento 2 platform can be a daunting prospect. After all, Magento is supporting the revenue stream and online presence of your entire online business. If your e-commerce platform lets you down, then your entire business is at risk.

Even if you are thinking of staying with Magento 1 for the time being, it is a good idea to open a conversation with your Magento solution partners about how to best handle the future of your online business and put together a long term transition plan.

At Jamersan we have been developing e-commerce sites for over 16 years. We are a Magento Professional Solution Partner with expertly trained staff capable of making your transition to Magento 2 a simple one.   We would love the opportunity to discuss your interest in Magento 2. 

Guide to B2B eCommerce Success: Separate Your B2B And B2C

B2B customers have very different needs and are typically in completely different mindsets and buying modes that B2C customers.   To maximize effectiveness and ease of use, you need to separate your B2B and B2C websites.  Attempting to have a B2B and B2C website on the same eCommerce installation  is a way too common problem that we encounter.

  1. Navigation is different for B2B.   Search is important in both B2B and B2C, but in many cases B2B buyers are much less likely to browse through long category listings of products.   It is important to provide advanced search capabilities that allow them to easily hone in on the product they are seeking.

  2. Pricing is different for B2B:  Negotiated pricing, tiered pricing, and promotions (or lack thereof) are commonly very different between B2B and B2C websites.  If you attempt to accomplish both B2B and B2C pricing needs in the same installation, you often find yourself in a logistical nightmare from a management of data perspective.  It is also a very common cause of performance issues on eCommerce websites, and slow performance costs you sales.

  3. Features are different for B2B:  Quick order, re-order capabilities, account approvals are very common in B2B eCommerce, but not so common in B2C.   You want to remove friction in the buying process and to make it as simple as it can be.  With that in mind, you don’t want features on your B2C site that those customers would never utilize because they are aimed at B2B customers and vice-versa.  Separating them into eCommerce installations designed and aimed at each feature set may cost you more up-front, but will save you trouble managing data and allow you more flexibility to be aggressive in your marketing and developing of new features and promotions for each channel of your business.    

Guide to B2B eCommerce Success: Easy To Adopt, Easy To Shop

Just about any business has customers that either love them or don’t want to spend time looking for an alternative.  Those customers will shop on your site whether it’s great or terrible.  However, if you want to maximize the site’s usage or grow your business, then you need to keep the site simple and easy to use.

  1. Easy to Adopt: If you are going to get customers to use your new website, then it needs to be easy for them to begin doing so.   
    • Prime The Site:  Go ahead and prime your site by creating accounts for each of your regular customers or migrating them from any existing system you may have.   Have your sales team reach out to them and schedule a time to go over the site and show them the benefit in using it.   This will help increase adoption and make sure you get an immediate impact from the site’s launch.

    • Don’t Require Signup or Make Signup Simple:  Guest checkout has been known to increase sales by huge margins.  As a result, It’s best if you do not require signup in order to purchase.  However, if that is not possible make sure you request the least amount of information that you need to verify a customer during the account signup process.  The salesman that it gets assigned to can always follow up with the customer for more information that you may need or want to use in the future.

    • Approve Accounts Quickly: It is recommended that you allow instant new account approvals if at all possible.  However, if you cannot then there should be a quick and simple process in which accounts are promptly approved.

    • Don’t Hide Products: If new customers cannot see your product offering until after they register and are approved for an account, it will significantly decrease the amount of new customers that you receive.   Search engines won’t see the products and you’ll lose traffic to the site not to mention that much of the new traffic that you receive will simply move on to a competitor that does show their products.
  1. Easy to Shop:  A lot of the same principles of simplicity of use in a B2C eCommerce website also apply to a B2B website.

    • Make Checkout Quick and Simple:  It’s a very simple recipe.  The fewer clicks and less user interaction that it takes to move from your product page through order completion, the higher the percentage of users that will complete it.

    • Ensure Pages Load Quickly: If your site is fast loading, customers will visit more product page resulting in more products sold and a higher number of customers completing checkout.

    • Make Sure You Are Available: The website is an extension of your sales team, not a replacement for them.   People still want to deal with people.   Make sure that your contact information including the Sales Representative that they should contact should they have problems is readily available.

    • Quick Order and Re-Order Capability:  In a typical B2B relationship, your customers often know what product they need to order or have already order that exact product in the past.   As such, it is important to make it easy for them by allowing them to create lists of commonly order products that they can choose from, allow re-ordering from previous orders, and also allow them to quick order by simply entering the SKU.  Easy ordering means happy customers and happy customers buy more frequently.        

Guide to B2B eCommerce Success: Your Sales Team Is Key To Your Success

In most organizations, your sales team has the biggest impact and is often exclusively your relationship with your customers.  It would be a huge mistake to try to attempt to introduce anything to your customers without having their buy-in.    If your goal is to cut down on sales commissions or to cut back on the size of your sales team, then you are heading down a very dangerous path. 

If your sales team feels threatened by this new technology, why would they support it?  Follow these tips to ensure you get your sales team on board for maximum success.

  1. Sell your sales team: You need them to be on board to have a chance at success.  Explain to them that this tool is not to replace them.   Make sure they know that any sales commission will still be attributed to online orders.   Show them that this will not cost them sales, but increase their efficiency and allow them to take on more customers and make more sales.

  2. Get your sales team involved early:  Your team knows your customers better than anyone.  Who else would be better at consulting on decisions that impact those customers?   Have them involved in the process so they understand the decisions that have been made and how they impact your business.

  3. Train your sales team on the new technology: If they are going to be introducing this to customers, confidence is important.    The only way to instill confidence in the team is for them to be fully trained on how it works so that they can be comfortable showing customers how to use the site or helping them with basic problems that they may encounter. 
  4. Make sure you have an open line of communication:  Your managers need to make sure they are receptive to feedback including concerns and complaints from your sales team during the decision making process and continuing after launch.   Having your team feel like they have an open communication and that feedback is accepted and considered makes them feel more committed to the project’s success.

Create New Magento Admin User via MySQL

If you’ve ever been locked out of the Magento admin, for whatever reason, and need to create a new user, you can do so by making some adjustments to the following sql script and running it inside phpMyAdmin, or command line (CLI). You will need to make some changes to this script, so please read below for more details.

The MySQL Script

[sql]LOCK TABLES `admin_role` WRITE , `admin_user` WRITE;

SET @SALT = “ms”;
SET @PASSWORD = “password”;
SET @FIRSTNAME = “firstname”;
SET @LASTNAME = “lastname”;
SET @EMAIL = “firstname@email.com”;
SET @USERNAME = “myusername”;
SELECT @EXTRA := MAX(extra) FROM admin_user WHERE extra IS NOT NULL;

INSERT INTO `admin_user` (firstname,lastname,email,username,password,created,lognum,reload_acl_flag,is_active,extra,rp_token_created_at)

INSERT INTO `admin_role` (parent_id,tree_level,sort_order,role_type,user_id,role_name)
VALUES (1,2,0,’U’,(SELECT user_id FROM admin_user WHERE username = @USERNAME),@FIRSTNAME);


How to Edit the Script

  • If you need to set the salt portion of your password, you can change the ms to the lowercase letters of your choosing. You should rarely have to do this, and usually you can leave this as is.
  • Change the @PASSWORD value to the password you would like to use. In this example I have it set to ‘password’. *Line 04*
  • Change the @FIRSTNAME value to the user’s first name. *Line 06*
  • Change the @LASTNAME value to the new user’s last name. *Line 07*
  • Change the @EMAIL value to the new user’s email address. *Line 08*
  • Change the @USERNAME value to the new username you wish to use. *Line 09*

Once you’ve made these changes you can just paste this script into the SQL section of phpMyAdmin, or run it via CLI. You should then be able to use the new user that you created to login to the Magento admin.


There are a few ways that you can add a new user in Magento when you currently do not have access to the admin. This is just one of the methods that I’ve used in the past. I will post another method in the future that requires only FTP access to the server, as well as an easy way to just reset an existing user’s password via MySql CLI and phpMyAdmin.

Innovative New Magento Extensions for Developers!

The Enhanced Developer Tools Extension (Download) 

When a page is loaded, that has not been cached, Magento processes well over 100 files. So, if you need to edit a page, this normally requires manually looking for the file(s). The ‘Enhanced Developer Tools’ extension automatically locates the file(s) you are looking for.

When a user types in a word or two that is in the block, Magento then identifies the block you are looking for and provides the block’s name, class, template file, layout xml file, and other information of significance.

Please click here, if you would like to download this extension.

The Attribute Creator Extension (Download)

When Creating Attributes, normally many different settings need to be specified as shown in the first picture below. However, the process of creating new attributes in Magento is more complicated than it truly needs to be.


The above code creates one attribute while the ‘Attribute Creator’ extension creates three attributes in only 3 lines.


By clicking here, you can download an extension that allows you to create a new attribute with one line of code as the example below illustrates. The link to this extension contains within it complete documentation of this feature.





The Super Guide to Theming in Magento 2 – Part 1 of 3

Magento 2(M2) is vastly different in its structure than Magento 1.x. When you first crack the surface of this new platform, it can seem a little daunting. You might be asking yourself “Where do I start?”, at least I did. Once you dive into M2 you will see, not only how much more organized the file structure is, but also the improvement in ability to override content/layout XML and extend JS without having to load all its dependencies. Some other improvements include the addition of HTML5 tags built into the templates, the intro of CSS3, and the use of LESS over Sass (as well as a built-in LESS preprocessor). Notably, M2 has also switched from Prototype to a jQuery library. If you have ever worked with prototype before, this is a welcomed change!

With all that being said, there are not too many resources out there for us Frontend Dev’s. I have mostly relied on the Magento 2 development docs and trial and error. My goal here is to create a well explained process of theming in Magento 2. This will be a 3 part blog series to guide you through setting up your M2 install, creating a child theme, and customizing it (and I mean really customizing it).

Installing Magento 2

As you may be aware, there are a few different ways to install Magento 2. Please refer to the Magento installation guide first if this is your first M2 install. It is also very important to check whether your server meets the minimal Magento 2 requirements:

  • Apache: 2.2 or 2.4
  • PHP: 5.5.x or 5.6.x
  • MySQL: 5.6.x


I suggest using composer when installing Magento 2. Composer enables you to manage the Magento components and their dependencies. Here are some resources to walk you through your install:

Theme structure

There are number of differences and improvements to theme structure and the fallback system in Magento 2. The fallback system in M2 works in a similar way to Magento 1.x, but now has the added advantage of being able to create unlimited parent themes. In this tutorial, we will be creating a new theme based on M2’s ‘Blank’ theme.

M2 fallback system explained

In M2, the fallback system is defined by the theme.xml file. It tells your theme which parent to fallback on. The great thing in M2 is we can declare our own fallback system within our themes.

Magento 2 has a different folder naming convention for themes than Magento 1. In Magento 1, you would create your theme within app/design/frontend/<package>/<theme>. For Magento 2, you create your theme in app/design/frontend/<vendor>/<theme>. Lets take a closer look at the pieces of the new naming convention, and therefore how you should chose your folder names:

Vendor: This is the name of the individual or company developing the code for this theme.

Theme: This can be any name that you would like to call your theme.

├── Mycompany/
│   │   ├──...default/
│   │   │   ├── ...
│   │   │   ├── ...

Above, indicates a new vendor folder with theme ‘default’.  This is based off M2’s ‘Blank’ theme. There can be multiple themes and store views under one vendor. I chose default as the base theme so when we create multiple store views the global assets for the stores will remain here. 

├── Mycompany/
│   │   ├──...default/
│   │   │   ├── ...
│   │   │   ├── ...
├── Myothercompany/
│   │   ├──...store/
│   │   │   ├── ...

Above, indicates a new vendor folder, ‘Myothercompany’,  using ‘Mycompany’ as its parent theme. In this theme you can override global assets from ‘Mycompany/default’, otherwise they will fallback in hierarchy respectively. 

In Magento 1.x, the last place Magento would look in it’s fallback system is base/default. In M2, base/default is the module. Modules are now all encapsulated. This means, instead of having all your site wide assets, js, templates, blocks and controllers in different locations, they are now organized within the module. The location of the default versions of each module can be found in app/code/Magento. The folders in the image below represent the default modules in Magento 2.


Now, let’s take a look at the structure of one of a default modules. In this case we are looking at the layered navigation module:


Here, you see that the template and layout xml files now exist in view/frontend of the module. If you want to override/extend the modules’ templates, styling or JS, you will need to create an equivalent module folder in your theme that matches the path(s) of the file(s) you wish to override/extend. If we were extending the layered navigation module, you would create a folder named Magento_LayeredNavigation and place it in your theme folder eg. <vendor>/<theme>/Magento_LayeredNavigation.

Magento_LayeredNavigation is an example of a <Namespace_Module>. Magento being the namespace and the module being LayeredNavigation separated by an underscore. If you were extending the checkout module, it would be Magento_Checkout. The process of extending <Namespace_Module>(s) will be covered in detail later in this blog series.

*Note that you can only override the contents of the view/frontend portion of the module within your theme. If you need to override Controllers and Blocks, this is done in a different location in the file structure and will not be covered in this blog series.

Creating a New Magento theme

Creating theme.xml to declare fallback system

  • Navigate to app/design/frontend
  • Create a new vendor folder in app/design/frontend/ and name it ‘Mycompany’ eg.  app/design/frontend/Mycompany
  • Create a theme folder in within your new vendor folder named ‘default’ eg. app/design/frontend/MyCompany/default


This is what your theme structure should resemble:

├── Mycompany/
│   │   ├──...default/
│   │   │   ├── ...
│   │   │   ├── ...

Next, create a theme.xml file in this directory. Copy it directly from app/design/frontend/Magento/blank/theme.xml. We are now going to declare our theme, ‘Mycompany’ and choose the appropriate parent. In this case, we are choosing /Magento/blank.

Your theme.xml should look like this:

<theme xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
 <title>Mycompany Default</title>

and should be in this location app/design/frontend/Mycompany/default/theme.xml

Make your theme a Composer package (optional)

Magento default themes are distributed as Composer packages.

To distribute your theme as a package, add a composer.json file to your theme directory and register the package on a packaging server. A default public packaging server is https://packagist.org/.

composer.json provides theme dependency information.

In our case, copy the composer.json file to the theme directory app/design/frontend/Mycompany/default and edit the orange text as follow:

    "name": "magento/theme-frontend-default",
    "description": "N/A",
    "require": {
        "php": "~5.5.0|~5.6.0|~7.0.0",
        "magento/theme-frontend-blank": "100.0.*",
        "magento/framework": "100.0.*",
        "magento/magento-composer-installer": "*"
    "type": "magento2-theme",
    "version": "100.0.1",
    "license": [
    "autoload": {
        "files": [
    "extra": {
        "map": [

You can find details about the Composer integration in the Magento system here.

Registering our theme

The next step is to register our theme. In your theme directory add a registration.php file. I suggest copying the file from app/design/frontend/Magento/blank/registration.php and editing. Your file should look like this:

* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.

Next, we will create _theme.less and folder structure where we will extend/override our theme LESS files. Create app\design\frontend\<Vendor>\<theme>\web\css\source\_theme.less. In this case our _theme.less will be in app\design\frontend\Mytheme\default\web\css\source\_theme.less

Installing and configuring Grunt

Magento has built-in Grunt tasks configured, but there are still several prerequisite steps you need to take to be able to use it. Make sure that you set your Magento application to developer in your .htaccess.

SetEnv MAGE_MODE developer

You’ll be running Magento in developer mode. In developer mode, Magento’s much more strict about PHP errors, will display raw exceptions, and make it easier to develop modules.

Next, install node.js to globally on your machine.

Install Grunt CLI tool globally. To do this, run the following in a command line:

npm install -g grunt-cli

Install (or refresh) the node.js project dependency, including Grunt, for your Magento instance. To do this, run the following in a command line:

cd <your_Magento_instance_directory>
npm install
npm update

Add your theme to Grunt configuration. To do this, in the dev/tools/grunt/configs/themes.js file, add your theme to module.exports as follows:

module.exports = {
    <theme>: {
        area: 'frontend',
        name: '<Vendor>/<theme>',
        locale: '<language>', 
        files: [
            '<path_to_file1>', //path to root source file
        dsl: 'less'

(Optional) If you want to use Grunt for “watching” changes automatically, without reloading pages in a browser each time, install the LiveReload extension in your browser.

Next, we need to clean static files and caches. In command line run:

Create directories for static files

Next we will create directories to store the static files: styles, fonts, JavaScript and images. Each type should be stored in a separate sub-directory of web in your theme folder:

├── web/
│ ├── css/
│ │ ├── source/ 
│ ├── fonts/
│ ├── images/
│ ├── js/

In the .../web/images  general theme related static files are stored. For example, a theme logo is stored in .../web/images. It is likely that your theme will also contain module-specific files, which are stored in the corresponding sub-directories, like .../<Namespace_Module>/web/css and similar.

Declaring theme logo

To declare a theme logo, add an extending default.xml to /Mycompany/de/Magento_Theme/layout/default.xml.

For example, if your logo file is my_logo.png sized 300x300px, you need to declare it as follows:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
        <referenceBlock name="logo">
                <argument name="logo_file" xsi:type="string">images/my_logo.png</argument>
                <argument name="logo_img_width" xsi:type="number">300</argument> 
                <argument name="logo_img_height" xsi:type="number">300</argument>

Declaring the logo size is optional.

Your theme directory structure 

At this point your theme file structure looks as follows:

├── default/
│   ├── etc/
│   │   ├── view.xml
│   ├── web/
│   │   ├── images/
│   │   │   ├── logo.svg
│   │   ├── css/
│   │   │   ├── source/
│   │   │   │   ├── _theme.less
│   │   ├── fonts/
│   │   ├── js/
│   ├── registration.php
│   ├── theme.xml
│   ├── composer.json

Apply your theme

Now we are ready to apply our theme to a store. Login to your magento admin and apply theme as follows:

In Admin, go to CONTENT > Design > Configuration. A Design Configuration page opens. It contains a grid with the available configuration scopes.

Design Configuration page

In the configuration record corresponding to your store view, click Edit.

On the Default Theme tab, in the Applied Theme drop-down, select your newly created theme.

Click Save.

Clear the cache.

To see your changes applied, reload the store front pages.

Now we have set up our theme and are ready to start customizing it!

What’s Next?

The next part of this blog series will cover extending, overriding and customizing our theme via <Namespace_Module>(s) and xml.



Mage Titans: Jamersan’s Chris Manger speaking

chris manger mage titansOur own Chris Manger will be speaking at Mage Titans next week in Austin Texas! He’ll be presenting the topic The Swiss Army Knife of Magento Development.  Learn how to automate attribute creation, simplify file updates after front end changes, and more!

mage titansMage Titans Austin promises to be a great event – building on the success of their UK conferences and giving it a Texas flavor! If you’re coming to Mage Titans, drop in a day early and check out the Austin OroPlatform Meetup as well! Jamersan is a key sponsor. There will be a presentation by Jary Carter, one of Oro’s founders.

Getting Magento Help with IRC

“Internet Relay Chat (IRC) is a protocol for real-time Internet text messaging (chat) or synchronous conferencing. It is mainly designed for group communication in discussion forums, called channels, but also allows one-to-one communication via private message as well as chat and data transfer, including file sharing.” – Wikipedia

It amazes me how some technologies are simple yet effective enough that they fundamentally stay unchanged for 20+ years. IRC is nearly the same as it was when I first started using it in 1992. There’s no graphics unless you send a file to someone and no “bells and whistles” to speak of. It’s plain text communication at it’s best.

It is still be a great medium to connect with people to discuss technical issues.

Before you can use this resource you’ll need a client to connect. If you are a Windows user then I recommend a program called mIRC (pronounced “Merc”) written by Khaled Mardam-Bey. It is available here: http://www.mirc.com. There’s a $20 registration fee but it’s well worth it. There are also free IRC client alternatives out there (like IceChat IRC).

There are plenty of options for Mac users to connect to IRC like LimeChat (http://limechat.net/mac/) or Textual (https://www.codeux.com/textual/).

For Ubuntu/Linux users like me, I recommend Konversation. The installation is as easy as “sudo apt-get install konversation“.

After you get your IRC client up and running, it will prompt to select a name. Enter your information to proceed.

There are lists of servers available containing thousands of chat rooms, or “channels”. The main server to find Magento and other technical help is called freenode. It is located at irc.freenode.net 6667. Type that address into your IRC client then hit Connect to jump in.

A dialog box will pop up with a list of channels. Type “#magento“, or “/join #magento” to enter the Magento help channel. There’s also “#magento2” and many other channels available. Depending on the time of day there may already be a conversation in progress.

This is a real example of someone being helped with Magento in IRC from earlier today!

A helpful document about freenode for new people is located here: http://freenode.net/kb/all.

Most people are familiar with social media so everyone knows that there’s a lot of common sense do’s and don’ts for online behavior. Social media has rules for etiquette and IRC is no different.

This is the text that is seen when entering the #magento channel. It gives helpful hints on how to interact with the people in the channel.

Here are some basic helpful tips:

  • Don’t be rude or pushy. It’s very easy for someone to be kicked and banned from IRC.
  • Don’t keep retyping your question if you don’t get an immediate answer. Your question won’t get answered any faster nor does it motivate the people that are taking the time to answer your questions to help you at all.
  • Don’t yell. ALL CAPS is still considered yelling.
  • Do be patient. If your question didn’t get answered then chances are no one is around at the time you asked it. Some people stay logged in all day on IRC but may not be looking at the chat.
  • Do ask nicely. Politeness goes a long way.
  • Do give back. Don’t just get your answer and leave. Try to help others the way that you were helped!

Your username can be registered after you connect to prevent anyone else from using it. This is accomplished by typing the following into the chat:

/msg NickServ REGISTER your_password your_email

/msg means that it’s a private message. It will show up in the chat but only you and Nickserv will be able to see it. Replace your_password with a password and your_email with your e-mail address. The e-mail address is important because Nickserv will send a confirmation phrase that will need to be entered into the chat to complete your registration.

If you’ve never used IRC before then there’s a lot of new terms to familiarize yourself with. Here are a few that everyone should know:

bot: This is a program that serves a function on IRC. Most channels have a bot to help with administration or to perform other functions (like serving up Trivia questions)

channel: IRC refers to chat rooms as “channels”. It is possible to be in many channels at the same time.

flooding: Repeating the same text over and over in an attempt to get attention or to disrupt the channel is called flooding. It’s one of the quickest ways to get kicked and banned.

kicked: Being “kicked” is getting ejected from a channel. Anyone with admin privileges (an “op”) can do this.

op: An operator, or administrator. This person can remove or permanently ban problem users from the channel.

IRC can be a great Magento resource and a great place to exchange ideas. Have fun!


Adding a CRM to your eCommerce Business Tool Box

Scale faster. Work smarter.

We all know a CRM (Customer Relationship Management) allows us to scale faster and work smarter to drive our businesses into the future with astronomical growth. But, how can a piece of software promise such a thing? The reality is — it cannot.

You, the business owner and management team, drive the company to scale faster and work smarter. A CRM is a very valuable tool you should use along the way. Your CRM is one of many tools you can use to manage and grow your business. Trying to use a hammer to sew a sock seems silly – about as silly as using a CRM without understanding what it can and what it can’t do for you. (Especially since you could probably buy everyone in Ohio, Kentucky, and Georgia a hammer for what you’ll spend doing a CRM wrong.)

What Can a CRM Do for Your Business?

  1. Improve Your Existing Data – a CRM lets you gather your business data in a central place, making it accessible and actionable in real-time across your company.
  2. Find Actionable Data – a CRM lets you set up insights into the data you collect: notify sales teams of neglected accounts, order anniversaries, etc.
  3. Manage Sales Activities – track and assign sales team member activities inside the CRM: give them direction to meet business goals and align with mission critical tasks
  4. More Informed Decision Making – perhaps the best decision-making tool you’ll ever have for your business, your CRM gives you the information you need to make critical business decisions.

One thing a CRM will not do for your business is grow sales. You do that by improving your existing data, finding actionable data, managing sales team activities, and making informed decisions. A CRM allows you to do these things most effectively and ultimately that allows you to grow sales.

What CRM Is Right for Me?

When choosing the right CRM for your business, you must first make sure that you choose the right CRM implementation partner. Having a knowledgeable and experienced guide through this process can be the difference between a successful implementation and a literal disaster.

First and foremost, remember what your CRM is designed to do: to track current and future interactions with customers for the entire organization, in other words, sales activities and opportunities. So which one is right for you? Simply put, the right CRM is the one that your people will actually use. The list of features the top CRMs come standard with is more overwhelmingly long than the menu at your average smorgasbord – and growing daily. The most sophisticated tool can be wholly useless if no one uses it because it is too complex or poorly configured.

If you are using Magento, the best choice of CRM is Oro. OroPlatform is the world’s first open source Business Application Platform and has been downloaded over 100,000 times. Oro supports out of the box integration with Magento which enables loading data to and from your store and processes it inside OroCRM. Oro gives you cross-channel data capture from all points of interaction from eCommerce and in-store purchase data to marketplaces and reseller sites and tracks data from promotions and service and support interactions. Using Oro with Magento, you get a complete CRM for client relationship management.

Jamersan is proud to be an Oro Silver Partner.

OroCRM Silver Partner


This CRM thing is the tool to end all tools for business!! Well, it can be. It can also be a tool to end a business. Rushing to implement because of the price tag – failing to detail requirements, failing to understand what you’re getting, rushing to see a return on investment, failing to guide employees through culture shock and into a new culture, these and many other factors can often lead to a huge disappointment for the business owner after surviving the CRM implementation process, which leaves them feeling as if the cure all was worse than the disease.

Jamersan works with its clients to smooth the transition from your disparate and disconnected systems to an integrated solution that gives you access to your data in actionable ways.

Product Tags Not Part of Magento 2

What are product tags?

Product tags in Magento allow users and admins to add keywords or phrases that help identify products and their features. For many users that run a Magento website, these can be thought of as similar to attributes. Think of a yellow dress being tagged ‘summer dress’, but there can also be more broad descriptive terms.  For example, the same yellow dress could be tagged as ‘pretty’, ‘cute’ or ‘brightly colored’.

Approved tags are displayed on the product details page and link to a list of all products that share the same tag. A shopper wanting to see other products marked as ‘brightly colored’ or ‘summer dress’ can click on the tag link and will be taken to a page showing only those products – thus giving shoppers another way to filter products based on their personal preferences.

Magento 2 Removes Product Tags

During Magento 2’s planning and development, Magento looked to the community for their feedback on features. Their goal was to find out not only what new features needed to be added, but also what existing features did not need to be recreated in Magento 2.

One of the features that did not receive enough support to get recreated in Magento 2 was Product Tags. The community is now looking to see which extension development group will provide this functionality for Magento 2.

Let us know what you think…

[yop_poll id=”1″]

NomadMage: Key to Employing Top Magento Developers

OK, so the title might be a little over the top, but let me explain. Good Magento developers are in-demand. They are tough to find. However, they are even tougher to hold on to if you aren’t providing them with an environment where their skills can grow and flourish.  Initiatives like NomadMage can help.

Magento developers are typically very curious and self-motivated. Why else would they have explored this little open-source platform called Magento?

If you employ Magento developers then you understand the challenges of keeping that talent. Recruiters are regularly sending them LinkedIn messages. You want great developers, yet great developers are desirable by other companies. However, you want to be able to keep them at your business.

How do you keep your best developers happy?

Providing them with the opportunity to learn and grow is one of the biggest things you can do to keep your best developers happy. However, who has loads of free time and money for formal education? I sure don’t. That’s where programs like NomadMage come in.

NomadMage is a monthly series of interactive online sessions. In these sessions, the technical leaders of our industry give presentations on topics that are important to Magento developers. It gives your developers opportunities to learn new techniques and technologies that will not only help them grow, but are vital parts of being a leading Magento 2 developer.

Conferences are a great reward for developers but the technical merits are often lacking. Many of their technical discussions are very shallow in their coverage of the topic and can often times end up being a sales pitch or a play for exposure from the speaker. That’s where NomadMage is different. There are no travel costs, and no lost work days. Your developers can ask questions and the discussions can go as deep or shallow as the participants demand.

Why does Jamersan subscribe to NomadMage?

At Jamersan, we believe in educating our team members and strive to be the best in our field. We are always evaluating new and existing technologies, finding new ways to improve upon them, and integrating them into our business process. Having my team participate in the NomadMage session is one of the ways we’ve continued to do this. The Jamersan team has already gained enough knowledge from the first broadcast of NomadMage (Vinai Kopp’s discussion on writing testable code) to more than justify the cost of purchasing team tickets for the year.

After seeing my team’s reaction to the first broadcast, I believe that NomadMage is one of those tools that will pay for itself, considerably. In my opinion, if you want to continue to foster an environment where your developers can grow, I highly suggest you make sure your team participates as well. Not only will this help you retain your top talent, but I firmly believe that your business will continue to benefit from the additional knowledge gained.

Visit NomadMage.com for more information.

Introduction to N98-Magerun


N98-Magerun (http://magerun.net/) is an essential tool for all Magento developers. It was developed and provided free of charge by netz98.de and it provides you with a simple to use Command Line Interface (CLI) tool that can work with your Magento instance. By using a CLI tool we are able to easily use N98-Magerun on any local or remote installation of Magento.

It’s fairly common for a Magento developer to know about N98-Magerun, but most developers haven’t taken the time to become familiar with it. This is probably because they do not see the value of learning yet another set of commands. This is usually due to the developer not fully understanding what benefits this set of commands provides. That being said, I feel that if you give N98-Magerun a try, you will most certainly find ways to automate and speed up your current process.


Getting started with N98-Magerun’s installation is very simple. Head on over to their GitHub page and look at the most recent installation notes.

Most users may install the tool by following these steps (this is typically installed on the same machine as the Magento installation that the tool will be operating on):

# Download the tool
wget https://files.magerun.net/n98-magerun.phar

# Set permissions to executable
chmod +x ./n98-magerun.phar

# Copy to a PATH folder to make this easily executable
sudo cp ./n98-magerun.phar /usr/local/bin/

For those of you looking to automate the process I have provided a simple bash script to install N98-Magerun here.

General Usage & Documentation Reference

On a day to day basis you should find yourself using N98-Magerun to do everything from bootstrapping a new extension to toggling template hints. Here I will cover several of the N98-Magerun commands that I have found most helpful, but you may access the full list of commands and parameters at any time using this page.

The primary reason that N98-Magerun is much simpler than manually running these types of commands via php or bash is because it automatically parses your Magento install for credentials and information- meaning you just point it to your Magento install and dump if you’re after a database. So, to begin, navigate to your Magento install’s root folder. Then do the following:


Dump A Database:

n98-magerun.phar db:dump [filename]

This will automatically connect to your DB and dump the database to [filename]. [filename] is relative to your Magento installation. This uses the same dump command each time, and provides a consistent way for an entire team to dump their databases.

Dump A Stripped Database (No sensitive data, such as customers, orders, carts, logs, or other):

n98-magerun.phar db:dump --stripped="@development" [filename]

This command works much the same way as the standard dump, however it does not include any sensitive customer data. This dump will be much smaller than a standard dump, because it includes no data for orders, quotes, customers, logs and more. This is a great tool for sending a copy of the database to a developer for working locally or for creating a dump to be used in continuous integration situations, since the smaller size will speed up automated processes. Local developers should take note of the customer:create:dummy command. This allows you to generate many dummy customers for local environments, which is very useful during debugging and/or testing.

Import A Database:

n98-magerun.phar db:import [filename]

This will automatically connect to your DB and import the database from [filename]. [filename] is relative to your Magento install.

Manually Run A Query:

n98-magerun.phar db:query [query]

This will automatically connect to your DB and run the provided [query] using the MySQL CLI tool. This does require the CLI tool be installed on the server.


List Extensions:

n98-magerun.phar dev:module:list [--codepool[="..."]] [--status[="..."]] [--vendor=[="..."]] [--format[="..."]]

This will boot up Magento and pull a list of all extensions from the configuration XML based on the parameters passed. Therefore, it is very helpful for listing out all of the disabled extensions, or auditing a site for local/community extensions.

List Extension Rewrite Conflicts:

n98-magerun.phar dev:module:rewrite:list

This will simply list any potential rewrite conflicts for your Magento installation. This is incredibly useful for debugging a problem with multiple extensions because there are usually many that operate on the same functionality in Magento.

Bootstrap A New Extension:

n98-magerun.phar dev:module:create [--add-blocks] [--add-helpers] [--add-models] [--add-setup] [--add-all] [--modman] [--add-readme] [--add-composer] [--author-name[="..."]] [--author-email[="..."]] [--description[="..."]] vendorNamespace moduleName [codePool]

This command is one of the larger commands offered by N98-Magerun, and for good reason. As you can see, using this command you can easily create a new module with any vendor name, module name, code pool, and components. This command supports modman, which will be covered in a later blog post.


Clear The Cache:

n98-magerun.phar cache:flush

This will completely empty the Magento cache by using the built-in Magento method to do so. This also means that if your cache is in REmote DIctionary Server (Redis), it will also clear it there.

Enable The Cache:

n98-magerun.phar cache:enable [code]

This enables all caching by default. However, if a [code] is specified it will only enable that specific cache.

Disable The Cache:

n98-magerun.phar cache:disable [code]

This will disable all caching by default. However, if a [code] is specified it will only disable that specific cache.


Change A Config Setting:

n98-magerun.phar config:set [--scope[="..."]] [--scope-id[="..."]] [--encrypt] [--force] path value

This command utilizes Magento to set a configuration value in the database. It supports setting the value of your config path for individual scopes. This is extremely helpful for writing a simple bash script to quickly change a Magento installation so that you can configure it for a new environment.

Toggle Template Hints:

n98-magerun.phar dev:template-hints [store_code]

This is especially relevant for developers working locally. You can easily toggle template hints without loading up the admin panel from directly in your terminal. It supports providing a [store_code] to enable or disable templates on a particular store.

Dump A Portion of XML Config:

n98-magerun.phar config:dump [path]

This tool simplifies debugging of config nodes greatly. With this, you can supply any config node (such as ‘modules’ or ‘global/catalog’). This will instantly return data about these XML nodes.

Use Cases

As previously mentioned, N98-Magerun should be used in day to day development. However, it fills a large void when it comes to automating the development workflow. N98-Magerun’s command line-based approach allows for easy use within Continous Integration tools.

For example, when we deploy a sprint for a project we automatically acquire a stripped dump for the development team within their local machines. After this, we audit the site using a simple script and N98-Magerun when our staging environment is built. We then dynamically update our Confluence pages to reflect all current extensions, observers, and extension dependencies within that copy of Magento.

Below is a list of some useful ways that you can utilize N98-Magerun locally during development. If you take advantage of the tools that N98-Magerun provides, as a result, I can assure you that you that you will have a much easier time debugging any issues that you might come across, and in the long run, you will become a better developer for doing so. Because I feel this is such an important topic, I plan to add more specific blog posts in the future that will extend your knowledge of this great tool. These posts will contain information about how we utilize each of the following convenient examples within our continuous integration tools:

  • Dump a stripped copy of the db (no sensitive user data) with n98-magerun
  • Create an admin user with n98-magerun
  • Clear the cache properly with n98-magerun
  • Toggle template hints with n98-magerun
  • List extensions for automated audits of the Magento install with n98-magerun
  • Manually trigger a Magento cron job to fire with n98-magerun


I hope this gives you a good basic understanding of what is available using n98-magerun. It seems like the biggest hurdle here is going to be just getting people to try the tool once. Once you’re in, theres no looking back- so give it a shot!

Add a permanent link to a CMS page from the Category menu in Magento.

If you have ever needed to have a category link point to a Magento CMS page, I am sure that you are aware that there are a few different ways that you can go about doing this. Here are three of the methods that I prefer to use in order to link a category menu link to a CMS page in Magento.

Edit the topmenu.phtml

If you are a Magento developer with access to the files via Secure File Transfer Protocol (SFTP) or a git repository, add the menu item by overriding /app/design/frontend/base/default/template/page/html/topmenu.phtml in your own theme.

After you copy this file into your custom theme(if this file already exists in your custom theme, you can just edit the existing file as there is no need to copy the base version), simply edit it and add the link you want before or after the Magento generated menu code and give it the relative path to CMS page (This is from a base install of Magento CE


<nav id="nav">
   <ol class="nav-primary">
      <?php echo $_menu ?>


<nav id="nav">
   <ol class="nav-primary">
      <li><a href='/' alt='My SIte'>Home</a></li>
      <?php echo $_menu ?>
      <li><a href='/about-us' alt='About Us'>About Us</a> </li>

If you don’t see your change right away, make sure you have disabled or cleared your Magento cache. Note – you may also have to modify your css to get the menu items to display properly.

Add a category in Catalog -> Manage Categories and link it to a static block

If you are not a Magento developer or you do not have access to the files, the best way to add a link to the category menu is to create content in a static block, instead of a CMS page, and then associate it with a category. This method is by far the simplest way to achieve the desired goal, and I prefer this over any other method on this page.

After you have created your CMS block, add a new category and place it where you want it in the category menu. Add the name of the menu item, set it as active, and include it in the navigation menu.


On the Display settings:
Set ‘Display Mode’ to Static Block Only
Set CMS block to the static block with the content that you want displayed
Set “Is Anchor” to No.

Click the Save Category button.


And that’s it. Reload home page. The new menu item will be there. – About Us in this case. Once again, if you don’t see your change, make sure that your old page is not cached.


 The URL Rewrite Method:

A less preferred and more involved method is to create a category item, and then use Magento’s URL rewrite system to change the URL for the category to point to a CMS page. Daniel Morales shows us how to do that on Template Monster:
http://www.templatemonster.com/help/magento-adding-page-links-in-the-navigation-bar.html I would not suggest using this method, due to its somewhat inconsistent behavior. Sometimes the URL rewrites disappear after the site reindexes, other times the rewrites stay in place. However, if you have no other option, then this is the solution for you. I would recommend testing it a few times, and manually reindexing the site to confirm that the rewrites stay in place.


Adding a menu item to link to a CMS page in a Magento website is a much needed function. Magento offers the flexibility to allow this change to be done easily, either by a developer or non-developer. There are other methods available that are not listed here.  For example: Using XML to add a CMS page to the topmenu.  The reason why I chose not to list that method here is because it is layout specific, and generally only works on “out of the box” code.  That being said, please feel free to choose the way that works best for your situation.

Simple Site Automated Development Setup with Jekyll

Getting all the right tools to work together is no easy task. Even harder to get them to work automatically. Pressing refresh for every one of your changes, be it for CSS or a blog edit, is also a hassle. When you just want to publish content or just change a color, you don’t want to spend time firing up a web server, starting the IDE, opening your browser and finding the right URL. This automated setup will do all of that for you just by opening your project. Designers and blog writers alike would make good use of this set up. For designers, there is SASS, auto vender prefixes, mixin library with a grid layout. For bloggers, simple date filename layout, with your choice of several markdown languages. Also, blog posts automatically populated with links when Jekyll compiles automatically with Gulp. These instructions will work for Linux, Unix, and OS X. 


  • Fast and simple development
  • No database or web server for development
  • Markdown blog syntax
  • Blog-aware
  • Single compiled CSS file
  • HTML / SASS changes update browser automatically
  • Opening the project in PhpStorm launches all build processes and browser
  • Automatically add vendor prefixes to CSS rules using values from Can I Use


Tools you’ll need


PhpStorm 2016.x https://www.jetbrains.com/phpstorm/
Jekyll 3.1.6 https://jekyllrb.com/
SASS 3.4.22 http://sass-lang.com/ https://github.com/sass/sass
Node.js https://nodejs.org/en/
NPM https://www.npmjs.com/

Node Js Modules
Gulp http://gulpjs.com/ Automate and enhance your workflow
Normalize SCSS https://github.com/JohnAlbin/normalize-scss , a collection of HTML element and attribute rulesets to normalize styles across all browsers
Bourbon http://bourbon.io/ a lightweight mixin library
Bourbon Neat http://neat.bourbon.io/ a mixin-based grid layout system
Browsersync https://www.browsersync.io/ a time-saving synchronised browser testing
Autoprefixer https://github.com/postcss/autoprefixer plugin to add vendor prefixes to CSS rules using values from Can I Use

  1. Download and install 30-day trial of PhpStorm https://www.jetbrains.com/phpstorm/download/
  2. Download and install current version of Node.js https://nodejs.org/en/
  3. ~ $ sudo npm install npm -g
  4. Download and install Jekyll requirements https://jekyllrb.com/docs/installation/
  5. ~ $ sudo gem install jekyll -v 3.1.6 or for 10.11 sudo gem install -n /usr/local/bin jekyll -v 3.1.6


Creating new Sites

  1. ~ $ jekyll new {path to project} i.e. jekyll new my-blog
  2. ~ $ cd {path to project} i.e. cd my-blog
  3. ~ $ npm install -S gulp
  4. ~ $ npm install -S gulp-sass
  5. ~ $ npm install -S browser-sync
  6. ~ $ npm install -S normalize-scss
  7. ~ $ npm install -S bourbon
  8. ~ $ npm install -S bourbon-neat
  9. ~ $ npm install -S gulp-autoprefixer
  10. Download https://github.com/BernardRobbins/jekyll-gulp-sass-browser-sync/blob/master/gulpfile.js into {path to project}. Now, click the “Raw” button and “save as” from browser to {path to project}.
  11. Changes need to be made to {path to project}/css/main.scss file.
    1.  Remove --- comment block
    2.  Add @import "normalize/import-now", "bourbon", "neat"; under @charset "utf-8";
  12. Add exclude: ["node_modules", "gulpfile.js", "package.json", "css/main.scss"] to {path to project}/_config.yml
  13. PhpStorm -> Create New Project from Existing Files -> Source files are in a local directory, no Web server is yet configured -> {path to project} -> click Project Root -> click Finish.
  14. PhpStorm -> Settings -> Tools -> Startup Tasks -> + Add New Configuration -> Gulp.js
    Name: Jekyll
    Gulpfile: {path to project}/gulpfile.js (should be pre-filled)
    Gulp package: {path to project}/node_modules/gulp (should be pre-filled)
  15. PhpStorm -> Run -> Run… -> Jekyll

You should now see a browser window that has opened showing the default Jekyll site.

_config.yml Jekyll options are listed on https://jekyllrb.com/docs/configuration/

Terminal Commands When Username Has an at sign “@” In It.

I recently ran into an issue where I needed to access a server remotely via ssh terminal command. I was surprised to find out that the syntax I have always used to perform such a task was not working.

The issue as it turns out, is that the server administrator created my username with an ampersand in it. Suppose you have a username of “user@domain.com” and the server name is simply “domain.com”. Given the user/server name, to ssh into this server you might want to type something like the following:

ssh user@domain.com@domain.com

The above will not work for obvious syntax reasons. The solution is to simply use the -o User option (or through the equivalent User directive found in the client configuration file at ~/.ssh/config), and specify the ip you are connecting to. So, the command that allowed me to connect actually looks something like this:

ssh -o User=user@domain.com 192.168...

This also applies to sftp, scp and sshfs as well. For example, if you wanted to copy a file from the remote server to your local machine and your username has an ampersand, the command would look something like this:

scp -o User=user@domain 192.168.xxx.xxx:\file-to-copy.txt

I should also note, that you can handle this sort of thing in your configuration file too, instead of using -o options, which provides the advantage of also working with tools that call ssh and don’t let you easily pass line options, if at all.

Introduction to Securing Your Magento Storefront

A Magento store may seem like it has not been compromised, because orders are coming in and everything looks normal. However, under the surface there could be malicious code that’s designed to grab all of the data from every form field on the site.

Most scraper hacks in Magento are effective because they’re typically buried deep within a site’s file system and may go unnoticed for long periods of time.

If your storefront is compromised, then every piece of data that has been entered may be on its way to someone intending to steal it. Most scraper hacks will use e-mail to receive the stolen form data or save it in sneaky places like your media folder for easy access later.

Hackers will often obfuscate their code to make it as unreadable as possible while still retaining the ability to execute. A hack could appear to be a nonsense jumble of code. To the untrained eye, a hack may even seem like it’s supposed to be there.

Hack example

Example of a hack designed to scrape form data

One common hack is placed in Magento’s AccountController.php or OnepageController.php. In these locations, the customer’s data can be grabbed in plain-text before it is sent to the secure credit card processor. All of the information needed to authorize a credit card transaction on a customer’s card could be in the hacker’s hands before the customer even gets to the checkout confirmation screen.

Security scans often miss these types of scrapers because the malicious code performs normal functions like processing $_POST fields and sending e-mail.

The good news is that there are ways to minimize a hacker’s ability to compromise a site in the first place by following a few simple practices.

1. Start off with a secure host

The best place to host your Magento site is with a Magento Hosting Partner.

One of the biggest mistakes I’ve seen companies make is selecting the most inexpensive web host they can find. Think of your host as the physical storefront where your store is located. Would you want to keep all of your inventory in a building without an alarm system or that has a broken front door? Cheap web hosting is fine for personal blogs or sites that don’t contain sensitive information.

2. Fix owners and permissions

Work with your web host to ensure that the file owners and permissions are set correctly. Magento also has guidelines for how this should be set up.

3. Use Secure Socket Layer (SSL)

SSL (Secure Sockets Layer) is the standard security technology for encrypting data that is transmitted from the web host to a browser. All Magento storefronts should use SSL to protect the customer’s data. SSL Certificates can be purchased from numerous companies and can easily be installed by your web host.

4. Backup, backup, backup

If your web host has an off-site backup plan for your files and database, then use it. Ensure that your data is safely backed up on regular basis with at least a two week retention policy. With this in place your site can be restored to any point within the previous two weeks. If you don’t have a backup of everything, then it’s possible that your site could be lost forever for any number of reasons.

5. Evaluate all new code

There’s a Magento extension for just about any feature imaginable but don’t get carried away when installing them!  If you’re technically inclined, then carefully review every file of a new extension before installing it. If not, then reach out to professionals to help evaluate it. Don’t install anything unless it comes from a trusted source, or you could end up adding a vulnerability to your site.

6. Keep Magento and third-party extensions updated

You must install any new patches from Magento as soon as possible. These patches are released to address a bug or security problem that Magento has fixed.

If you have third-party extensions installed then verify that you are running the most up-to-date versions to keep your site safe.

7. MageReport

Use Magereport.com to evaluate your site for missing patches and other security problems. Follow the advice that is recommended after your site analysis is complete. The people at Hypernode are frequently updating their free service to help protect the Magento community.

8. Monitoring

Check your logs for suspicious activity. This is easier said than done and can be very tedious.

The most effective installable tool that I’ve used is a package called OSSEC. OSSEC is an open source, host-based intrusion detection system (HIDS). OSSEC can analyze your logs, detect root-kits, detect log errors and monitor file system changes. If you’re interested in trying OSSEC then it can be found here: http://ossec.github.io/downloads.html. It will require some server experience to install and configure.

If you aren’t familiar with setting up server software then you should sign up for a security scanning service like Sucuri. Your web host or integration partner may recommend a similar monitoring service that works best with your hosting platform. Services like this can protect a site against many types of attacks and can perform frequent file system scans to protect against hacked files.

It’s impossible to stop all hacks. The only way to truly prevent it is to unplug the computer and never turn it back on. Since that isn’t a realistic option, you can use the advice in this article to begin to fortify your storefront and to help protect your customer’s data. 


Site Speed and Magento

Optimizing website response time is one of the most confusing aspects of running a Magento website. Many variables go into this problem: hardware, bandwidth, application layer, cloud services, database engines, load balancing, etc. For a shop owner, or even a developer, getting the environment right can be an impossibly confusing nightmare – even for one who is otherwise well-equipped to maintain and operate a Magento store.

The general consensus is that the faster a website loads, the more successful it will be in retaining visitors and converting goals. Site speed is also a critical factor in search engine ranking. When looking at ways to improve a site’s speed performance, we consider all kinds of caching – temporarily stored data on a computer’s file system or in its memory that is more quickly retrieved than the same dynamically created content it replaces.

There are a few kinds of caching that can be used in conjunction to fully and ideally optimize a site.

  • opcode – Alternative PHP Cache (APC) is an opcode cache. Integrated at the server level, it optimizes the PHP code itself.
  • cache systems for back-end and session stores – Magento /var/cache, Memcache, Remote Dictionary Server (Redis) are generic cache systems that integrate with Magento and which cache data to a file system or memory. You can use only one backend cache with Magento. You can use only one session store with Magento. My recommendation is to use Redis for the back-end cache system and session store. Memcache is an in-memory key/value store. Redis is a data structure server (which can act like a key/value store).  Magento /var/cache is the cache system built into Magento.
  • reverse proxy cache – Varnish caches responses at the server level. Magento 2 is designed to run with it and Magento 1 will need plugins such as Turpentine.


Magento Core Functionality

The least-effective, slowest cache system relies entirely on the file system. Although, if your server has Solid State Drives (SSDs), this is not necessarily true any longer. In Magento, the built in file system caching functionality stores its files in /var/cache. This cache grows as the number of products in your store grows, so a larger store will have a very slow cache system if using only the built in caching. A store with 10 products will be very fast with this cache. A store with 1000 will not.

Magento Enterprise Edition(EE) comes with a built-in full page cache. The Full Page Cache (FPC) allows you to cache pages that do not have dynamic content.  This cache will enable the pages to serve very quickly by comparison. It is possible to pass arguments to a dynamic block container and retain most of the advantage of full page caching on pages with a little dynamic content by either using Edge Side Includes (ESI, otherwise known as ‘hole punching’) or asynchronous JavaScript and XML (AJAX). (See Stack Overflow, “How do I include a dynamic block in the product page with full page caching turned on?” )

When used with a reverse proxy cache, the FPC can improve an already fast site’s performance by reducing resource usage. You can, and probably should, use a FPC and a reverse proxy cache – contrary to popular belief, perhaps. The reverse proxy cache is not application aware, but the FPC has direct access to the user session and the Magento core. Thus, they handle different situations and complement each other.


Back-end Cache Systems

Prior to Redis 3.0, there may have been strong arguments for Memcache over Redis. Now, however, Redis is the preferred method for caching because it is a data structure server and not “just” a key-value store. It offers significantly more scalability, functionality, persistence, optimistic locking, clustering, and powerful data types, and more.

For a site with significant product count or volume it is highly recommended to use Redis in lieu of Magento’s file-based caching system.

The following Magento editions support Redis session and back end caching:

  • Enterprise Edition (EE) 1.13 and later
  • Community Edition (CE) 1.8



Varnish is a reverse proxy HTTP accelerator. It is a separate service entirely (and can be on a separate web server, even). Think of it as a transparent go-between between anonymous traffic and the web server back-end. It can provide the fastest possible page load times on this kind of traffic achievable (if configured properly).

Varnish handles all of the incoming anonymous requests to your Magento shop. If it has served the page before, it sends the cached version right away, and the traffic never even gets to your database or web server (Apache, Nginx, whatever).

Varnish can also act as a load balancer.



Server optimization and site speed is a confusing yet critical aspect of a successful web presence. Don’t make the mistake of waiting to see what happens – plan for efficient, effective caching as part of every project. It may also help to consult with one of our Magento Certified Solution Specialists, who can guide you on the right path to a successful Magento store.

5 Steps to Improve your Social Media Marketing

Have you ever wondered why your Social Media isn’t where you want it to be? As the Social Media Account Specialist here at Jamersan, I’d like to share a few things that I have picked up that could help you take your business to the next level.

Step One – Make Valuable Connections.

I used to think business was 50 percent having the right people. Now I think it’s 80 percent. – Kevin P. Ryan, Internet Enterpreneur

If you have good connections on your Social Media, it will thrive. Being friends with everyone and their mother on Social Media could give less than beneficial results. In other words, having too many friends can be bad. Let’s say that you are following accounts that do not necessarily promote the best that this world has to offer. If a potential customer sees that you are following them, it could make them think that you promote or agree with that point of view. I recommend you keep it strictly business. Follow accounts that have the same goals, and views as your company.

Step Two – Know When To Post.

Depending on who you’re trying to reach, the times may vary. But, if you are trying to reach business people, office workers, or developers then post before or after the hour. Some people have meetings scheduled during the day. Meeting times may be something like this, 10am-11am, 12:30pm-1pm, 3pm-3:15pm. So like I said, before or after the hour. Example if meeting is at 11am and ends at 12pm post something around 10:55am or 12:02pm. The trick is to get people as their meeting is just about to start or right after it ends.

Step Three – Engage In Your Audience.

Ask your audience questions, do not be afraid to engage! You need to get them involved, they want their voice to be heard just as much as you want yours to be heard. The importance of building a good relationship with your audience is vital. If you don’t have a good, grounded relationship how can you expect anything to grow? Plant the seed, and then allow it time to nurture and grow. Do not rush the relationship.

Step Four –  Know The Best Platforms

I’m sure that you’ve heard of Twitter, Instagram, Facebook, and LinkedIn. Most people have heard of these Social Networks and for good reason. These are, at this time, the most popular and well known Social Media Outlets used today. Here are some of the best times that you can post to these platforms:

Twitter: Monday – Friday 12:00 – 3:00pm

Instagram: Monday – Thursdays ( except for 3:00-4:00pm)

Facebook: Wednesdays 3pm-4pm, Thursdays & Fridays 1pm-4pm, Saturdays & Sundays 12pm-1pm

LinkedIn: Tuesdays, Wednesdays, and Thursdays 7-9am, 12pm-12:30pm, 5-6pm

*  best times are according to a study done by blog.hubspot.com *

Step Five – Quality of posts.

Only share photos that are relevant to your business. You don’t want people getting the wrong idea of the intention behind your posts. Remember, quality beats quantity. Don’t just post to be posting something, have a clear objective in mind regarding that particular post. Make sure your audience gets the point of the post.

Quality is more important than quantity. One home run is much better than two doubles. – Steve Jobs

Conclusion – Make an effort, and make some time.

If you do these things your social media should improve. It may take time, and effort, so just give it your all. You have to be dedicated. Remember, make sure that you make time for this — sometimes it can be tough, but just do it. You won’t regret it.

Modern Design Tips for Developing an eCommerce Site

To say that eCommerce has grown tremendously over the past five years would be an understatement. Just as with the ever-evolving tech industry, the Internet has grown in leaps and bounds in recent years. It has become the desired medium for advertising and shopping in our modern society and for good reason: convenience. With the click of a button, consumers can have anything and everything delivered to their door within days. Brick and mortar storefronts are still a great way to start and grow a business, but in today’s retail market, it is imperative that all businesses also have an online presence.

Web development for eCommerce sites is quite an involved and complex process. There are many things to take into consideration, from marketing and design to performance and security. Our main goal, as developers, is to make the user experience (UX) as easy and intuitive as possible. Form and function are at the core of usability, but it must also be aesthetically pleasing, engaging and search engine friendly. Below are a few design and UX tips to consider during the development process.

Rewriting the Grid with Upward Responsive layouts

Responsive web design has seen a complete shift in the last 5 years and now is almost a requirement. Our techniques and approaches have evolved from the standard screen size. We have focused solely on optimizing for tablet and mobile devices, but now we are seeing an increasing trend towards browsing and shopping on high-res devices and TVs. It is time to take upward responsive layouts into consideration when designing an eCommerce store.


Firebox.com at large screen widths

According to WebDesignerDepot.com, over 32% of web users have devices with a screen resolution of 1920 pixels of higher, which demonstrates just how important it is to consider those larger sizes. Through 2016 more and more sites will take their lead from eCommerce stores that work well on large screen devices, such as FireboxSmythson and Burberry.

Large Expanding Navigation

When you are designing a eCommerce site that is packed full of information and categories, it is important to have a cohesive structure in your navigation. Categories and products should easily be accessible. The user shouldn’t have to ‘go searching’ through layers and sub layers of navigation to find what they are looking for. In the past, we literally had to ‘minimize’ the amount of links in standard dropdown menus for usability. With large, expanding menus like the mega menu, we have a lot more control over what categories and products ‘make the cut’.


Home Depot and Lowe’s mega menus

This menu style is used to direct content and the flow for the end user through a store. The navigation becomes a sales force, highlighting the most profitable and purchased products. It can also be used to guide users to popular or sales items. Take Home Depot and Lowe’s mega menus for example. The end user can easily navigate through categories without a multitude of clicks or hovers. Thus, creating a better UX.

Images Sell, Not Content

Let’s be honest, the best way to sell a product is to let it sell itself. Having engaging, beautiful and informative photographs of your products is your best marketing tool. Photographs can be used to educate, inform, inspire, evoke. They give depth and tell a story. Nowadays most people are overwhelmed with information from the web and pay more attention to visuals when browsing and shopping.


Joss and Main homepage

Photographs can communicate information very quickly. They can evoke an emotional response and create a more immersive experience than text can do alone. Take Joss and Main for example. Their home page layout depicts rooms and products so the customer can envision their products in their own home. Not to say that content is to be left on the back burner. Rich content is essential for SEO, but with new SEO strategies like Schema, we no longer need to rely on text based content solely to drive traffic.

Material design for layout

Last year, Google launched its new style language, Material Design. It uses shadows, layers, movement and depth of objects in order to create layouts that appear more realistic and engaging to the user. Material design is a more clean and modern approach. It engages the user and focuses on UX and interaction with elements. It has a minimalistic approach and similar to a common and growing design trend – flat design.



Success of any eCommerce site lies in improving UX, keeping it simple, and gaining the customer’s trust. We should be taking usability and design into consideration in all aspects of our development process. Speed and optimization are important, but what’s the point if the user can’t properly navigate or find what they are looking for in a crowded layout? It is proven that a consumer will decide in 3 seconds if they are going to stay on a site or not… so let’s keep them there!


What are Directives in Magento and How to Use Them

What is a Directive?

From time to time, in Magento, you may run across code snippets with two squiggly opening and closing brackets.
What are those “squiggly bracketed” snippets of code officially called? They are called directives. These are very similar to “shortcodes” in WordPress. The first word after the two opening squiggly brackets is the name of the directive. So, in the picture on the right, we have examples of the skin directive, media directive, config directive, store directive, and the customvar directive.

What is the purpose of a directive? To put it simply, a directive executes code that inserts content onto a page or email.

What is the Output Generated by the Directives in The above Image?

The above image is a picture of the location in the Magento CMS where you can edit the text on the homepage. So, I’m going to refresh the homepage to see what the directives do……….


The directives in the very first image of this article produce the output shown directly above. Below, is a summary of what is going on:


What do Each of These Directives Do?

The “config” Directive

The first two examples in the above image are “config” directives. These directives are calling the function Mage::getStoreConfig($path). They are passing the “path” into this function. How do we know the Mage::getStoreConfig() function is being called?

Every directive has one function that is responsible for outputting it. The function responsible for outputting the “config” directive is called configDirective. The function responsible for outputting the “media” directive is called mediaDirective. The function that outputs the “skin” directive is called skinDirective. And, so on, and so forth….

All of the functions that output the directives in the above image are located in the class Mage_Core_Model_Email_Template_Filter.

Let’s take a look at the configDirective function:


The above picture shows that the “path” is being inserted into the Mage::getStoreConfig($path) function. Please note that the value of $params[‘path’] is the value you passed into it (general/locale/timezone) as the picture below illustrates.


The getStoreConfig($path) function is pulling data from the core_config_data table. There is a column in this table called path. This function will find the row in this table whose path is equal to the value we specified, “general/locale/timezone”. Then, this function will pull the ‘value’   from this row. The ‘value’ is then output to your screen.

(note: there are certain circumstances where this value will come from a config.xml if it does not exist in the database.)

Please note, for the “config” directive to work, please insert the path you want to output into the permission_variable table. And, please be sure to set the is_allowed column in this table to 1. Then, press the “Flush Cache Storage” button.

The “customvar” Directive

Go to “System” –> “Custom Variables” in the Magento admin and create a custom variable. This “customvar” directive can retrieve the value of any custom variable you have created.

The image below shows the parameter called “code”. The parameter is the part within the squiggly brackets that comes after the directive (the word “customvar” is the directive). The image below shows that the parameter called code. This parameter is set equal to “test_custom_variable”


Please observe how, in the picture below, $params[‘code’] is equal to the value of the parameter, which is “test_custom_variable”. When the code below calls loadByCode(), this retrieves a value from the core_variable table.


The “media” Directive

The media directive looks for and retrieves a url. The path must correspond to a location within the media directory. For example, the directive below……..


Refers to this location in the media folder……….


The picture of the mediaDirective function below contains $params[‘url’]. $params[‘url’] is equal to the value of the parameter called “url”.


The parameters are those things that come after the name of the directive (which is media). Therefore, the image below shows that “url” is the name of the parameter.


The “skin” Directive

The skin directive looks for and retrieves a url. The path must correspond to a location within the skin directory. For example, the parameter called url in the picture below contains the value “images/centinel/sc_learn_62x34.png”.


This refers to this location in the skin folder pictured below……….


And, here is the function that is used to output the skin directive. The reason why the parameter we are using above is called “url” is because the code below contains $params[‘url’]


The “block” Directive

In the Magento CMS editor, I typed in the following directives………..


These directives in the picture above produce the colored blocks shown below…………


Please note, if type is anything different than “core/template”. Then, please add the type to the “permission_block” table and then press the “Flush Cache” storage button. This step must be performed otherwise the “block” directive will be unable to output the block.

The Layout Directive

The layout directive is used to output multiple blocks. Here is a picture of a handle called “custom_handle_for_blocks” in one of my layout.xml files.


Here is the directive that I am calling:


Here is the result:


The layout directive is used in the email that is sent to the customer after an order is placed. This directive is used to load blocks that list all of the items the customer has purchased.

What directives can you use in emails?

You can use all of these directives mentioned in this article in emails too!

Where can Directives be Used?

In the above examples, these directives are being entered into the CMS editor for the home page. But, directives can be used in many other places as well. They can be used on the product detail page, emails, and in newsletters.

Adding Your Own Directives

You can create your own directives:

  • To add a directive that can be used on a CMS page overwrite this node: config/global/cms/page/template_filter
  • To add a directive that can be used on a CMS block overwrite this node:
  • config/global/cms/block/template_filter
  • To add a directive that can be used on the product detail page overwrite this node:
  • config/global/catalog/content/tempate_filter
  • To add a directive that can be used on newsletters overwrite this node:
  • config/global/newsletter/tempate_filter



Two exciting announcements from Jamersan and Oro!

Jamersan has two exciting announcements in the OroPlatform arena!

OroCRM Silver PartnerAt the end of Q3, Jamersan became an OroCRM Silver Partner! This means that we have access to all of resources, code, demos, etc., to begin implementing OroPlaform, OroCRM and OroCommerce at Jamersan. Contact us if you would like a demo.

Austin OroPlatform MeetupOn August 2, 2016, Jamersan will sponsor an OroPlatform Meetup in Austin, Texas. This is the first OroPlatform Meetup in the United States, and only the second in the world! The Austin OroPlatform Meetups will be held the first Tuesday of every month. To sign up for our Austin, Texas OroPlatform Meetup group, please visit: http://www.meetup.com/Austin-OroPlatform-Meetup/

Oro – the Web 3.0 Business Application Platform that Means “Gold”

We recently learned about a new wave of technology, brought to us by old friends – OroPlatform by Oro, Inc. Oro’s dream team lineup includes the original team who brought us Magento…Yoav Kutner as CEO, Dima Soroka as CTO, Jary Carter as Chief Revenue Officer, and Roy Rubin as Advisor.

OroPlatform’s architecture is based on ready-to-use mini-applications, or bundles, which can talk natively via php to other bundles written on OroPlatform. This means the end of giant, overblown business applications. As we have seen with open source ecommerce development, there will be an overall shift to rapid application development focused on a community of interconnected bundles – each of which you can use, re-use, extend, or disregard – the choice is yours.

Web 3.0 functionality like workflow and access control lists are built into OroPlatform’s out-of-the-box bundles. OroPlatform will integrate with your current user management system via an LDAP bundle, and will let you secure it all with a Security Bundle.

OroPlatform started because Yoav and the team saw a need for an open source CRM. While they were constructing OroCRM, the Oro team decided at the same time to build a standard set of tools so they could keep building interconnected business applications. Thus OroPlatform, the world’s first and only open source Business Application Platform, or BAP, was born.

While the OroPlatform BAP is new to us, it started in 2012, and there are already several out-of-the-box applications that are written for OroPlatform. These include Akeneo Product Information Management (PIM) Tool, Diamante Desk Enterprise Help Desk, TimeLap time tracking software, Marello Enterprise Resource Planning (ERP), as well as OroCommerce, which is due Q4 2016.

OroPlatform is easy to learn for PHP developers, as it is based on the popular Symfony 2 framework and runs on the LAMP stack.

OroPlatform is completely free to download and use. OroCRM is available either stand-alone or as an extensible hosted solution – please call us for pricing.

If you’d like to talk about how Jamersan can help your organization get started with OroCRM, OroCommerce, or other applications on the OroPlatform, please contact us.

Pre-Imagine is a must attend for Magento Developers

If you’ve ever been to the Magento Imagine Conference, then I hope you arrived early and visited the Pre-Imagine event that occurs on Sunday prior to the conference start on Monday. If you haven’t, you’ve missed the best opportunity for networking that exists at the event!

Arrive early before the crowd shows up so you can easily network with other Magento developers and users and take advantage of the lack of lines to go ahead and complete your registration for the Imagine event and pick up your swag bag!

Joseph over at Imagination Media strapped on his handy GoPro and filmed an awesome video of the 2016 Pre-Imagine event from an interesting perspective. View the video of the Magento Pre-Imagine gathering on Imagination Media’s site.

Using Guzzle Without Composer

While working on a module to integrate Magento with Foxy Cart’s awesome checkout service, I came across the need to use Guzzle in my Magento module. Because I am building the initial version of this module using Magento 1.x, I could not be certain that users of this module would have Composer available.

To accomplish this task, I had to put together a basic autoloader.php class that would serve as my autoloader for not only Guzzle, but any library that it or my script requires.

To start, I create a Magento module like any other module. In my app/code/Namespace/Module folder, I create a folder named “lib” for my includes. In this folder, I added the following libraries:

1. Doctrine/Common/Cache
2. GuzzleHttp
3. React/Promise
4. Riimu/Kit

I also added a file named autoloader.php. I started with the proper autoloader.php from the zip file download of GuzzleHttp, but then added all the other library includes that I may need. The resulting file is below:

$mapping = array( 'React\Promise\CancellablePromiseInterface' => __DIR__ . '/React/Promise/CancellablePromiseInterface.php',<br ?--> 'React\Promise\Deferred' => __DIR__ . '/React/Promise/Deferred.php',
'React\Promise\ExtendedPromiseInterface' => __DIR__ . '/React/Promise/ExtendedPromiseInterface.php',
'React\Promise\FulfilledPromise' => __DIR__ . '/React/Promise/FulfilledPromise.php',
'React\Promise\LazyPromise' => __DIR__ . '/React/Promise/LazyPromise.php',
'React\Promise\Promise' => __DIR__ . '/React/Promise/Promise.php',
'React\Promise\PromiseInterface' => __DIR__ . '/React/Promise/PromiseInterface.php',
'React\Promise\PromisorInterface' => __DIR__ . '/React/Promise/PromisorInterface.php',
'React\Promise\RejectedPromise' => __DIR__ . '/React/Promise/RejectedPromise.php',
'React\Promise\UnhandledRejectionException' => __DIR__ . '/React/Promise/UnhandledRejectionException.php',
'React\Promise\functions' => __DIR__ . '/React/Promise/functions.php',
'React\Promise\functions_include' => __DIR__ . '/React/Promise/functions_include.php',
'GuzzleHttp\Stream\AppendStream' => __DIR__ . '/GuzzleHttp/Stream/AppendStream.php',
'GuzzleHttp\Stream\AsyncReadStream' => __DIR__ . '/GuzzleHttp/Stream/AsyncReadStream.php',
'GuzzleHttp\Stream\BufferStream' => __DIR__ . '/GuzzleHttp/Stream/BufferStream.php',
'GuzzleHttp\Stream\CachingStream' => __DIR__ . '/GuzzleHttp/Stream/CachingStream.php',
'GuzzleHttp\Stream\DroppingStream' => __DIR__ . '/GuzzleHttp/Stream/DroppingStream.php',
'GuzzleHttp\Stream\Exception\CannotAttachException' => __DIR__ . '/GuzzleHttp/Stream/Exception/CannotAttachException.php',
'GuzzleHttp\Stream\Exception\SeekException' => __DIR__ . '/GuzzleHttp/Stream/Exception/SeekException.php',
'GuzzleHttp\Stream\FnStream' => __DIR__ . '/GuzzleHttp/Stream/FnStream.php',
'GuzzleHttp\Stream\GuzzleStreamWrapper' => __DIR__ . '/GuzzleHttp/Stream/GuzzleStreamWrapper.php',
'GuzzleHttp\Stream\InflateStream' => __DIR__ . '/GuzzleHttp/Stream/InflateStream.php',
'GuzzleHttp\Stream\LazyOpenStream' => __DIR__ . '/GuzzleHttp/Stream/LazyOpenStream.php',
'GuzzleHttp\Stream\LimitStream' => __DIR__ . '/GuzzleHttp/Stream/LimitStream.php',
'GuzzleHttp\Stream\MetadataStreamInterface' => __DIR__ . '/GuzzleHttp/Stream/MetadataStreamInterface.php',
'GuzzleHttp\Stream\NoSeekStream' => __DIR__ . '/GuzzleHttp/Stream/NoSeekStream.php',
'GuzzleHttp\Stream\NullStream' => __DIR__ . '/GuzzleHttp/Stream/NullStream.php',
'GuzzleHttp\Stream\PumpStream' => __DIR__ . '/GuzzleHttp/Stream/PumpStream.php',
'GuzzleHttp\Stream\Stream' => __DIR__ . '/GuzzleHttp/Stream/Stream.php',
'GuzzleHttp\Stream\StreamDecoratorTrait' => __DIR__ . '/GuzzleHttp/Stream/StreamDecoratorTrait.php',
'GuzzleHttp\Stream\StreamInterface' => __DIR__ . '/GuzzleHttp/Stream/StreamInterface.php',
'GuzzleHttp\Stream\Utils' => __DIR__ . '/GuzzleHttp/Stream/Utils.php',
'GuzzleHttp\Ring\Client\ClientUtils' => __DIR__ . '/GuzzleHttp/Ring/Client/ClientUtils.php',
'GuzzleHttp\Ring\Client\CurlFactory' => __DIR__ . '/GuzzleHttp/Ring/Client/CurlFactory.php',
'GuzzleHttp\Ring\Client\CurlHandler' => __DIR__ . '/GuzzleHttp/Ring/Client/CurlHandler.php',
'GuzzleHttp\Ring\Client\CurlMultiHandler' => __DIR__ . '/GuzzleHttp/Ring/Client/CurlMultiHandler.php',
'GuzzleHttp\Ring\Client\Middleware' => __DIR__ . '/GuzzleHttp/Ring/Client/Middleware.php',
'GuzzleHttp\Ring\Client\MockHandler' => __DIR__ . '/GuzzleHttp/Ring/Client/MockHandler.php',
'GuzzleHttp\Ring\Client\StreamHandler' => __DIR__ . '/GuzzleHttp/Ring/Client/StreamHandler.php',
'GuzzleHttp\Ring\Core' => __DIR__ . '/GuzzleHttp/Ring/Core.php',
'GuzzleHttp\Ring\Exception\CancelledException' => __DIR__ . '/GuzzleHttp/Ring/Exception/CancelledException.php',
'GuzzleHttp\Ring\Exception\CancelledFutureAccessException' => __DIR__ . '/GuzzleHttp/Ring/Exception/CancelledFutureAccessException.php',
'GuzzleHttp\Ring\Exception\ConnectException' => __DIR__ . '/GuzzleHttp/Ring/Exception/ConnectException.php',
'GuzzleHttp\Ring\Exception\RingException' => __DIR__ . '/GuzzleHttp/Ring/Exception/RingException.php',
'GuzzleHttp\Ring\Future\BaseFutureTrait' => __DIR__ . '/GuzzleHttp/Ring/Future/BaseFutureTrait.php',
'GuzzleHttp\Ring\Future\CompletedFutureArray' => __DIR__ . '/GuzzleHttp/Ring/Future/CompletedFutureArray.php',
'GuzzleHttp\Ring\Future\CompletedFutureValue' => __DIR__ . '/GuzzleHttp/Ring/Future/CompletedFutureValue.php',
'GuzzleHttp\Ring\Future\FutureArray' => __DIR__ . '/GuzzleHttp/Ring/Future/FutureArray.php',
'GuzzleHttp\Ring\Future\FutureArrayInterface' => __DIR__ . '/GuzzleHttp/Ring/Future/FutureArrayInterface.php',
'GuzzleHttp\Ring\Future\FutureInterface' => __DIR__ . '/GuzzleHttp/Ring/Future/FutureInterface.php',
'GuzzleHttp\Ring\Future\FutureValue' => __DIR__ . '/GuzzleHttp/Ring/Future/FutureValue.php',
'GuzzleHttp\Ring\Future\MagicFutureTrait' => __DIR__ . '/GuzzleHttp/Ring/Future/MagicFutureTrait.php',
'GuzzleHttp\BatchResults' => __DIR__ . '/GuzzleHttp/BatchResults.php',
'GuzzleHttp\Client' => __DIR__ . '/GuzzleHttp/Client.php',
'GuzzleHttp\ClientInterface' => __DIR__ . '/GuzzleHttp/ClientInterface.php',
'GuzzleHttp\Collection' => __DIR__ . '/GuzzleHttp/Collection.php',
'GuzzleHttp\Cookie\CookieJar' => __DIR__ . '/GuzzleHttp/Cookie/CookieJar.php',
'GuzzleHttp\Cookie\CookieJarInterface' => __DIR__ . '/GuzzleHttp/Cookie/CookieJarInterface.php',
'GuzzleHttp\Cookie\FileCookieJar' => __DIR__ . '/GuzzleHttp/Cookie/FileCookieJar.php',
'GuzzleHttp\Cookie\SessionCookieJar' => __DIR__ . '/GuzzleHttp/Cookie/SessionCookieJar.php',
'GuzzleHttp\Cookie\SetCookie' => __DIR__ . '/GuzzleHttp/Cookie/SetCookie.php',
'GuzzleHttp\Event\AbstractEvent' => __DIR__ . '/GuzzleHttp/Event/AbstractEvent.php',
'GuzzleHttp\Event\AbstractRequestEvent' => __DIR__ . '/GuzzleHttp/Event/AbstractRequestEvent.php',
'GuzzleHttp\Event\AbstractRetryableEvent' => __DIR__ . '/GuzzleHttp/Event/AbstractRetryableEvent.php',
'GuzzleHttp\Event\AbstractTransferEvent' => __DIR__ . '/GuzzleHttp/Event/AbstractTransferEvent.php',
'GuzzleHttp\Event\BeforeEvent' => __DIR__ . '/GuzzleHttp/Event/BeforeEvent.php',
'GuzzleHttp\Event\CompleteEvent' => __DIR__ . '/GuzzleHttp/Event/CompleteEvent.php',
'GuzzleHttp\Event\Emitter' => __DIR__ . '/GuzzleHttp/Event/Emitter.php',
'GuzzleHttp\Event\EmitterInterface' => __DIR__ . '/GuzzleHttp/Event/EmitterInterface.php',
'GuzzleHttp\Event\EndEvent' => __DIR__ . '/GuzzleHttp/Event/EndEvent.php',
'GuzzleHttp\Event\ErrorEvent' => __DIR__ . '/GuzzleHttp/Event/ErrorEvent.php',
'GuzzleHttp\Event\EventInterface' => __DIR__ . '/GuzzleHttp/Event/EventInterface.php',
'GuzzleHttp\Event\HasEmitterInterface' => __DIR__ . '/GuzzleHttp/Event/HasEmitterInterface.php',
'GuzzleHttp\Event\HasEmitterTrait' => __DIR__ . '/GuzzleHttp/Event/HasEmitterTrait.php',
'GuzzleHttp\Event\ListenerAttacherTrait' => __DIR__ . '/GuzzleHttp/Event/ListenerAttacherTrait.php',
'GuzzleHttp\Event\ProgressEvent' => __DIR__ . '/GuzzleHttp/Event/ProgressEvent.php',
'GuzzleHttp\Event\RequestEvents' => __DIR__ . '/GuzzleHttp/Event/RequestEvents.php',
'GuzzleHttp\Event\SubscriberInterface' => __DIR__ . '/GuzzleHttp/Event/SubscriberInterface.php',
'GuzzleHttp\Exception\BadResponseException' => __DIR__ . '/GuzzleHttp/Exception/BadResponseException.php',
'GuzzleHttp\Exception\ClientException' => __DIR__ . '/GuzzleHttp/Exception/ClientException.php',
'GuzzleHttp\Exception\ConnectException' => __DIR__ . '/GuzzleHttp/Exception/ConnectException.php',
'GuzzleHttp\Exception\CouldNotRewindStreamException' => __DIR__ . '/GuzzleHttp/Exception/CouldNotRewindStreamException.php',
'GuzzleHttp\Exception\ParseException' => __DIR__ . '/GuzzleHttp/Exception/ParseException.php',
'GuzzleHttp\Exception\RequestException' => __DIR__ . '/GuzzleHttp/Exception/RequestException.php',
'GuzzleHttp\Exception\ServerException' => __DIR__ . '/GuzzleHttp/Exception/ServerException.php',
'GuzzleHttp\Exception\StateException' => __DIR__ . '/GuzzleHttp/Exception/StateException.php',
'GuzzleHttp\Exception\TooManyRedirectsException' => __DIR__ . '/GuzzleHttp/Exception/TooManyRedirectsException.php',
'GuzzleHttp\Exception\TransferException' => __DIR__ . '/GuzzleHttp/Exception/TransferException.php',
'GuzzleHttp\Exception\XmlParseException' => __DIR__ . '/GuzzleHttp/Exception/XmlParseException.php',
'GuzzleHttp\HasDataTrait' => __DIR__ . '/GuzzleHttp/HasDataTrait.php',
'GuzzleHttp\Message\AbstractMessage' => __DIR__ . '/GuzzleHttp/Message/AbstractMessage.php',
'GuzzleHttp\Message\AppliesHeadersInterface' => __DIR__ . '/GuzzleHttp/Message/AppliesHeadersInterface.php',
'GuzzleHttp\Message\FutureResponse' => __DIR__ . '/GuzzleHttp/Message/FutureResponse.php',
'GuzzleHttp\Message\MessageFactory' => __DIR__ . '/GuzzleHttp/Message/MessageFactory.php',
'GuzzleHttp\Message\MessageFactoryInterface' => __DIR__ . '/GuzzleHttp/Message/MessageFactoryInterface.php',
'GuzzleHttp\Message\MessageInterface' => __DIR__ . '/GuzzleHttp/Message/MessageInterface.php',
'GuzzleHttp\Message\MessageParser' => __DIR__ . '/GuzzleHttp/Message/MessageParser.php',
'GuzzleHttp\Message\Request' => __DIR__ . '/GuzzleHttp/Message/Request.php',
'GuzzleHttp\Message\RequestInterface' => __DIR__ . '/GuzzleHttp/Message/RequestInterface.php',
'GuzzleHttp\Message\Response' => __DIR__ . '/GuzzleHttp/Message/Response.php',
'GuzzleHttp\Message\ResponseInterface' => __DIR__ . '/GuzzleHttp/Message/ResponseInterface.php',
'GuzzleHttp\Mimetypes' => __DIR__ . '/GuzzleHttp/Mimetypes.php',
'GuzzleHttp\Pool' => __DIR__ . '/GuzzleHttp/Pool.php',
'GuzzleHttp\Post\MultipartBody' => __DIR__ . '/GuzzleHttp/Post/MultipartBody.php',
'GuzzleHttp\Post\PostBody' => __DIR__ . '/GuzzleHttp/Post/PostBody.php',
'GuzzleHttp\Post\PostBodyInterface' => __DIR__ . '/GuzzleHttp/Post/PostBodyInterface.php',
'GuzzleHttp\Post\PostFile' => __DIR__ . '/GuzzleHttp/Post/PostFile.php',
'GuzzleHttp\Post\PostFileInterface' => __DIR__ . '/GuzzleHttp/Post/PostFileInterface.php',
'GuzzleHttp\Query' => __DIR__ . '/GuzzleHttp/Query.php',
'GuzzleHttp\QueryParser' => __DIR__ . '/GuzzleHttp/QueryParser.php',
'GuzzleHttp\RequestFsm' => __DIR__ . '/GuzzleHttp/RequestFsm.php',
'GuzzleHttp\RingBridge' => __DIR__ . '/GuzzleHttp/RingBridge.php',
'GuzzleHttp\Subscriber\Cookie' => __DIR__ . '/GuzzleHttp/Subscriber/Cookie.php',
'GuzzleHttp\Subscriber\History' => __DIR__ . '/GuzzleHttp/Subscriber/History.php',
'GuzzleHttp\Subscriber\HttpError' => __DIR__ . '/GuzzleHttp/Subscriber/HttpError.php',
'GuzzleHttp\Subscriber\Mock' => __DIR__ . '/GuzzleHttp/Subscriber/Mock.php',
'GuzzleHttp\Subscriber\Prepare' => __DIR__ . '/GuzzleHttp/Subscriber/Prepare.php',
'GuzzleHttp\Subscriber\Redirect' => __DIR__ . '/GuzzleHttp/Subscriber/Redirect.php',
'GuzzleHttp\ToArrayInterface' => __DIR__ . '/GuzzleHttp/ToArrayInterface.php',
'GuzzleHttp\Transaction' => __DIR__ . '/GuzzleHttp/Transaction.php',
'GuzzleHttp\UriTemplate' => __DIR__ . '/GuzzleHttp/UriTemplate.php',
'GuzzleHttp\Url' => __DIR__ . '/GuzzleHttp/Url.php',
'GuzzleHttp\Utils' => __DIR__ . '/GuzzleHttp/Utils.php',
'GuzzleHttp\Subscriber\Cache\CacheSubscriber' => __DIR__ . '/GuzzleHttp/Subscriber/Cache/CacheSubscriber.php',
'GuzzleHttp\Subscriber\Cache\CacheStorage' => __DIR__ . '/GuzzleHttp/Subscriber/Cache/CacheStorage.php',
'GuzzleHttp\Subscriber\Cache\CacheStorageInterface' => __DIR__ . '/GuzzleHttp/Subscriber/Cache/CacheStorageInterface.php',
'GuzzleHttp\Subscriber\Cache\ValidationSubscriber' => __DIR__ .
'GuzzleHttp\Subscriber\Cache\PurgeSubscriber' => __DIR__ .
'GuzzleHttp\Subscriber\Cache\Utils' => __DIR__ .
'Doctrine\Common\Cache\ArrayCache' => __DIR__ . '/Doctrine/Common/Cache/ArrayCache.php',
'Doctrine\Common\Cache\CacheProvider' => __DIR__ . '/Doctrine/Common/Cache/CacheProvider.php',
'Doctrine\Common\Cache\Cache' => __DIR__ . '/Doctrine/Common/Cache/Cache.php',
'Doctrine\Common\Cache\FlushableCache' => __DIR__ . '/Doctrine/Common/Cache/FlushableCache.php',
'Doctrine\Common\Cache\ClearableCache' => __DIR__ . '/Doctrine/Common/Cache/ClearableCache.php',
'Doctrine\Common\Cache\MultiGetCache' => __DIR__ . '/Doctrine/Common/Cache/MultiGetCache.php',
'Doctrine\Common\Cache\MultiPutCache' => __DIR__ . '/Doctrine/Common/Cache/MultiPutCache.php',
'Riimu\Kit\CSRF\CSRFHandler' => __DIR__ . '/Riimu/Kit/CSRF/CSRFHandler.php',
'Riimu\Kit\CSRF\Storage\SessionStorage' => __DIR__ . '/Riimu/Kit/CSRF/Storage/SessionStorage.php',
'Riimu\Kit\CSRF\Storage\TokenStorage' => __DIR__ . '/Riimu/Kit/CSRF/Storage/TokenStorage.php',
'Riimu\Kit\CSRF\Source\PostSource' => __DIR__ . '/Riimu/Kit/CSRF/Source/PostSource.php',
'Riimu\Kit\CSRF\Source\TokenSource' => __DIR__ . '/Riimu/Kit/CSRF/Source/TokenSource.php',
'Riimu\Kit\CSRF\Source\HeaderSource' => __DIR__ . '/Riimu/Kit/CSRF/Source/HeaderSource.php',
'Riimu\Kit\SecureRandom\SecureRandom' => __DIR__ . '/Riimu/Kit/SecureRandom/SecureRandom.php',
'Riimu\Kit\SecureRandom\Generator\RandomReader' => __DIR__ . '/Riimu/Kit/SecureRandom/Generator/RandomReader.php',
'Riimu\Kit\SecureRandom\Generator\AbstractGenerator' => __DIR__ . '/Riimu/Kit/SecureRandom/Generator/AbstractGenerator.php',
'Riimu\Kit\SecureRandom\Generator\Generator' => __DIR__ . '/Riimu/Kit/SecureRandom/Generator/Generator.php'

spl_autoload_register(function ($class) use ($mapping) {
if (isset($mapping[$class])) {
require $mapping[$class];
}, true);

require __DIR__ . ‘/React/Promise/functions.php’;


In my class that needs to use Guzzle, I then add this to the top of the class file:

require Mage::getModuleDir('','Jamersan_Foxy').DS.'lib'.DS.'autoloader.php';
use GuzzleHttp\Subscriber\Cache\CacheSubscriber;
use GuzzleHttp\Client;

That should do it! After adding these items, you should now be able to use Guzzle in your Magento module!

Going To Industry Conferences Is A Must

Since I founded Jamersan, we have been a small development shop. I spent the early years making some great strategic partnerships that helped us not have to do sales yet stay swamped with work. Because we were always swamped and “head down” getting work done, we never spent much time thinking about industry conferences such as SunshinePHP or Magento’s Imagine Conference. It was a mistake I wish I could go back and undo sooner.

Conferences have the obvious benefit of being a great place to network and get to know fellow developers in the industry. It’s a great place to build those relationships you’ll need to grow and recruit the top talent. We met some great PHP and Magento developers at SunshinePHP 2016. We had a great dinner at Prime 112 with Ben Marks and Phillip Jackson compliments of Miami locals Imagination Media. As expected, the networking was fantastic.

By being “too busy” during our early years of being in business, who knows how many opportunities for work or potential employees we missed by not properly networking? It’s probably the single biggest reason it took so long for us to start growing.

I wished we had taken advantage of all those years of networking opportunities. However, the thing that I believe I missed out on the most was keeping up with all the technologies and techniques that the best shops are using. I took us growing and hiring top talent before we started recognizing the tools they used at their previous employers.

There are a ton of modern tools out there to help developers be the best they can be. In my desire to make Jamersan the best development shop that it can be, I am confident that we could have gotten there much earlier by visiting more industry conferences and listening to the great talks that they have put together.

I will make a point in the future to get more of my developers to conferences. Conferences can be expensive endeavors for a small business. In addition to travel, lodging, and tickets, time not coding is time not billing. Regardless, if you are building a business and want to get better and do so rapidly, you need to find conferences in your industry and get as many of your developers to it as you can reasonably afford.

You won’t regret it.

Certified Magento Developers Wanted

We’re looking to add quality certified Magento developers with WordPress experience. Experience with PHP, CSS and template customizations a must, some experience with custom modules/plug-ins and experience with Git implementations highly preferred.

Jamersan is a fast growing e-commerce company based in Alabama but with a distributed remote team in states such as Georgia, Texas, Florida, Michigan, and Colorado.

We want the best talent, so working remotely is always an option! We offer a competitive salary and a benefits package that includes insurance, paid time off, and a generous profit-sharing plan.

Interested? Please contact us.

Jamersan, LLC is an equal opportunity employer.

Google Mobile Usability warnings

Google is sending out mobile usability warning emails like this:



with more and more web usage going mobile, with phones, tablets, and the like, and with modern screen sizes for PCs varying from laptop screens to TV sizes, responsive design is the only way to go. Responsive designs adapt to the environment they’re in (phone, tablet, browser window size) and change accordingly. This has positive effects on user interaction as well as search engine optimization (SEO) and even the cost of your pay-per-click (PPC) campaigns.

If you haven’t gotten an email like this (they’re going to Google Analytics users), but would like to see what Google thinks of your site’s mobile-friendliness, you can type your web address into this tool:


If you don’t like what you see, or just need help with SEO, running your PPC campaign, managing your content, contact us today.


Easy 301 Redirect

Just add the following to the .htaccess file in the correct directory of the pages you would like to redirect.

RewriteEngine On
Redirect 301 /shop/oldFILE.html http://mywebsite.com/shop/new-subfolder-if-needed/newFILE.html

Lather, Rinse, Wash, Repeat….as needed.


Remove “+” (plus symbol) from Custom Option Prices in Magento

Create the following file structure to avoid making any changes to the Magento Core files.


Then open and and copy the content from app/code/core/Mage/Catalog/Block/Product/View/Options/Abstract.php into the Abstract.php file you just created in your local folder.

In your new Abstract.php file run a search for $sign = ‘+’; (It’s in the _formatPrice function if your search doesn’t work)

Replace the ‘+’ with ‘ ‘.

Save, Upload, Enjoy!

Magento: Setting order quote’s tax rate based on shipping

One of our customers recently approached us to add an in-store pickup module to their Magento website. No problem, this is a pretty simple task and we quickly setup the module. However, the customer then notified us that they needed to start charging their city tax for orders that are picked up from one of their stores. After much searching, I didn’t find many leads on how to do this, so now that I have figured it out I thought I would post it here in case someone else had the same problem. I am going to stick to the high level abstraction on most of this and assume you know how to build a Magento module.

First, you need to create your module and add an observer that hooks into the event you want to set the tax rate after. In our case, we are changing the rate after the user chooses shipping, so we created an observer on the checkout_controller_onepage_save_shipping_method event.

Second, you’ll need to set up a customer group and assign it a new tax rate. Do this through the Magento admin.

The trick is that you can’t set the tax rate on the quote item iteslf. If you dig into the Magento code, you’ll find that when you get the tax rate on the quote, it actually returns it from the customer group and not the quote.

If the user is logged in, you actually have to change their tax group and save the user. If they are checking out as a guest, you can simply set the customer tax group on the quote itself.

// We need this quote
$quote = $observer->getEvent()->getQuote();
// get our shipping address
$shipping_address = $quote->getShippingAddress();
// get our selected shipping method
$shipping_method = $shipping_address->getShippingMethod();
// if our shipping method is selected
if ($shipping_method == "storepickupmodule_pickup") {
// get our session object
$session = Mage::getSingleton('customer/session');
// load the customer from the session
$customer = $session->getCustomer();
// if this customer is logged in
if ($session->isLoggedIn()) {
// Set our group id to whatever we need it to be (be sure to get the correct id from your group)
} else {

In our case, the site isn’t using groups in any special way (everyone is in the General group) so we don’t have to worry about setting the user back to a default group etc. However, you might want to add another observer to change the user back after checkout, etc.

I know it’s pretty basic, I hope this helps someone out that might be struggling with this task.