Tuesday, October 07, 2014

Miva Merchant for Code Geeks; Or how I fought against the default Miva dev model and sort of won

Miva Merchant? Let's Do it!

I've got a relatively new client who's current platform is MivaMerchant. While he's open to switching to a new platform, I'm hesitant to do so without a firm grasp of his business and what the pros/cons of Miva are. So for now, I need to become best buds with Miva.

Doing a few Google searches turned up MivaScript.com, which implies that Miva is, well, scriptable. And while the syntax appears to be on the clunky side (it's XML based, so that is to be expected), it does look relatively complete.

As I dove into my first few projects, I started to come up to speed on Miva. The video tutorials are well done, the admin tool quite complete, and template language (audaciously named Store Morph Technology aka SMT) looked promising.

But wait...

As I started to truly build out my projects I kept running into two questions: (1) where's the flat file interface for the templates, and (2) when do I get to start using MivaScript?

While the admin UI is nice and all (there's a basic version control system built in), it's hardly the ideal environment to work on large template files (which are a mix of HTML and special tags). Or put more bluntly, I want to use emacs to edit content, not a text area in Firefox. Surely I was missing something. Finally I broke down and filed a ticket on the topic. The tech rep said she'd call me to discuss; and sure enough she did. She explained to me that you *have* to use the admin UI, there is no file interface. Apparently, the Miva techs work by copying and pasting content into a text editor, making changes, and copying and pasting it back.

While the tech was very nice (and again, promptly called me), surely she must have just been misinformed. Miva can't expect professional programmers to build sophisticated stores by copying and pasting code. Can they? Even if I'm OK with all this copying and pasting, how am I supposed to use a real version control system or do an automated deployment, if all the source code needs to live in an HTML admin tool?

I took my quandary further up the Miva chain. (Which again, I give them credit for having as an option.) I finally spoke to a senior developer and he told me that the tech's understanding is correct. They are aware of the limitations of the admin UI, but it's the only way they currently support using Miva. I got the impression that future versions of the product may help address this issue.

OK, I'll learn to love the admin UI. My work around for now is to keep a version of the templates found in Miva in a local source repository. The content of the PROD page for example, is stored in: admin/Pages/PROD/Page.smt.

And it gets worse

Issue number (2), however, points to a potentially larger concern. After a bunch of research I learned that Miva Merchent itself is written in MivaScript< and while the templates themselves understand SMT tags, they don't process MivaScript. In other words, your typical MivaMerchant developer never writes or even encounters MivaScript. Fair enough. But how do they modularize code? That is, how do I void duplicating code in templates, and how do I keep my templates from growing out of control? Looking at the template language of choice, there didn't seem to be a way to include code. Without a basic include statement, how can I achieve any sort of modularity?

I ran these questions by the nice tech that called me. The short answer was, there is no way to do this. At the senior tech level, he mentioned something about setting up custom items that would appear in the UI as their own editable regions, and then I could include those items at will. This is somewhat promising, but that means embracing the the admin UI even more.

All this left me pretty disappointed with Miva. There simply had to be a way to make it more developer friendly.

A first attempt at a fix

If the standard set of tools weren't going to give me what I wanted, what about building out a custom extension or two? I make custom plugins in WordPress all the time, how hard could it be to do in Miva? This seemed promising, as extensions are written in MivaScript, so I'd get power of a full programming language instead of making do with an admin UI and the basic SMT language. Alas, after a few days of analyzing extensions (you can see lots of examples in the source for MivaMerchant provided here (and you'll need the compiler here), I finally had to throw in the towel. Between the fact that MivaScript is a language unto itself, and my lack of understanding of how MivaMerchant operates, I'm just not ready to create extensions for it. I had to surrender.

And the real fix

But still, I wasn't ready to give up on my dream of a move developer friendly Miva experience. And then I found the missing piece of the puzzle: the External File Pro v5+ module. This bad boy allows you to invoke a MivaScript function in an arbitrary file, and it places the result in an SMT file of your choice.

Let's take a specific example to see how this module can save the day. Suppose you want to customize your title tag depending your product name. You could head over to the PROD page and put in some code like this:

<mvt:if expr="l.all_settings:product:name EQ 'Iguana'>
  <title>Love Lizards! Buy an Iguana Today!</title>
</mvt:if>
<mvt:if expr="l.all_settings:product:name EQ 'Turtle'>
  <title>Totally Turtles! Buy an Turtle Today!</title>
</mvt:if>
...

But, that code is messy and hard to maintain. Ideally, it would live in its own function, in its own file. That's where External File Pro comes.

The first order of business is to buy and install the External File Pro v5+. Once you've enabled the module and associated it with the PROD page you're ready to get to work.

I created a MivaScript source file: /mm5/snippets/seo/title.mv. The path is totally arbitrary. I plan to organize all these includes as snippets, and this particular one is related to SEO. Hence the naming. Note, the source file is .mv. The actual MivaScript file looks something like this:

<MvComment>
  Generate our Page Title in a smart way. If we can make a better title than the default one, then
  go for it.
</MvComment>

<MvFUNCTION NAME = "ADS_External_File" PARAMETERS = "module var, item, all_settings var, settings var, ignored" STANDARDOUTPUTLEVEL = "text, html, compresswhitespace">
  <MvIF EXPR = "{ l.all_settings:product:name EQ 'Iguana' }">
    <MvEVAL EXPR = "{ '<title>' $ 'Love Lizards! Buy a ' $ l.all_settings:product:name . ' Today!' $ '</title>' }"/>
    <MvFUNCTIONRETURN />
  </MvIF>

  <MvIF EXPR = "{ l.all_settings:product:name EQ 'Turtle' }">
    <MvEVAL EXPR = "{ '<title>' $ 'Totally Turtles! Buy a ' $ l.all_settings:product:name . ' Today!' $ '</title>' }"/>
    <MvFUNCTIONRETURN />
  </MvIF>

  <MvEVAL EXPR = "{ '<title>' $  $ l.all_settings:product:name $ '! Buy one Today!' $ '</title>' }"/>
  <MvFUNCTIONRETURN />
</MvFUNCTION>

Notice that the function is named ADS_External_File. That's a requirement of the External File Pro plugin, and serves as the entry point to our snippet.

This file needs to be compiled to a .mvc file. I'm using a simple Makefile to accomplish this:

## Makefile for building our MivaScript function files

export PATH := /c/tools/miva/msc/BIN:$(PATH)
RM  = rm
MVC = mvc.exe  -B 'c:\tools\miva\msc\BUILTINS'
SNIPPETS = seo/title
SRCS     = $(addsuffix .mv, $(SNIPPETS)))
COMPILED = $(addsuffix .mvc, $(SNIPPETS))

all : $(COMPILED)

%.mvc : %.mv
 $(MVC) $<

clean :
 $(RM) -f $(COMPILED)

With the command:

  make ;  sitecopy -u dev.mysite.com

The snippet is compiled and pushed to the server.

Finally, in the PROD Page template I put in a call to the snippet:

  <mvt:item name="ads-extfile" param="function|/mm5/snippets/seo/title.mvc"/>

And I'm done.

Whoo!

I've now got the ability to create arbitrary functions in MivaScript and pull their contents into an a template. This gives me the modularity and maintainability I was after, and opens the door to streamlining development of complex functionality. Looks like Miva and I may indeed be best buds after all.

No comments:

Post a Comment