Agency pages are more commonly found on portals, but the idea of an agency as a container for branches, staff etc, exists on every site on the platform. This area will explore output options and general agency functions.

The agency show page

Anything agency related will reside in the agencies folder in your Rails directory structure and your show page will follow the normal format of show.liquid. Let’s start to build the page using the agency name, agency description and the agency’s portal logo with a fallback to their default logo:

{% if agency.portal_logo %}
 <img src="{{agency.portal_logo | url_for_agency_logo : "200x_"}}" />
{% elsif agency.logo %}
 <img src="{{agency.logo | url_for_agency_logo : "200x_"}}" />
{% endif %}


Next, let’s add a Google style map to our show page - note that this will show the branches belonging to an agency:

<div id='agency_map'></div>
 {{ gmap_for agency.branches as roadmap in agency_map }}

Don’t forget to give your map div a height and a width setting in your CSS.

If you would prefer to use a Leaflet style map:

<div id='branches_map'></div>
<script type="text/javascript">
 Ctesius.addConfig('branch_map_element', 'branches_map');
 Ctesius.addConfig('branches', {{ include_as_json branches/branches_list }});

Now let’s extract the branches of an agency, including their branch pic or logo, description etc:

{% for branch in agency.branches_ordered_alphanumerically %}
 {% include "branches/branch_small" %}
{% endfor %}

Note that we’re ordering the branches alphabetically using a helper function and we’re reusing our branch_small. Not only is this excellent reuse, but it means if your branch_small layout is sorted, it should work out of the box on you agencies pages. In addition, when you need to make a change to it, it will be reflected on all pages that use it.

Finally, let’s see how we can extract some social media links from the CRM:

{% if agency.has_social_links %}
 <div class="agency_social">
  {% if agency.facebook_uri %}
   <a href="{{agency.facebook_uri }}" target="_blank"><img src="{{'facebook' | theme_image_url}}" width="32" height="32"></a>
  {% endif %}
  {% if agency.twitter_uri %}
   <a href="{{agency.twitter_uri }}" target="_blank"><img src="{{'twitter' | theme_image_url}}" width="32" height="32"></a>
  {% endif %}
  {% if agency.linkedin_uri %}
   <a href="{{agency.linkedin_uri }}" target="_blank"><img src="{{'linkedin' | theme_image_url}}" width="32" height="32"></a>
  {% endif %}
  {% if agency.googleplus_uri %}
   <a href="{{agency.googleplus_uri }}" target="_blank"><img src="{{'google-plus' | theme_image_url}}" width="32" height="32"></a>
  {% endif %}
{% endif %}

This block of code first executes a has_social_links function - this checks whether any one of the standard social media slots has a value. If at least one does, it will execute the block. We then use individual agency drop checks to see if the URI is available and output a theme image linking to the URI if so.

Properties from fragment

Properties from fragment is a function that effectively allows you to run a background search using any search criteria, then loop through the results anywhere on the site using a well defined content block.

If you’ve been working with search results as well as filtering by price, type and so on, you’ll be familiar with the URL ‘fragments’. A typical fragment could be: from-3-bed/from-200000/up-to-300000. This is exactly what we can add to the block:

{% search_from_fragment fragment: status-sold/most-recently-updated-first channel: sales %}
 {% for property in properties limit: 10 %}
   <a href="{{ property | url_for_property }}">
    <img src="{{ | url_for_property_asset: "265x160" }}">
    <h5>{{ property.display_address }}</h5>
    <p>{{ property.bedrooms }} bedrooms</p>
 {% endfor %}
{% endsearch_from_fragment %}

Agency recent sales and lettings

There are three recent property related functions to be aware of:

  • Recent properties
  • Recent sales properties
  • Recent lettings properties

Whereas recent properties gets both sales and lettings, recent sales or recent lettings gets five properties belonging to the respective channel. They are all called in much the same way and make use of the same fields. Here’s how to call the recent sales function:

{% for property in agency.recent_sales_properties %}
 <a href="{{property | url_for_property}}">
  <h3>New Listings</h3>
  <img src="{{ | url_for_property_asset }}" />
{% endfor %}

Interesting properties

The interesting properties algorithm attempts to find properties similar to the ones a user has searched for and/or viewed, then display them in a location such as the home page. Many agency sites have a default output that is replaced if a certain number of interesting properties are returned.

Our first port of call is to switch on a couple of options in the theme. In your JS Event Registers file add the following:

Ctesius.addConfig('enable_user_history', true);

And if you want to make sure enough properties are on the stack before outputting:

Ctesius.addConfig('minimum_interesting_properties', 1);

Now consider a typical home page presentation:

<div id='interesting_properties_view'>
 <div class="span3">
  <div class="homePanel box">
   {% for property in agency.recent_sales_properties limit:1 %}
    <a href="{{property | url_for_property}}">
     <h3>New Listings</h3>
     <img src="{{ | url_for_property_asset}}" />
   {% endfor %}

There’s nothing special about this - if we had another three you’d have a nice row of recent property boxes. Now, somewhere convenient, we would then add:

{% raw %}
  <script id="interesting_properties_template" type="text/liquid">
   <div class="span3">
    <div class="homePanel box">
     {% for property in properties limit:1 %}
      <a href="{{property.property_url | url_for_property}}">
       <h3>New Listings</h3>
       <img src="{{ | url_for_property_asset}}" />
     {% endfor %}
{% endraw %}

This template will be used to render our results.

###Working with statuses and property fields

At the time of writing, the property status Liquid that finds and outputs the appropriate sash is not available for use on the Interesting Properties output. Instead, the solution is to add the property’s channel to the properties_list.ljson, then run some Liquid checks to output the appropriate sash.

status: "{{property.status}}" - add to the LJSON
primary_channel: "{{property.primary_channel}}" - also worth adding to get the channel

{% if property.primary_channel == 'sales' %}
 {% if property.status == 'SSTC' }
  <img src="{{ 'sstc.jpg' | theme_image_url }}" class="property-status" />
 {% if property.status == 'SSTC' }
  <img src="{{ 'sstc.jpg' | theme_image_url }}" class="property-status" />
 {% endif %}
{% endif %}

If you wanted to exclude Sold, Let, etc from the output altogether, you can add this to the JSON within the for loop:

{% highlight liquid %} exclude_from_implied: {% if property.status == ‘SSTC’ %}true{% endif %}{% if property.status == ‘Let agreed’ %}true{% endif %}{% if property.status == ‘Let’ %}true{% endif %}{% if property.status == ‘Sold’ %}true{% endif %} {% endhighlight %}

This if statement looks a bit ugly but the value must follow the field.

Most fields can be added to the JSON, so if you wanted to output for example, you could add it to the JSON then check and output put it to the Interesting Properties view.

###Working with User History

A handy event and callback is available to you as and when the user history for the Interesting Properties output is built up. This can be used to add a custom title, background or anything else you please.

Ctesius.registerEvent('user_history_ready', function(collection){
 var last_search = collection.last()

 if (last_search != undefined && last_search.get('place') != undefined){
  var place = last_search.get('place').get('name')


In this code sample you could run a test on place, then use a jQuery attribute change on an element.


Agency testimonials can be added via the CMS link: /configure/website/testimonials. You can then loop over and output the testimonials as follows:

{% for testimonial in agency.testimonials limit: 20 %}
  <p>"{{ testimonial.content }}"</p>
  <p>{{ }}</p>
{% endfor %}

A route exists in the Ctesius app the /pages/testimonials and a testimonials.liquid page can exist under your pages folder to have a dedicated testimonials page. Use the loop above here to extract them to the page.

A useful testimonials function is to assign a random testimonial and output to a given area:

{% assign testimonial = agency.featured_testimonial %}
 <span class="author">{{}}</span>

Need to slice the testimonials array to get the latest five and then shuffle them? Use the slice_array and shuffle functions:

{% assign testimonials = agency.testimonials | slice_array : 0, 4 %}
{% assign shuffled_testimonials = testimonials | shuffle %}

{% for testimonial in shuffled_testimonials limit: 1 %}
 <span class="author">{{}}</span>
{% endfor %}

Need testimonials by channel? No problem:

{% assign testimonials = agency.testimonials | selected_by : 'channel', 'lettings' %}

{% assign testimonials = agency.testimonials | selected_by : 'channel', 'sales' %}

Then loop through them as normal.


Banners are useful blocks that can contain a title, description, image and a URL. Items belonging to a banner can be manually ordered, which makes them very versatile. To add a banner, head over to the agency admin: /configure/website/site_banners. Here’s the markup:

{% assign banner = 'department_links' | site_banner %}

{% unless banner.banner_menu_items == empty %}
 {% for menu_item in banner.banner_menu_items %}
  <div style="background-image:url('{{menu_item.image | url_for_site_asset: "226x126"}}')">
   <a href="{{menu_item.url}}">Read more &gt;</a>
 {% endfor %}
{% endunless %}