This is the documentation for LemonStand V1, which has been discontinued. You can learn more and upgrade your store here.

LemonStand Version 1 Has Been Discontinued

This documentation is for LemonStand Version 1. LemonStand is now offered as a cloud-based eCommerce platform.
You can try the new LemonStand and learn about upgrading here.

How to Create a Customer Profile Page

This article explains how to enable customer profile pages for your eCommerce store. Allow for registered users and customers to edit their account details, billing information, shipping information, and view order history.

If you have not created customer account creation and registration for your eCommerce store, follow this guide to get started.

 customer profiles

Installing the Customer Profile module

The Customer Profile module was developed by LemonStand and is provided for free on our marketplace. You can find all of LemonStand's modules here: http://lemonstand.com/marketplace/author/lemonstand/

 You can install the module for any of your projects in 4 easy steps:

  1. Get the Customer Profile module from the marketplace
  2. Bind and add the Customer Profile module to your chosen project. Here are the step-by-step instructions on how to install a module
  3. Get the Utility theme from the marketplace
  4. Install the theme. Here are the step-by-step instructions on how to install a theme
  5. Set up the design for your customer profile page.

Developing the Customer Profile Page

We've designed the customer profile page in multiple parts with partials and content blocks. Below are the pieces needed the code that you can use for each part:

  • shop:states partial
  • 'Account' page
  • 'Change account' content block
  • 'Change information' content block
  • 'Change shipping' content block
  • 'View orders' content block
  • Sidebar navigation partial

"shop:states" partial

Below is the code used for the shop:states partial:

<? foreach($states as $state): ?>
  <option <?= option_state($current_state, $state->id) ?> value="<?= h($state->id) ?>"><?= h($state->name) ?></option>
<? endforeach ?>

"account" page content

Below is the code for the content used to create an account page:

<?
extract(array_merge(array(
  'partial_step' => post('partial_step', false),
  'section' => post('section', 'change_information') //defaults to the change_information section
), $params));
?>
<? if($partial_step) { $this->render_block($section); return; } ?>
<? $this->render_block($section) ?>

"change account" content

Below is the code for the content of the 'change account' section:

<article class="col-9">
<?= open_form() ?>
  <ul class="form">
    <li class="field text left">
      <label for="first_name">First Name <span class="required">*</span></label>
      <div class="text-box"><input id="first_name" name="first_name" type="text" value="<?= $this->customer->first_name ?>" /></div>
    </li>
    <li class="field text right">
      <label for="last_name">Last Name <span class="required">*</span></label>
      <div class="text-box"><input id="last_name" name="last_name" type="text" value="<?= $this->customer->last_name ?>" /></div>
    </li>  
    <li class="field text">
      <label for="email">Email <span class="required">*</span></label>
      <div class="text-box"><input id="email" type="text" name="email" value="<?= $this->customer->email ?>" /></div>
    </li>
  </ul>
  <div class="submit-box right clear-both">
    <input type="submit" onclick="return $(this).getForm().sendRequest('profile:on_updateAccount', {
      extraFields: {'no_flash': true},
      onSuccess: function() {
      }
    })" value="Save" />
  </div>
<?= close_form() ?>
</article>
<article class="col-9">
<?= open_form() ?>
  <ul class="form">
    <li class="text">
      <label for="old_password">Old Password <span class="required">*</span></label>
      <div class="text-box"><input id="old_password" type="password" name="old_password" /></div>
    </li>
    <li class="field text left">
      <label for="password">New Password <span class="required">*</span></label>
      <div class="text-box"><input id="password" type="password" name="password" /></div>
    </li>
    <li class="text right">
      <label for="password_confirm">Password Confirmation <span class="required">*</span></label>
      <div class="text-box"><input id="password_confirm" type="password" name="password_confirm" /></div>
    </li>
  </ul>
  <div class="submit-box right clear-both">
    <input type="submit" onclick="return $(this).getForm().sendRequest('profile:on_updatePassword', {
      extraFields: {'no_flash': true},
      onSuccess: function() {
      }
    })" value="Save" />
  </div>
<?= close_form() ?>
</article>

"change information" content

Below is the code for the contenet of the 'change information' section:

<?
$billing_info = Shop_CheckoutData::get_billing_info();
$billing_countries = Shop_Country::get_list($billing_info->country);
$billing_country = $billing_info->country ? $billing_info->country : $billing_countries[0]->id;
$billing_states = Shop_CountryState::create(true)->where('country_id=?', $billing_country)->order('name')->find_all();
?>
<article class="col-9">
<?= open_form(array('id' => 'billing_info')) ?>
  <h3 class="block">Billing Information</h3>
  <ul class="form billing_info">
    <li class="text left">
      <label for="billing_first_name">First Name</label>
      <div class="text-box"><input id="billing_first_name" name="billing[first_name]" type="text" value="<?= h($billing_info->first_name) ?>" /></div>
    </li>
    <li class="text right">
      <label for="billing_last_name">Last Name</label>
      <div class="text-box"><input id="billing_last_name" name="billing[last_name]" type="text" value="<?= h($billing_info->last_name) ?>" /></div>
    </li>
    <li class="text left">
      <label for="billing_company">Company</label>
      <div class="text-box"><input id="billing_company" type="text" value="<?= h($billing_info->company) ?>" name="billing[company]" /></div>
    </li>
    <li class="text right">
      <label for="billing_phone">Phone</label>
      <div class="text-box"><input id="billing_phone" type="text" value="<?= h($billing_info->phone) ?>" name="billing[phone]" /></div>
    </li>
    <li class="text">
      <label for="billing_street_address">Street Address</label>
      <div class="text-area"><textarea id="billing_street_address" rows="2" name="billing[street_address]" value="<?= h($billing_info->street_address) ?>"><?= h($billing_info->street_address) ?></textarea></div>
    </li>
    <li class="text left">
      <label for="billing_city">City</label>
      <div class="text-box"><input id="billing_city" type="text" name="billing[city]" value="<?= h($billing_info->city) ?>" /></div>
    </li>
    <li class="field text right">
      <label for="billing_zip">Zip/Postal Code</label>
      <div class="text-box"><input id="billing_zip" type="text" name="billing[zip]" value="<?= h($billing_info->zip) ?>" /></div>
    </li>
    <li class="select left">
      <label for="billing_country">Country</label>
      <select id="billing_country" name="billing[country]" onchange="return $(this).getForm().sendRequest('shop:on_updateStateList', {
        extraFields: {
          'country': $('#billing_country').val(), 
          'current_state': '<?= $billing_info->state ?>'
        },
        update: {'#billing_states': 'shop:states'}
      })">
        <option value=''>Select Country</option>
      <? foreach($billing_countries as $country): ?>
        <option <?= option_state($billing_info->country, $country->id) ?> value="<?= h($country->id) ?>"><?= h($country->name) ?></option>
      <? endforeach ?>
      </select>
    </li>
    <li class="field select right">
      <label for="billing_states">State</label>
      <div>
        <select id="billing_states" name="billing[state]">
        <?= $this->render_partial('shop:states', array('states' => $billing_states, 'current_state' => $billing_info->state)) ?>
        </select>
      </div>
    </li>
  </ul>
  <div class="submit-box right clear-both">
    <input type="submit" onclick="return $(this).getForm().sendRequest('profile:on_updateBilling', {
      extraFields: {'no_flash': true},
      onSuccess: function() {
      }
    })" value="Save" />
  </div>
<?= close_form() ?>
</article>
<article class="col-9">
<?= open_form(array('id' => 'shipping_info')) ?>
<?= close_form() ?>
</article>
<script>
  LS.sendRequest('<?= Phpr::$request->getCurrentUri() ?>', 'on_action', {
    update: {'#shipping_info': 'ls_cms_page'},
    extraFields: {
      'section': 'change_shipping',
      'partial_step': true
    }
  });
</script>

"change shipping" content

Below is the code for the contenet of the 'change shipping' section:

<?
$shipping_info = Shop_CheckoutData::get_shipping_info();
$shipping_countries = Shop_Country::get_list($shipping_info->country);
$shipping_country = $shipping_info->country ? $shipping_info->country : $shipping_countries[0]->id;
$shipping_states = Shop_CountryState::create(true)->where('country_id=?', $shipping_country)->order('name')->find_all();
?>
  <h3 class="block left">Shipping Information <a href="javascript:;" onclick="return $('#billing_info').sendRequest('profile:on_updateBilling', {
    onSuccess: function() {
      LS.sendRequest('<?= Phpr::$request->getCurrentUri() ?>', 'profile:on_copyBillingToShipping', {
        update: {'#shipping_info': 'ls_cms_page'},
        extraFields: {
          'section': 'change_shipping',
          'partial_step': true
        },
        onSuccess: function() {
        }
      });
    }
  })">copy billing</a></h3>
  <ul class="form shipping_info clear-both">
    <li class="text left">
      <label for="shipping_first_name">First Name</label>
      <div class="text-box"><input id="shipping_first_name" name="shipping[first_name]" type="text" value="<?= h($shipping_info->first_name) ?>" /></div>
    </li>
    <li class="text right">
      <label for="shipping_last_name">Last Name</label>
      <div class="text-box"><input id="shipping_last_name" name="shipping[last_name]" type="text" value="<?= h($shipping_info->last_name) ?>" /></div>
    </li>
    <li class="text left">
      <label for="shipping_company">Company</label>
      <div class="text-box"><input id="shipping_company" type="text" value="<?= h($shipping_info->company) ?>" name="shipping[company]" /></div>
    </li>
    <li class="text right">
      <label for="shipping_phone">Phone</label>
      <div class="text-box"><input id="shipping_phone" type="text" value="<?= h($shipping_info->phone) ?>" name="shipping[phone]" /></div>
    </li>
    <li class="text">
      <label for="shipping_street_address">Street Address</label>
      <div class="text-area"><textarea rows="2" id="shipping_street_address" name="shipping[street_address]" value="<?= h($shipping_info->street_address) ?>"><?= h($shipping_info->street_address) ?></textarea></div>
    </li>
    <li class="text left">
      <label for="shipping_city">City</label>
      <div class="text-box"><input id="shipping_city" type="text" name="shipping[city]" value="<?= h($shipping_info->city) ?>"/></div>
    </li>
    <li class="text right">
      <label for="shipping_zip">Zip/Postal Code</label>
      <div class="text-box"><input id="shipping_zip" type="text" name="shipping[zip]" value="<?= h($shipping_info->zip) ?>"/></div>
    </li>
    <li class="select left">
      <label for="shipping_country">Country</label>
      <select id="shipping_country" name="shipping[country]" onchange="return $(this).getForm().sendRequest('shop:on_updateStateList', {
        update: {'#shipping_states': 'shop:states'},
        extraFields: {
          'country': $('#shipping_country').val(), 
          'current_state': '<?= $shipping_info->state ?>'
        }
      })">
        <option value=''>Select Country</option>
      <? foreach($shipping_countries as $country): ?>
        <option <?= option_state($shipping_info->country, $country->id) ?> value="<?= h($country->id) ?>"><?= h($country->name) ?></option>
      <? endforeach ?>
      </select>
    </li>
    <li class="select right">
      <label for="shipping_states">State</label>
      <div>
        <select id="shipping_states" name="shipping[state]">
        <?= $this->render_partial('shop:states', array('states' => $shipping_states, 'current_state' => $shipping_info->state)) ?>
        </select>
      </div>
    </li>
  </ul>
  <div class="submit-box right clear-both">
    <input type="submit" onclick="return $(this).getForm().sendRequest('profile:on_updateShipping', {
      extraFields: {'no_flash': true},
      onSuccess: function() {
      }
    })" value="Save" />
  </div>
<script>
jQuery(function($) {
  $('.use_billing_address').click(function() {
    $('.billing_info [name]').each(function() {
      var re = new RegExp('^billing\\[(.+)\\]$', 'gi');
      var item = re.exec($(this).attr('name'));
      $('.shipping_info [name="shipping[' + item[1] + ']"]').val($(this).val());
    });
    return false;
  });
});
</script>

"view orders" content

Below is the code for the contenet of the 'view orders' section:

<article class="col-9">
<?= open_form() ?>
  <? if(!$orders->count): ?>
    <p>No orders yet.</p>
  <? else: ?>
    <p>Click an order for details.</p>
    <table>
      <thead>
        <tr>
          <th class="first"></th>
          <th>#</th>
          <th>Date</th>
          <th>Status</th>
          <th class="text-right last">Total</th>
        </tr>
      </thead>
      <tbody>
        <? foreach($orders as $order): ?>
          <?
          $url = root_url('/') . 'account/order/' . $order->id;
          ?>
          <tr class="<?= zebra('order') ?>">
            <td>
              <span title="<?= h($order->status->name) ?>" style="background-color: <?= $order->color ?>">&nbsp;</span>
            </td>
            <td><a href="<?= $url ?>"><?= $order->id ?></a></td>
            <td><a href="<?= $url ?>"><?= $order->order_datetime->format('%x') ?></a></td>
            <td><a href="<?= $url ?>"><strong><?= h($order->status->name) ?></strong> since <?= $order->status_update_datetime->format('%x') ?></a></td>
            <td class="text-right last"><a href="<?= $url ?>"><?= format_currency($order->total) ?></a></th>
          </tr>
        <? endforeach ?>
      </tbody>
    </table>
  <? endif ?>
<?= close_form() ?>
</article>

"sidebar navigation" partial

To navigate through all the sections, we will create a sidebar navigation contained in a partial. 

<h2>My Account</h2>
<ul class="categories">
  <li>
    <a href="javascript:;" onclick="return LS.sendRequest('/account', 'on_action', {
      update: {'.page .wrap': 'ls_cms_page'},
      extraFields: {'section': 'change_information'}
    })">Change Information</a>
  </li>
  <li>
    <a href="javascript:;" onclick="return LS.sendRequest('/account', 'on_action', {
      update: {'.page .wrap': 'ls_cms_page'},
      extraFields: {'section': 'change_account'}
    })">Change Account</a>
  </li>
  <li>
    <a href="javascript:;" onclick="return LS.sendRequest('/account/orders', 'on_action', {
      update: {'.page .wrap': 'ls_cms_page'}
    })">View Orders</a>
  </li>
</ul>

Support

If you're looking for support and help, check out the following links below:


Previous: How to Set Minimum Order Amount
Return to Articles