CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion (Moderator: Donald Lobo) »
  • A modest Smarty/MVC question
Pages: [1]

Author Topic: A modest Smarty/MVC question  (Read 778 times)

benmoreassynt

  • I post occasionally
  • **
  • Posts: 52
  • Karma: 0
  • CiviCRM version: 4.4.4
  • CMS version: Joomla 2.5.19/Wordpress 3.8
  • MySQL version: 5.5.35
  • PHP version: 5.3.10
A modest Smarty/MVC question
March 09, 2014, 11:01:01 am
I know this question might be interpreted as somewhat cheeky from someone who does not contribute to CiviCRM code, or who has not thus far beyond a single confirmed bug report, however I thought I'd share a recent user experience trying to modify some default CiviCRM functionality first through profiles, then through custom templates, and finally through the api and a custom plugin. It is done with all due respect for the colossal achievement and mountain of man-hours that CiviCRM represents.

My objective was fairly simple. I wanted slightly to extend the New Membership signup page, while keeping it extremely simple. The default page was almost perfect for my needs, with one exception. If a contact is not in the database and needs to be added, a small Ajax-generated 'new contact' form pops up, but only accepts firstname, lastname and email address. It was important that low level users could add address details as well, without having to add the contact in a separate operation, or go back afterwards to edit the just-created contact.

Having established that there was no simple, built-in way to do that, I looked at replacing the new membership signup form using profiles. However, while if I'd stuck with that approach it might have been possible to achieve my end, I found that I wasn't making quick progress towards useable simple form that would create a new contact and a new memberships at the same time, while doing necessary checks to avoid duplicates, etc. That's not a criticism of the profiles system - it just didn't appear to suit what I was trying to do.

What I really needed was a relatively minor alteration to the new membership page using a custom template. In theory CiviCRM is set up perfectly for that, so I started working on the Smarty templates. What I found, however seemed to suggest that there are some serious drawbacks with Smarty and/or the way it is implemented in CiviCRM.

The idea behind Smarty is to separate logic from presentation, so that the presentational pages are simple to edit and modify. In fact, my experience of working with the Smarty templates is that they in fact place far more barriers in the way of non-specialist developers trying to modify CiviCRM for 'in-house' reasons than a PHP only 'view' page would have done. This seems to be because of a very complex structure of templates embedded in templates, of logic embedded in the presentational files (whether presentational logic or not), templates which, because they perform related functions on different pages are a maze of ifs and elseifs, and generated code which does things such as embed the same piece of JavaScript in five different places within a page.

Consider the following bit of code in CRM/Member/Page/Tab.tpl

Code: [Select]
{$action}
{if $action eq 1 or $action eq 2 or $action eq 8} {* add, update or delete *}
    {include file="CRM/Member/Form/Membership.tpl"}
{elseif $action eq 4}
    {include file="CRM/Member/Form/MembershipView.tpl"}
{elseif $action eq 32768}  {* renew *}
    {include file="CRM/Member/Form/MembershipRenewal.tpl"}
{elseif $action eq 16} {* Browse memberships for a contact *}
    {if $permission EQ 'edit'}{capture assign=newURL}{crmURL p="civicrm/contact/view/membership" q="reset=1&action=add&cid=`$contactId`&context=membership"}{/capture}{/if}

    {if $action ne 1 and $action ne 2 and $permission EQ 'edit'} ...

That doesn't seem like simple presentational code to me, but pretty dense logic that requires intimate knowledge of the CiviCRM logic to navigate successfully.

The template I was directed to initially from searching the CiviCRM output HTML for .tpl, however, was CRM/Profile/Form/Edit.tpl

The entirety of that file reads:

Code: [Select]
{include file="CRM/Profile/Form/Dynamic.tpl"}
So the sole role of this template is to include another template, and thereby obfuscate the code a little further.

Dynamic.tpl on the other hand, includes code which looks like this:

Code: [Select]
{assign var=zeroField value="Initial Non Existent Fieldset"}
    {assign var=fieldset  value=$zeroField}
    {foreach from=$fields item=field key=fieldName}
      {if $field.skipDisplay}
        {continue}
      {/if}
      {assign var="profileID" value=$field.group_id}
      {assign var=n value=$field.name}
      {if $field.groupTitle != $fieldset}
        {if $mode neq 8 && $mode neq 4}
          <div {if $context neq 'dialog'}id="profilewrap{$field.group_id}"{/if}>
          <fieldset><legend>{$field.groupTitle}</legend>
        {/if}
        {assign var=fieldset  value=`$field.groupTitle`}
        {assign var=groupHelpPost  value=`$field.groupHelpPost`}
        {if $field.groupHelpPre}
          <div class="messages help">{$field.groupHelpPre}</div>
        {/if}
      {/if}

So - variables are being created (one variable is immediately assigned to another), a dense logic structure is generated, for a total output of about two lines of HTML, and there is no way in which someone not deeply familiar with the business logic of CiviCRM can intelligently edit the file to add functionality.

And then there's the embedded JavaScript ... on the Membership signup page the same bit of code to handle a datepicker is echoed something like 6 times - once for each date field. That just seems ... bad.

My overall point though, is that, as a method to separate logic from presentation so as to allow CiviCRM managers to extend or customise functionality, Smarty (as implemented) completely fails. I appreciate it may succeed from the point of view of generating cached template pages and thereby reducing server load, but it poses a major barrier to developers hoping to implement relatively modest customisations to CiviCRM to enhance it for their users.

My eventual solution was to design a Wordpress plugin using the API which basically recreates the membership signup form, but with the additional features I wanted. Quite a major undertaking for something which seemed a fairly trivial tweak.

On the plus side, the API is terrific, and perhaps the lesson is that I should have started there, rather than ended. But it does seem to me that it would not be unreasonable to question what benefit Smarty brings to the table, and whether templates which are so densely embedded with Smarty logic are something CiviCRM needs to be committed to maintaining.

Once again, I appreciate this out of the blue post is somewhat cheeky, and perhaps just means I'm in a camp of Smarty dislikers who should mind their own business and not risk flame wars. However I thought I'd post it in hopefully a respectful manner to get a sense of current thinking among the developers.

Coleman Watts

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 2346
  • Karma: 183
  • CiviCRM version: The Bleeding Edge
  • CMS version: Various
Re: A modest Smarty/MVC question
March 09, 2014, 11:14:15 am
Quote
If a contact is not in the database and needs to be added, a small Ajax-generated 'new contact' form pops up, but only accepts firstname, lastname and email address.
It sounds like you are referring to the "new_individual" profile, which can be configured just as any other profile can - go to Administer -> Profiles -> Reserved Profiles and edit it adding your desired fields.
Try asking your question on the new CiviCRM help site.

benmoreassynt

  • I post occasionally
  • **
  • Posts: 52
  • Karma: 0
  • CiviCRM version: 4.4.4
  • CMS version: Joomla 2.5.19/Wordpress 3.8
  • MySQL version: 5.5.35
  • PHP version: 5.3.10
Re: A modest Smarty/MVC question
March 09, 2014, 11:50:53 am
Ah well - there you go. I'm kind of an idiot then ... annoyed I missed that! :-\

Although I still think there's kind of an issue with the Smarty...


awasson

  • I post frequently
  • ***
  • Posts: 230
  • Karma: 7
  • Living in a world of Drupal / CiviCRM
    • My Company: Luna Design
  • CiviCRM version: Latest
  • CMS version: Drupal 6/7/8
  • MySQL version: 5.x
  • PHP version: 5.3.x
Re: A modest Smarty/MVC question
March 09, 2014, 01:45:09 pm
@benmoreassynt: Sort of an aside to your discussion but have you had a look at the quite comprehensive CiviCRM Cookbook: http://it-ebooks.info/book/2950/

CiviCRM is a pretty massive subject to master and that book is a pretty fantastic reference for doing real world things like working with registrations, signups, dealing with contact records for all sorts of reasons.

Disclaimer: I was fortunate to have been one of the reviewers so I got to have a good read. I only wish I had it a few years ago when I first discovered CiviCRM.

Andrew
My CiviCRM Extension Workshop: https://github.com/awasson

Pages: [1]
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion (Moderator: Donald Lobo) »
  • A modest Smarty/MVC question

This forum was archived on 2017-11-26.