homeflow_api 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ console.log('This would be the main JS file.');
data/lib/homeflow/api.rb CHANGED
@@ -40,7 +40,7 @@ require current_dir + "/api/response"
40
40
  module Homeflow
41
41
  module API
42
42
 
43
- VERSION = "1.0.2"
43
+ VERSION = "1.0.3"
44
44
 
45
45
  class << self
46
46
  attr_accessor :configuration
@@ -63,9 +63,10 @@ module Homeflow
63
63
 
64
64
  # A configuration instance
65
65
  class Configuration
66
- attr_accessor :api_key, :source, :show_debug, :logger
66
+ attr_accessor :api_key, :source, :show_debug, :logger, :request_key
67
67
 
68
68
  def initialize
69
+ @request_key = ''
69
70
  @api_key = 'API_KEY_REQUIRED'
70
71
  @source = 'http://localhost:3000'
71
72
  @show_debug = false
@@ -67,7 +67,10 @@ module Homeflow
67
67
 
68
68
 
69
69
  def constant_params
70
- {:api_key=> Homeflow::API.config.api_key}
70
+ {
71
+ :api_key => Homeflow::API.config.api_key,
72
+ :request_key => Homeflow::API.config.request_key
73
+ }
71
74
  end
72
75
 
73
76
  class << self
data/params.json ADDED
@@ -0,0 +1 @@
1
+ {"name":"Homeflow api","tagline":"","body":"- [Home](/homeflow/homeflow_api/wiki)\r\n- [Getting started](/homeflow/homeflow_api/wiki/ctesius#getting-started)\r\n\t- [Theme folder structure](/homeflow/homeflow_api/wiki/ctesius#theme-folder-structure)\r\n\t- [The layout file](/homeflow/homeflow_api/wiki/ctesius#the-layout-file)\r\n\t- [Building up the layout](/homeflow/homeflow_api/wiki/ctesius#building-up-the-layout)\r\n\t- [Running your theme](/homeflow/homeflow_api/wiki/ctesius#running-your-theme)\r\n- [Application &amp; home page](/homeflow/homeflow_api/wiki/ctesius#building-up-the-application-and-home-page)\r\n\t- [The header](/homeflow/homeflow_api/wiki/ctesius#the-header-with-an-agency-or-portal-logo)\r\n\t- [The navigation menu](/homeflow/homeflow_api/wiki/ctesius#the-navigation-menu)\r\n\t- [The carousel](/homeflow/homeflow_api/wiki/ctesius#the-carousel)\r\n\t- [The footer](/homeflow/homeflow_api/wiki/ctesius#the-footer)\r\n- [Property Searching](/homeflow/homeflow_api/wiki/ctesius#working-with-property-searches)\r\n\t- [Property search form](/homeflow/homeflow_api/wiki/ctesius/working-with-property-searches#constructing-a-property-search-form)\r\n\t- [Displaying search results](/homeflow/homeflow_api/wiki/ctesius#displaying-search-results)\r\n\t- [The properties loop](/homeflow/homeflow_api/wiki/ctesius#the-properties-loop)\r\n\t- [Locations and postcodes](/homeflow/homeflow_api/wiki/ctesius#handling-with-locations-and-postcodes)\r\n\t- [Headings and pagination](/homeflow/homeflow_api/wiki/ctesius#headings-and-pagination)\r\n\t- [More on pagination](/homeflow/homeflow_api/wiki/ctesius#more-on-pagination)\r\n\t- [Togglable areas](/homeflow/homeflow_api/wiki/ctesius#togglable-areas)\r\n\t- [Working with map views](/homeflow/homeflow_api/wiki/ctesius#working-with-the-map-view)\r\n\t- [Working with grid views](/homeflow/homeflow_api/wiki/ctesius#working-with-grid-views)\r\n\t- [Saving to shortlist](/homeflow/homeflow_api/wiki/ctesius#saving-properties-to-a-shortlist)\r\n\t- [Saving searches](/homeflow/homeflow_api/wiki/ctesius#saving-searches)\r\n- [Draw a Map](/homeflow/homeflow_api/wiki/ctesius#draw-a-map)\r\n- [The property show page](/homeflow/homeflow_api/wiki/ctesius#the-property-show-page)\r\n\t- [Outputting basic information](/homeflow/homeflow_api/wiki/ctesius#outputting-basic-information)\r\n\t- [Other property drops](/homeflow/homeflow_api/wiki/ctesius#other-property-drops)\r\n\t- [Working with maps](/homeflow/homeflow_api/wiki/ctesius#working-with-maps)\r\n\t- [Submitting a lead](/homeflow/homeflow_api/wiki/ctesius#submitting-a-lead)\r\n- [Working with agencies](/homeflow/homeflow_api/wiki/ctesius#working-with-agencies)\r\n\t- [Agency show page](/homeflow/homeflow_api/wiki/ctesius#the-agency-show-page)\r\n- [Working with branches](/homeflow/homeflow_api/wiki/ctesius#working-with-branches)\r\n\t- [The branches index](/homeflow/homeflow_api/wiki/ctesius#the-branches-index)\r\n\t- [Branch maps](/homeflow/homeflow_api/wiki/ctesius#working-with-branch-maps)\r\n\t- [Branch searching](/homeflow/homeflow_api/wiki/ctesius#branch-searching)\r\n\t- [Titles and pagination](/homeflow/homeflow_api/wiki/ctesius#branch-titles-and-pagination)\r\n\t- [The branch show](/homeflow/homeflow_api/wiki/ctesius#the-branch-show)\r\n\t- [Branch properties](/homeflow/homeflow_api/wiki/ctesius#displaying-branch-properties)\r\n\t\t- [Recent sales and lettings](/homeflow/homeflow_api/wiki/ctesius#displaying-branch-properties)\r\n\t\t- [All branch properties](/homeflow/homeflow_api/wiki/ctesius#all-branch-properties)\r\n\r\n#The Homeflow API\r\n\r\nHi there and welcome to the Homeflow wiki.\r\n\r\nHomeflow provides developers with everything they need to build exceptional property based websites. Within this Wiki we hope you will find all the information you need to get your agency or portal theme up and running.\r\n\r\nYou'll use the IDE you're familiar with plus all the developer tools you know and love such as: HTML, CSS, JavaScript and jQuery. You will make your own decisions on the plugins you or your customer requires and have complete design control over your new website from the word go.\r\n\r\nAs alluded to above, we're making the assumption that you're familiar with HTML, CSS etc. You will also need a basic working knowledge of Git and Liquid, though both are relatively simple to pick up as you go along.\r\n\r\nBefore we get started, there are three areas of the Homeflow API to be aware of as they will be mentioned throughout this documentation:\r\n\r\n1) The Agency/Portal Admin<br>\r\n2) Hestia<br>\r\n3) Ctesius\r\n\r\nYou can consider The Agency and Portal Admin as the repository of all the information related to an agency or portal (essentially a CMS) - think properties, pages, content, images and more. Hestia (The Greek Goddess of the Heart) allows the querying of this information at lightning fast speeds. Finally Ctesius (The Greek God of Property) is our frontend application that is powered by Hestia. It includes an event management system, supports advanced property searching, user profiling and will support and augment the theme you will build. \r\n\r\nAll themes are developed using mostly HTML, CSS and JavaScript, but they also make use of the Liquid templating system, made popular by Shopify. Liquid sits in places of your code where dynamic content is required, such as property, agency, staff or user information.\r\n\r\nWe will explore all of the technologies mentioned above in much more detail later in the Wiki. In the meantime you can head straight over to the section you require using the menu on the right or move on to [Getting started](/homeflow/homeflow_api/wiki/ctesius#getting-started).\r\n\r\n#Getting started\r\n\r\nFirstly we will need to initialise a Git repository for your theme on our platform and provide it with an API key so it can query Hestia and get the information it needs. You don't need to do anything here and it's a stage we will automate in the future. \r\n\r\nOnce we have done this we will create you an account on ``Gitlab`` (our internal Git platform) and you will receive an automatic email containing your login information. Before you can get to work on your theme, your will need to supply Gitlab with your ``Public SSH key``. This is so you can clone and push/pull to and from your theme's repository. For information on how to fetch or generate your SSH key, visit [this link](https://help.github.com/articles/generating-ssh-keys#platform-mac). \r\n\r\nThis link will take you to the SSH section on Homeflow where you can paste in your key: ``http://hades.homeflow.co.uk/keys``.\r\n\r\nTo clone your repository, open up a command prompt and ``cd`` to directory of your choice (but one that you won't forget and is easy to get to!) and run the following:\r\n\r\n``git clone <link>``\r\n\r\nYour Git clone URL will look something like: ``git@hades.homeflow.co.uk:fdesign/pantani.git``.\r\n\r\nBy this point we should have provided you with a ``staging`` link so you/your team/your customer can view the development progress of the site. Once you have added your public key and you have successfully cloned your repository, we can now start to put your theme's folder structure together. \r\n\r\n##Theme folder structure\r\n\r\nCtesius themes use the standard Rails conventions for folder layouts. Don't worry if you're not familiar with Rails or this structure as an example theme folder structure can be seen below or found on the demo [Stabilisers theme](https://github.com/homeflow/stabilisers).\r\n\r\n- theme_name\t\t\r\n\t- agencies\r\n\t\t- index.liquid\r\n\t\t- show.liquid\r\n\t- articles\r\n\t\t- index.liquid\r\n\t\t- show.liquid\r\n\t- assets\r\n\t\t- images\r\n\t\t- javascripts\r\n\t\t- stylesheets\r\n\t\t\t- theme_styles.lcss - our LCSS file holds our styles just as a CSS file would\r\n\t- branches\r\n\t\t- _branches_list.ljson - a JSON view to list an array of branches\r\n\t\t- index.liquid\r\n\t\t- show.liquid\r\n\t- home\r\n\t\t- home.liquid - the main homepage\r\n\t- layouts\r\n \t\t- application.liquid - the main layout file which renders the other pages\r\n\t- pages\r\n\t\t- show.liquid\r\n\t- properties\r\n\t\t- _properties_list.ljson - a JSON view to list an array of properties\r\n\t\t- index.liquid\r\n\t\t- show.liquid\r\n\t- staff\r\n\t\t- index.liquid\r\n\t\t- show.liquid\r\n\t- user\r\n\t\t- new.liquid\r\n\r\nIf your repository doesn't have these files and folders yet, add them in. Once done, make your first commit and push to your repository. We would recommend a Git GUI such as Tower for OSx or one of the freebies available for Linux such as Git Cola. If you're using Git via the command line, bring up a terminal, ``cd`` to you theme's root directory and run:\r\n\r\n``git commit -a -m 'Theme folders and files'``\r\n\r\nThen run:\r\n\r\n``git push origin master``\r\n\r\nThis will add all of your modified files, commit them as well as push them to the remote repository. We can't view the site online just yet as there's nothing to render. Time to add some structure and content to our ``application.liquid`` file.\r\n\r\n##The layout File\r\n\r\nEvery page render starts at the layout, which is always found in ``/layouts/application.liquid``. This file will contain the html, head, and body tags and will define the overall 'makeup' of your site.\r\n\r\nTake a look at the source in the Stabilisers theme and you will see there's a few things to note. Firstly we link to the default styles and JavaScripts using our first bit of Liquid syntax:\r\n\r\n```\r\n {{ \"application\" | javascript_include_tag }}\r\n {{ \"application\" | stylesheet_link_tag }}\r\n```\r\n\r\nThis will bring in all the default styles and some JavaScript libraries which form the basis of every Ctesius theme. As of the latest revision to this Wiki, they are:\r\n\r\n- Bootstrap\r\n- jQuery - v1.9\r\n- jQuery Cycle - 3.0.3 (11-JUL-2013)\r\n- jQuery Nivo Slider\r\n- Backbone.js - 1.0.0\r\n- Underscore.js - 1.4.3\r\n- leaflet.js\r\n- Font Awesome\r\n- the Homeflow search and profile system\r\n\r\nYou'll also notice that we make another call:\r\n\r\n``{{ \"stabilisers\" | theme_stylesheet_link_tag }}``\r\n\r\nThere is a subtle different between the two Liquid directives in that the latter has a ``theme_`` directive and the other does not. When you add a theme stylesheet or theme JavaScript directive, the theme will expect the quoted LCSS file to reside in ``/assets/stylesheets`` (``/assets/javascripts`` for JavaScript files). LCSS files are pretty much CSS files run through a Liquid filter. This enables us to customise the CSS easily for different sites. The directive without the theme pointer will load something from the core app.\r\n\r\nContinuing with the layout file the next command you'll see is:\r\n\r\n``{% include 'layouts/js_templates' %}``\r\n\r\nThis is the first include that we've seen. A bit like PHP includes, Liquid includes allow you include a partial template. This is excellent for including blocks that occur on several pages, or, as we'll see later, in Liquid for loops. Important point: partial names must be preceeded by an underscore `_`. When you call the partial however, no underscore is required though you must put the path in quotes.\r\n\r\nThe directive here pulls in the default JavaScript templates for the dynamically drawn user sections of the site. They are all overridable so you can design them as you need to. We'll expand more on these templates later.\r\n\r\nPerhaps the most important section for the layout is the helper ``content_for_layout``. This outputs the rendered results of the rest of the template.\r\n\r\n``{{ content_for_layout }}``\r\n\r\nIn other words, all other template parts are like partials that get evaluated and loaded into this section.\r\n\r\nFinally we need to boot the Ctesius system to handle searches, user profiles and so on. To do that we add the following function: \r\n\r\n``` \r\n <script type=\"text/javascript\">\r\n $(document).ready(function(){ \r\n Ctesius.init()\r\n });\r\n </script>\r\n```\r\n\r\nThis needs to be used after any Ctesius events or config options are set. Some theme developers choose to add this function at the foot of application.liquid whereas others will add it to a theme JavaScripts file, include the directive at the bottom of it, then include the partial.\r\n\r\n##Building up the layout\r\n\r\nOther than the Liquid directives in the head section, the ``content_for_layout`` we saw earlier and the Ctesius boot, the ``application.liquid`` file is constructed just the same as a regular web page - add your classes and IDs, divs and CSS in the normal way and style them up using your theme CSS. Be sure to to put it in the stylesheets directive and make sure the names match up:\r\n\r\n``{{ \"your_theme_css\" | theme_stylesheet_link_tag }}``\r\n\r\nWe talk more about images in the [Working with images and assets](./assets) section, but for now add your agency's/portal's logo into the ``/assets/images`` folder and reference it in your application markup as follows:\r\n\r\n``<img src=\"{{'your_image.png' | theme_image_url : \"70x70\" }}\" />``\r\n\r\nYou will notice that we have added a Liquid directive straight into the source of the image. Liquid will expect there to be an image of the name and extension quoted in your theme images folder (``/assets/images``). Also note that we've added an arguement on the end to ask Liquid to resize the image on the server, then send it to the browser - neat.\r\n\r\n##Running your theme\r\n\r\nNow that you have hopefully added your HTML, some CSS and some images, it's time to see the results. Commit and push your changes and observe the ``staging`` URL we sent to you. It will look something like:\r\n\r\nAgencies: ``http://agency_homeflow_domain.agent.staging.homeflow.co.uk``<br>\r\nPortals: ``http://portal_homeflow_domain.search.staging.homeflow.co.uk``\r\n\r\nHopefully you will see the result in the browser.\r\n \r\n##Building up the application and home page\r\n\r\nAt this point we can start to think about the elements that will be consistent to every page and those that will just reside on the home page. Those that are consistent to every page need to reside in the application.liquid file and would probably include:\r\n\r\n- The header\r\n- The navigation menu\r\n- The footer\r\n\r\n##The header with an agency or portal logo\r\n\r\nA header would probably consist of the agency or portal logo, so let's take a first foray into the Agency or Portal admin, add the logo, then pull it out and plug it into the source using Liquid. Note that if you'd rather just add or keep your logo in ``/assets/images`` that's absolutely fine.\r\n\r\nTo get to your admin, you use a link similar to the two links outlined before:\r\n\r\nAgencies: ``http://agency_homeflow_domain.homeflow.co.uk/admin``<br>\r\nPortals: ``http://portal_homeflow_domain.portal.homeflow.co.uk/admin``\r\n\r\nWe'll assume you have been provided with your login.\r\n\r\nIn the agency admin, go to ``Website/Appearance/Logos`` and upload your logo<br>\r\nIn the portal admin, go to ``Configure/Appearance/Logos`` and upload your portal logo.\r\n\r\nNow in your source, within your header tags or header div tags, add:\r\n\r\nAgency:<br> \r\n``<img src=\"{{ agency.logo | url_for_agency_logo }}\" alt=\"{{agency.name}} logo\" />``\r\n\r\nPortal:<br> \r\n``<img src=\"{{ portal.website_logo | url_for_portal_logo }}\" alt=\"{{portal.name}}\" />``\r\n\r\nThere's a couple of new things here - the first is we need a ``key`` when referencing an agency or portal logo (and many other things as we'll see) and we're using the agency and portal Liquid name tag to fill in the alt attribute of the image. As you become more experienced with your template(s) you will find there's some useful and sometimes innovative ways you can use tags.\r\n\r\n##The navigation menu\r\n\r\nThe navigation is another area where you have complete freedom of development - if you wanted to hardcode your menu and add/remove new or old items as they come along, that's absolutely fine. If however, you'd prefer to add the navigation tree to the agency admin and extract them using Liquid, that's fine too. Generally speaking portals add their menu to their source whereas theme designers or agency sites will tend to code the menu using Liquid, as their theme can then be deployed for multiple agencies.\r\n\r\nLet's assume for now you would like to query the agency admin and therefore Hestia for the menu and, if it has been added, its sub-menu counterpart.\r\n\r\nTo start head over to your agency admin. Reminder: ``http://agency_homeflow_domain.homeflow.co.uk/admin``\r\n\r\nThen go to ``Website/Navigation``. From here you can drag in menu items for existing pages or create custom links, e.g. to the ``/branches`` page for example. Once you've got your primary menu items, you can then edit each one and add sub-menu items.\r\n\r\nHere's a code construct that would retrieve the primary menu items:\r\n\r\n```\r\n{% assign primary_menu = 'primary' | site_menu %}\r\n<ul class=\"top-level\">\r\n\t{% for menu_item in primary_menu.items %}\r\n\t\t<li class=\"top-level-li\">\r\n\t\t\t<a href=\"{{ menu_item.url }}\">{{ menu_item.name }}</a>\r\n\t\t</li>\r\n\t{% endfor %}\r\n</ul>\r\n```\r\n\r\nHere we can see two new things: an ``assign`` statement and a Liquid ``for loop ``.\r\n\r\nThe ``assign`` statement allows you to assign something to a Liquid variable. This can be as simple as a string or result of some evaluation. Also, as seen above, you can assign Liquid objects to a variable for looping and other purposes.\r\n\r\nAnd the good old ``for loop``. You'll probably be familiar with the ``for loop`` from other programming languages and Liquid's variant is very simple to use - loop through an object and you can write out its attributes as required.\r\n\r\nSo what about a nested menu to support dropdrowns? Here's a code construct that will satisfy this requirement:\r\n\r\n```\r\n<ul class=\"top-level\">\r\n\t{% assign primary_menu = 'primary' | site_menu %}\r\n\t{% for menu_item in primary_menu.items %}\r\n\t\t<li class=\"top-level-li\">\r\n\t\t\t<a class=\"navigation\" href=\"{{ menu_item.url }}\">{{ menu_item.name }}</a>\r\n\t\t\t{% if menu_item.items != empty %}\r\n\t\t\t\t<ul class=\"subnav\">\r\n\t\t\t\t\t{% for sub_menu_item in menu_item.items %}\r\n\t\t\t\t\t\t<li>\r\n\t\t\t\t\t\t\t<a href=\"{{sub_menu_item.url}}\">{{sub_menu_item.name }}</a>\r\n\t\t\t\t\t\t</li>\r\n\t\t\t\t\t{% endfor %}\r\n\t\t\t\t</ul>\r\n\t\t\t{% endif %}\r\n\t\t</li>\r\n\t{% endfor %}\r\n</ul>\r\n```\r\n\r\nThere's nothing new here but let's step through what's going on. Firstly we do our ``assign`` then we loop through the ``primary menu items`` and output an ``li`` and ``anchor`` for each. Next we check whether the menu item we're looping over has any items within it by doing an ``if not empty`` test - ``empty`` is a handy Liquid check to see if a variable has been initialised. If so, we output another unordered list and then we loop through the sub menu items of that menu item. We then output an ``li`` and ``anchor`` for each.\r\n\r\nFinally we close off the ``if`` and ``for loop`` using the appropriate end Liquid statements.\r\n\r\n##The carousel\r\n\r\nMany agency sites and indeed portals have what we refer to as a ``carousel`` on their home page. This is a gallery of images with text overlays designed to give the user an attractive initial presentation and to give your site the 'wow' factor. At the time of writing, many theme developers are using full width images within their carousel as well as responsive images to cater for different viewports.\r\n\r\nYour first port of call is to head to the carousel section within the agency or portal admin. You can find that under ``Website/carousel``. Don't worry about the settings for now but instead go straight to ``Add item``. Keep the standard option selected and upload your background image, add a title, a standfirst (the chunk of accompanying text) and a link if required. The minimum you'll want is an image and standfirst.\r\n\r\nNow return to you theme and the ``home/home.liquid`` file. This is one place, and a logical one, where we can add our carousel code:\r\n\r\n```\r\n<ul>\r\n\t{% for item in agency.carousel_items %}\r\n\t <li style=\"background-image:url({{item.image | url_for_generic_image}})\">\r\n\t <div class=\"slide-content\">\r\n\t <h2>\r\n\t \t{% if item.link_url != empty %}\r\n\t \t\t<a href=\"{{ item.link_url }}\" class=\"link_url\" title=\"{{item.title}}\">\r\n\t \t{% endif %}\r\n\t \t\t\t{{item.title}}\r\n\t \t{% if item.link_url != empty %}\r\n\t \t\t</a>\r\n\t \t{% endif %}\t\r\n\t </h2>\r\n\t <p>\r\n\t {{item.standfirst | truncate: 200}}\r\n\t </p>\r\n\t </div>\r\n\t </li>\r\n\t{% endfor %}\r\n</ul>\r\n```\r\n\r\nThere are numerous ways you can use the carousel - some themes have a small photo box whereas others go full width with the photos. In the example above, we are going full width with our carousel image set as a background against the ``li`` for each carousel item using a for loop. As you can see, we check if the ``link_url`` is empty and if not, we wrap out title with the link URL. We then output our standfirst and in this case we truncate it to two hundred characters (more on truncate in a bit). Note that we could run a check on standfirst but here we're assuming a standfirst has been entered for each carousel item.\r\n\r\nWhilst we're covering the carousel and ``home.liquid`` it's worth pointing out that your carousel doesn't have to reside in ``home.liquid``. Many front pages are split into different sections and sometimes it doesn't make sense for everything that is featured on the home page to be in home (by the way the ``home.liquid`` file is automatically included into the ``{{content_for_layout}}`` yield when on the site's root). On occasions where we want to include content on the home page but you'd rather add it to ``application.liquid``, you can use the following statement:\r\n\r\n```\r\n{% if page.controller_name == 'home' %}\r\n\t*content*\r\n{% endif %}\r\n```\r\n\r\nAnd for a handy reference as to what controller is being used, you can add the controller and action as a class to the body tag then inspect the source:\r\n\r\n```<body class=\"{{page.controller_name}} {{page.action_name}}\">```\r\n\r\n##The footer\r\n\r\nAgain, the footer is an area where you can hardcode in your design and content, or you can manage the content using the Agent/Portal admin and the ``content chunks`` we have made available. ``Content chunks`` are well-known content areas that get used on all sites - e.g. a header, footer, sidebar and so on. If we add some content to the footer chunk we can then render it out. \r\n\r\nAgencies: ``Website/Content``<br>\r\nPortals: ``Configure/Content/Pages``\r\n\r\nBoth content chunk sections are then on the left. Checkout the ``Site footer`` chunk, add some filler content for now then save it.\r\n\r\nNow, where you want to render the chunk in your source (if it's the footer then most likely the ``application.liquid`` page), use the following code:\r\n\r\n```\r\n{% content_block 'site_footer' %}\r\n\t{% if content_block %}\r\n\t\t{{content_block}}\r\n\t{% endif %}\r\n{% endcontent_block %}\r\n```\r\n\r\nThis will render your chunk. Note that you can add HTML syntax into the chunk using the MCE editor.\r\n\r\n#Working with property searches\r\n\r\nThis part of the Wiki will explore how we construct the forms and display search results - arguably the most important aspect of a property search website.\r\n\r\n##Constructing a property search form\r\n\r\nSomewhere in your application layout file you're likely to have a property search form. There are a myriad of filter options you can show and a couple of methods of searching which we'll explore later, but for now is a basic form is below. Note we have stripped any classes or styling to keep it as simple as possible:\r\n\r\n```\r\n<form action='/search' id='search' method='get' />\r\n\t<input type=\"radio\" name=\"channel\" value=\"sales\" id=\"buy\"> <label>For Sale</label>\r\n\t<input type=\"radio\" name=\"channel\" value=\"lettings\" id=\"let\"> <label>To Let</label> \r\n\t<button onclick=\"Ctesius.Actions.submitSearchForm(); return false;\" type=\"submit\">Search</button>\r\n</form>\r\n```\r\n\r\nWhen the ``Ctesius.Actions.submitSearchForm()`` is called the system will evaluate every form on the page looking for elements with specified IDs and use them to construct a search. Here the only fields the user can select are whether it's a sales or lettings search. The results that will be shown with this type of form will be an ``index`` of an agency or portal's properties - this is where our ``/properties/index.liquid`` file comes in. More on that in the [Displaying search results](/homeflow/homeflow_api/wiki/ctesius#displaying-search-results) section.\r\n\r\nExpanding on our first example, we can now add two addition fields that allow the user to type in a location. If it's recognised in our database, we'll load a number of suggested locations for the user to select. The hidden place ID field is a lookup reference for our system and is required in the source. With just two extra fields your property search will be completely supported by our geo location database:\r\n\r\n```\r\n<input type='hidden' id ='place_id' name='place_id' value='{{place_id}}' /> \r\n<input placeholder='Town or Postcode' type=\"text\" id='location' name=\"location\" value=\"{{location_field}}\"/>\r\n```\r\n\r\nNow let's add some beds and price bracket options:\r\n\r\n```\r\n<select id=\"min_beds\" name='min_beds'>\r\n\t<option value=\"\" title=\"Min beds\">Beds min</option>\r\n\t<option value=\"1\" title=\"1 Bed\">1 bed</option>\r\n\t<option value=\"2\" title=\"2 Beds\">2 beds</option>\r\n</select>\r\n<select id=\"max_beds\" name='max_beds'>\r\n\t<option value=\"\" title=\"Max beds\">Beds max</option>\r\n\t<option value=\"1\" title=\"1 Bed\">1 bed</option>\r\n\t<option value=\"2\" title=\"2 Beds\">2 beds</option>\r\n</select>\r\n<select id=\"min_price\" name='min_price'>\r\n\t<option value=\"\" title=\"Min price\">Price min</option>\r\n</select> \r\n<select id=\"max_price\" name='max_price'>\r\n\t<option value=\"\" title=\"Max price\">Price max</option>\r\n</select>\r\n```\r\n\r\nThis is probably all self-explanatory. One thing to note is that the IDs and names are important so we can process the form.\r\n\r\nFinally let's add a property type selector:\r\n\r\n```\r\n<select id=\"type\" name='type'>\r\n\t<option value=\"\" title=\"Property type\">Property type</option>\r\n\t{{ agency | tag_dropdown_list }}\r\n</select>\r\n```\r\n\r\nYou will note a snippet of Liquid here. This code takes some pre-selected types in the Agency or Portal Admin and outputs them as options.\r\n\r\nIf it were a portal, you would use the portal tag instead:\r\n\r\n``{{ portal | tag_dropdown_list }}``\r\n\r\nAnother option is to simply specify the types - the names here must match what we use as type references:\r\n\r\n```\r\n<option value=\"cottage\" title=\"cottage\">Cottage</option>\r\n<option value=\"farmhouse\" title=\"farmhouse\">Farmhouse</option>\r\n<option value=\"townhouse\" title=\"townhouse\">Townhouse</option>\r\n```\r\n\r\nAgain you can style the form and position it in anyway you choose. Let's move on and see how we deal with property search results.\r\n\r\n##Displaying search results\r\n\r\nAfter the form has been submitted, Ctesius and Hestia will go off an fetch the results - normally ten per page though this is configurable. A JSON response is returned and Liquid loops through and displays the results.\r\n\r\nThe first file we will want to get up and running is the ``properties/index.liquid`` file, which is located in the ``properties`` folder. The index displays every property belonging to an agency or portal. All searches are channel based so an index could show all sales or all lettings. On the whole the index will check whether the ``properties`` JSON is empty and if not, it will then include a ``_results.liquid`` partial, which is the main body of code that we'll be working with.\r\n\r\nSo the code could look something like this:\r\n\r\n```\r\n{% if properties == empty %}\t\r\n\t<h4>Sorry, we couldn't find any properties for this search.</h4>\r\n{% else %}\r\n\t{% include 'search/results' %}\r\n{% endif %}\r\n```\r\n\r\nNote that in our example above we've put our ``results`` partial in a ``search`` sub-folder. You don't have to do this and your ``results`` partial could reside in the ``properties`` folder if you wish.\r\n\r\nOur ``results`` partial will probably include top and bottom pagination, top and/or bottom search statistics, alternative view types (list, map, grid, etc) and of course the Liquid loop that displays the properties. Note that one, more or indeed all of the above can be partials so we can re-use them if necessary.\r\n\r\n##The properties loop\r\n\r\nSince Liquid for loops can include a partial for each property it makes sense to include a tried, tested and mananageble partial of code for each property. We refer to this partial as ``_property_small.liquid``. \r\n\r\nHere's what our for loop looks like:\r\n\r\n```\r\n{% for property in properties %}\r\n\t{% include \"properties/property_small\" %}\r\n{% endfor %}\r\n``` \r\n\r\nAs you can see we loop through the properties array and include the ``_property_small`` partial for each one. Let's now take a look at what a sample ``_property_small.liquid`` could look like:\r\n\r\n```\r\n<div id=\"property_{{property.property_id}}\" class=\"property-small\">\r\n\t{{ property | photo_overlay }}\r\n\t<a href=\"{{property | url_for_property}}\">\r\n\t\t<img src=\"{{ property.photos.first | url_for_property_asset: \"176x133\" }}\">\r\n\t</a>\r\n\t<a href=\"{{property | url_for_property}}\">\r\n\t\t{{property.display_address | truncate : 60}}\r\n\t</a>\r\n\t<p>{{property.price}}</p>\r\n\t<p>{{property.short_description | truncate : 185}}</p>\r\n\t<p><a href=\"{{property | url_for_property}}\">Full details</a></p>\r\n</div>\r\n```\r\n\r\nLet's step through this. As you can see, we need to wrap each set of results in an ID or class container and we'll need to style up the elements so it renders nicely on a row. We'll assume you are okay with that and explain the Liquid. \r\n\r\nFirstly, the ID of the div is ``property_{{property.property_id}}``. As you can imagine, every property in our system gets assigned a numerical ID, and it's this ID that's used in URL and for other functions on the theme and in the backend. For now, we've outputted the ID so we can use our ``Save to shortlist`` function - more on that later.\r\n\r\nThe next tag ``{{ property | photo_overlay }}`` outputs the property status in the form of a sash image banner, or a custom banner of your choice. You can get to this custom images section via your agency or portal admin with the following link: ``/configure/website/appearance/custom_images``.\r\n\r\nThe next piece of Liquid is: ``{{ property.photos.first | url_for_property_asset: \"176x133\" }}``. As you might imagine, this looks at the photos array and gets the link of the first one for use in the image source. We then use the ``url_for_property_asset`` key and we pass in a size in pixels. As mentioned before, Liquid will resize the image on the server and send it to the browser.\r\n\r\nA tag that's used numerous times in this code, as well as on many of the property related pages; ``{{property | url_for_property}}`` outputs the relative address to the property in question.\r\n\r\nThe next tag is ``{{property.display_address | truncate : 60}}``. This tag outputs the display address of the property, which is the address as it comes in from the agency or portal feeds. A new arguement seen here is ``truncate``. This is a very useful Liquid function, which is particularly useful when curtailing long addresses, descriptions and so on - just pass in the number of characters you want to keep. Another useful truncate function is ``truncatewords: 20``. This does what it says on the tin.\r\n\r\n##Handling locations and postcodes\r\n\r\nSo far we have a basic properties index page and hopefully a set of results using the properties loop. How then, do we deal with locations like counties and towns as well as postcodes? This is where our include partial ``search/_results.liquid`` comes into its own. All we need to do is add three subfolders in the root directory: ``locations``, ``counties`` and ``postcodes``. Within these folders we simply need a ``show.liquid`` file and inside this file we add ``{% include 'search/results' %}``. This will use our search results partial for the location searches - great. W now need to do now is make sure our page headings reflect the search that has been carried out. We may as well look at pagination whilst we're at it, too...\r\n\r\n##Headings and pagination\r\n\r\nHeadings need to reflect the search the user has carried out or it should output a very general statement if it's an index search. There's other considerations here; for instance if it is a county or postcode seach and so on. Some developers choose to add pagination statistics and pagination navigation together with search and location information, whereas others choose to seperate the two - you are free to find whatever suits you/your client. Note that the code below would be in ``search/_results.liquid``. Here's an example heading:\r\n\r\n```\r\n<h1>\r\n\t{{search.dictionary.general_collective | capitalize}} \r\n\t{{search.dictionary.preposition}} \r\n\t{% if location %}in {{location.name}}{% endif %}\r\n</h1>\r\n```\r\n\r\nThis could output something like: \r\n\r\n``Houses for sale in Walton on Thames``\r\n\r\nThe ``general_collective`` is the property type, the ``preposition`` is the channel (sales or lettings) and finally we do a ``location`` test and output the ``in`` and ``{{location.name}}`` if it comes back as true. Let's look at another example:\r\n\r\n```\r\n{{pagination.from_record}} to {{pagination.to_record}} of {{pagination.total_count}} \r\nProperties found \r\n{% if location %} \r\n\tin {{location.name}}\r\n{% endif %}\r\n{% if pagination.has_prev_page %}\r\n | <a href=\"{{pagination.previous_page_link}}\" class=\"pagination_prev\">\r\n \tPrevious {{pagination.page_size}}\r\n </a>\r\n{% endif %}\r\n{% if pagination.has_next_page %}\r\n\t| <a href=\"{{pagination.next_page_link}}\" class=\"pagination_next\">\r\n\t Next {{pagination.page_size}}\r\n\t </a>\r\n{% endif %}\r\n```\r\n\r\nThis might output something like: \r\n\r\n``1 to 12 of 31 Properties found in Walton on Thames | Next 12``\r\n\r\nThis example starts with the ``from_record`` - if your page size is ten (which is the default) then this will go ``1``, ``11``, ``21`` etc. We then output the ``to_record``, which again, if we're going up in tens, this would be ``10``, ``20``, ``30`` etc. We then output ``{{pagination.total_count}}``, which outputs the item count. \r\n\r\nOur next segment of code is two if statements that will output next and previous buttons or links if they are required. As you can see, we can get the next and previous links using the appropriate Liquid syntax as well as a handle on the page size, which is most likely going to be ten, but could be twelve, fourteen or whatever you or your client requires.\r\n\r\n##More on pagination\r\n\r\nCtesius ships with a ``for pagination`` function. If you've ever used Google before, and let's face it, who hasn't, then you'll be familiar with the pages before and after pagination they utilise at the foot of the search results.\r\n\r\nThis function takes a couple of arguements: ``previous`` and ``after``.\r\n\r\nThese arguements allow you to define how many trailing and remaining pages to show. Here's the code:\r\n\r\n ```\r\n {% unless pagination.page_count == 1 %}\r\n <ul>\r\n {% if pagination.has_prev_page %}\r\n {% if pagination.page_count > 2 %}\r\n \t <li><a href='{{pagination.first_page_link}}'>&lt; First</a></li>\r\n {% endif %}\r\n {% endif %}\r\n {% for_pagination pagination previous: 4 after : 4 %}\r\n <li>\r\n \t<a href=\"{% if pagination_item.page_number == pagination.current_page %}#\r\n \t{% else %}{{pagination_item.link}}{% endif %}\" \r\n \t{% if pagination_item.page_number == pagination.current_page %} class='s'{% endif %}>\r\n \t{{pagination_item.page_number}}</a>\r\n </li>\r\n {% endfor_pagination %}\r\n {% if pagination.has_next_page and pagination.current_page != pagination.page_count %}\r\n {% if pagination.page_count > 2 %}\r\n \t<li>\r\n \t\t<a href='{{pagination.last_page_link}}'>Last &gt;</a>\r\n \t</li>\r\n {% endif %}\r\n {% endif %}\r\n </ul> \r\n{% endunless %}\r\n```\r\n\r\nWe start with the first ``unless`` statement we've seen. The ``unless`` statement will continue to output the code between the tags unless a certain condition is met. Here if page count is one, then we don't want to try and output the whole for block (incidentally this could be changed to an ``if/else`` and we could output the first page number to signify there's only one page). Next we use a couple of statments we've already seen and a Liquid tag we've not - ``{{pagination.first_page_link}}`` outputs the first page link.\r\n\r\nNext we get into our for loop. First we give it a reference and then ``previous: 4 after : 4``, meaning we want four trailing pages and four forthcoming pages (if they're available). The body of the for loop outputs the appropriate ``li anchor`` code for each. The final block in this code does a couple of checks to make sure there's pages remaining before outputting a helper ``last`` page link. We then close off our if statements and unless statements in the usual way.\r\n\r\n##Togglable areas\r\n\r\nThe core ``application javascript include`` comes with a JavaScript toggle system that can show and hide different ``tabs`` on a click. This is useful when working with different views and, as we will see later, it is also very useful on the ``property show`` page.\r\n\r\nThere are at least three well defined view types for the results page. They are ``list``, ``grid`` and ``map``. Here's what the code might look like:\r\n\r\n```\r\n<div id='togglable_list' class='togglable_area'>\r\n\t{% include 'properties/properties_list' %}\r\n</div>\r\n<div id=\"properties_grid_toggle_view\" class=\"hidden togglable_area\">\r\n\t{% include 'properties/properties_grid' %}\r\n</div>\r\n<div id='togglable_map' class='togglable_area hidden'>\r\n\t{% include 'properties/pagination_for_map' %}\r\n\t<div id='draggable_map_view'></div>\r\n</div>\r\n```\r\n\r\nThen to link to the views, we simply use the hash reference in the anchor like so:\r\n\r\n```\r\n<li><a href=\"#home\" class=\"active\">LIST</a></li>\r\n<li><a href=\"#grid\">GRID</a></li>\r\n<li><a href=\"#map\">MAP</a></li>\r\n```\r\n\r\nNote that ``#home`` correlates to the default list view.\r\n\r\n##Working with the map view\r\n\r\nCtesius comes loaded with maps for property results, individual properties, branches and so on. A draggable map is at your disposal for property results. The draggable map view can be placed on the map tab outlined above and can also update the property results on the fly based on the user dragging or zooming. To get the map up and running, all you need to do is add the ``draggable_map_view`` div to your tab and supply it with a height and a width in your CSS:\r\n\r\n``<div id='draggable_map_view'></div>``\r\n\r\nGiven that we're allowing the user to zoom and drag, it would be useful to have a dialogue of the current properties that are on display. It would also be useful to update this when the user interacts with the map. With Ctesius's built in event system, we can do just that.\r\n\r\nAbove the ``draggable_map_view`` div, you will see we have an include for map pagination. This is where we can add any map related dialogue we have. In our example below it's actually very little:\r\n\r\n```\r\n<span id='map_info'></span>\r\n{% include 'properties/pagination_links' %}\r\n```\r\n\r\nHere we have an empty div ready to be populated with our dynamic map information and we have a partial to include the list, grid and map links that are common to all of the views. All we need to add to get the map information is two ``Ctesius events``:\r\n\r\n```\r\n<script>\r\n Ctesius.registerEvent('before_draggable_map_updated',function(){\r\n $('#map_info').html('Updating map...')\r\n });\r\n\r\n Ctesius.registerEvent('draggable_map_updated',function(res){\r\n $('#map_info').html('Showing ' + res.properties.length + ' of ' + res.pagination.total_count + ' properties. Zoom in or drag the map to see more.' )\r\n });\r\n</script>\r\n```\r\n\r\nCtesius ``kicks`` events throughout the execution of a theme that we can conveniently get a handle on and perform some kind of action. In our example above, we register a callback function to execute when our draggable map events are kicked. By doing this we can add some nice feedback to the user. You can add these functions anywhere you like though many developers add them to the ``js_event_registers`` partial, which resides in the ``layouts`` folder.\r\n\r\n##Working with grid views\r\n\r\nAt the time of writing many agencies are integrating grid views into their property results. Grid views can sometimes produce a better visual offering than traditional list views and of course offers the user a degree of presentation flexibility. The easiest way to get up and running with a grid view is to have a ``properties_grid`` partial. Within this partial there is a second properties loop:\r\n\r\n```\r\n% for property in properties %}\r\n\t{% include 'properties/property_grid' %}\r\n{% endfor %}\r\n```\r\n\r\nThe partial ``property_grid`` then contains your individual grid view syntax. Since we're running another properties loop you might be forgiven to thinking we're fetching the properties again. Actually what we're doing is processing the same JSON that was returned from list view, so there is little or no overhead.\r\n\r\n##Saving properties to a shortlist\r\n\r\nA common feature on property websites is saving properties to a semi or permanent storage with the appropriate widgets to link to or add/remove properties as the user sees fit. This kind of function is extremely useful on portals, but is also a nice feature for agencies to have. \r\n\r\nOur first port of call is to use our first ``override`` partial so far. An override is simply a partial well-known to Ctesius that's in the ``core`` app ready for use. Sometimes core files can be used without needing to override them but in this instance we'll assume you want to modify the layout or at least have a degree of control over the partial.\r\n\r\nIn your ``js_templates`` folder, add the partial ``_saved_properties.liquid``. In it we need a couple of constructs, the first is:\r\n\r\n```\r\n{% raw %}\r\n\t<script id=\"saved_properties_template\" type=\"text/liquid\">\r\n\t\t<div class=\"content box\">\r\n\t\t <h3>My property shortlist</h3>\r\n\t\t <div class=\"shortlist_inner\">\r\n\t\t\t <div id=\"property_shortlist\" class=\"content-block\"> \r\n\t\t\t\t <div id='favourite_property_list' class=\"content\"></div>\r\n\t\t\t </div>\r\n\t\t </div>\r\n\t\t</div>\r\n\t</script>\r\n```\r\n\r\nEssentially this is our widget container. Here's the next construct:\r\n\r\n```\r\n\t<script id=\"saved_property_template\" type=\"text/liquid\">\r\n\t\t<div id=\"mini_property_{{property.property_id}}\" class=\"mini_property mini_property_{{property.property_id}}\">\r\n\t\t\t<div style=\"position:relative;\" class=\"clearfix\">\r\n\t\t\t\t<img src=\"/liquid_assets/images/delete.png\" style=\"display: none;\" id=\"remove_icon_{{property.property_id}}\"\r\n\t\t\t\t\tclass=\"remove_icon\" onclick=\"javascript:Ctesius.Actions.removeSavedProperty({{property.property_id}})\">\r\n\t\t\t\t<a href=\"{{property.property_url}}\"><img src=\"{{ property.small_photo }}\" class=\"shortlist_img\"></a>\r\n\t\t\t\t<div class=\"featured_property_data\"> \r\n\t\t\t\t <a href=\"{{property.property_url}}\">{{ property.bedrooms }} bedrooms</a><br />\r\n\t\t\t\t <a href=\"{{property.property_url}}\">{{ property.price }}</a><br />\r\n\t\t\t\t <a href=\"{{property.property_url}}\">{{ property.road_name | truncate : 20 }}</a>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</script>\r\n{% endraw %}\r\n```\r\n\r\nThis construct is the actual saved property record within the widget.\r\n\r\nThere's quite a lot here to digest but most of it we have touched on previously in the Wiki. The ``raw`` tag however, is one we haven't seen so far. Anything within the raw tag is ignored by the Liquid serverside parser. Instead it's sent back to the browser for (in our case) the application JavaScript to process. As you can see we output the property's ID in various places so we can get a handle on it.\r\n\r\nNext we need to allow our widget to show up somewhere in your theme - typically a sidebar. Add the following code whereever you would like it to show: \r\n\r\n``<div id=\"saved_properties_view\" class=\"hidden\"></div>``. \r\n \r\nThis will render the results of the script code seen above within the ``saved_properties_view`` div tags.\r\n\r\nNext we need to output a save button or link on each property. To do that we add the following code to our ``_property_small.liquid`` that we worked with earlier in the Wiki (and the grid view if you have one):\r\n\r\n```\r\n<a class=\"shortlist_link_{{ property.property_id }}\" \r\nonclick=\"Ctesius.Actions.addSavedProperty({{property.property_id}}); return false;\">\r\n\tAdd to Shortlist\r\n</a>\r\n```\r\n\r\nThe new code here is the ``Ctesius addSavedProperty action`` - essentially this saves the JSON representation of property's information to the browser's local storage for retrieval as and when required. It is now close to working but there's some events we need to add to ``js_event_registers`` to stitch it all together. The first is in an event to do some stuff when the view is rendered (i.e. when the user clicks the add button):\r\n\r\n```\r\nCtesius.registerEvent('saved_property_view_rendered', function(saved_property){\r\n\t$('#saved_properties_view').removeClass(\"hidden\");\r\n\t$(\".shortlist_link_\"+saved_property.id).html(\"Remove from Shortlist\");\r\n\t$(\".shortlist_link_\"+saved_property.id).attr(\"onclick\", 'Ctesius.Actions.removeSavedProperty('+saved_property.id+'); return false;');\r\n\t$('#mini_property_'+saved_property.id).mouseenter(function(){$('#remove_icon_'+saved_property.id).show()});\r\n\t$('#mini_property_'+saved_property.id).mouseleave(function(){$('#remove_icon_'+saved_property.id).hide()});\r\n});\r\n```\r\n\r\nFirstly we remove the hidden class from our sidebar widget so it shows. We then target the link, change the HTML to ``Remove from Shortlist`` then we add a click event to remove the very same property. Our last two lines are jQuery callback functions that show or hide the visual aid signifiying the user can remove the property.\r\n\r\n##Saving searches\r\n\r\nSaving searches is a tad quicker and easier to set up than the saved properties and they save in much the same way as the saved properties. They also make use of the events system to give the user some feedback. Here's the first bit of code you will need to add where you would like the link/button:\r\n\r\n```\r\n{% if location %}\r\n <li><a onclick=\"Ctesius.Actions.saveCurrentSearch();\" id=\"save_search\">SAVE SEARCH</a></li>\r\n{% endif %}\r\n```\r\n\r\nHere you can see we have wrapped the link in a location if statement. You don't _have_ to do this, though a saved search and the resultant email alerts to the user might not be very useful if the properties are not where they want to live or the location where they searched. Much like the saved properties function, here we call ``saveCurrentSearch()``. We also give the link an ID so we can grab it in context using our events. \r\n\r\nSpeaking of events, here's the two we'll need to provide the user with some feedback:\r\n\r\n```\r\nCtesius.registerEvent('saved_search_added', function(search, collection){\r\n if (search.equalTo(Ctesius.getSearch())){\r\n $('#save_search').html('REMOVE SEARCH');\r\n $(\"#save_search\").attr(\"onClick\", 'Ctesius.Actions.removeSavedSearch(\"'+search.search_id()+'\");')\r\n }\r\n\r\n $('#saved_searches_link').effect('highlight',{color: '{{theme_preferences.accent_colour}}'}, 3000);\r\n});\r\n\r\nCtesius.registerEvent('saved_search_removed', function(search, collection){\r\n if (search.equalTo(Ctesius.getSearch())){\r\n $(\"#save_search\").html(\"SAVE SEARCH\")\r\n $(\"#save_search\").attr(\"onclick\", 'Ctesius.Actions.saveCurrentSearch();')\r\n }\r\n});\r\n```\r\n\r\nAgain we're calling some Ctesius functions that will add or remove the saved search accordingly. We then set the display of the link and add the ``onclick`` events as needed. There's a couple of new statements used in this code that are worth a look:\r\n\r\n```$('#saved_searches_link').effect('highlight',{color: '{{theme_preferences.accent_colour}}'}, 3000);```\r\n\r\nThe first is more a concept than anything else - the events that we can get a handle on are not only good for adding and removing properties, searches etc, but can also be used to provide visual aids to the user. Here the ``saved_searches_link`` in the user profile header (more on this later) is highlighted and then fades out to show the user that the search was saved and can be viewed/amended in their control panel.\r\n\r\nThe other new Liquid tag is ``{{theme_preferences.accent_colour}}``.\r\n\r\nEarlier we mentioned that LCSS files are run through a Liquid filter. If you're building a theme that will be rolled out to multiple agencies, or if you want to standardise the colour palette and manage it in one place, you can use the ``agency/portal admin`` to set the colours, then pull them out in Liquid using tags similar to the one above. \r\n\r\n#Draw a Map\r\n\r\n*Coming soon*\r\n\r\n#The property show page\r\n\r\n##Outputting basic information\r\n\r\nMany of the concepts we have used on the results partial, property small and elsewhere in the Wiki get used on the property show page as well. The goal of the show page is to show all of the property's photos, videos, its full description, floor plans, brochures, Energy Performance Certificates (EPC) and its location on a map (including a Street view), then channel all of this into a telephone or email lead to the agency.\r\n\r\nYour first requirement is likely to be an output of the property's address, or at least part of it, and its price in a title:\r\n\r\n```\r\n<h1>{{property.display_address}}</h1>\r\n<h2>{{property.price}}</h2>\r\n```\r\n\r\nNext you will probably want to output the photos of the property. Many developers use jQuery type photo sliders for displaying and navigating through the photos. Thankfully, by using the photos loop, this is relatively easy to achieve:\r\n\r\n```\r\n{% for photo in property.photos %}\r\n <img src=\"{{ photo | url_for_property_photo : \"410x308\"}}\" height=\"308\" width=\"410\" />\r\n{% endfor %}\r\n```\r\n\r\nAnd if you just wanted the property's main photo:\r\n\r\n```\r\n<img src=\"{{property.main_photo | url_for_property_photo : \"410x308\"}}\" height=\"308\" width=\"410\" />\r\n```\r\n\r\nNext we might want to output the short description for the property:\r\n\r\n```\r\n{{property.short_description | truncate: 900}}\r\n```\r\n\r\nThen, to get the property's status (Sold, Let, etc), we can use:\r\n\r\n```\r\n<h4>{{property.status}}</h4>\r\n```\r\n\r\n##Other property drops\r\n\r\n```\r\n{{property.available_on}}\r\n```\r\n\r\nIf supplied, the date the property is available.\r\n\r\n```\r\n{% for feature in property.features %}\r\n {{ feature }}\r\n{% endfor %}\r\n```\r\n\r\nA list of property features that can be outputted to bullet points.\r\n\r\n```{{property.description}}```\r\n\r\nThe full description.\r\n\r\n```{{property.road_name}}```\r\n\r\nThe property's road name.\r\n\r\n```{{ property.vox_number }}```\r\n\r\nHomeflow is able to generate recorded telephone numbers for properties. Doing a check on this drop can see whether one is available.\r\n\r\n```{{property.bedrooms}}```\r\n\r\nA numerical figure that sometimes comes in as zero or empty so needs to be checked.\r\n\r\n```{{property.bathrooms}}```\r\n\r\nAs above.\r\n\r\n```{{property.reception_rooms}}```\r\n\r\nAs per bedrooms.\r\n\r\n```{{property.property_ref}}```\r\n\r\nThe agent's supplied property reference.\r\n\r\n```\r\n{% for floorplan in property.floorplans %}\r\n {% if forloop.first %}\r\n <a href=\"http://mr0.homeflow.co.uk/{{ floorplan.image }}\" title=\"Floor plan\">\r\n {% if property.floorplans.size == 1 %}\r\n View floor plan\r\n {% else %}\r\n View floor plans\r\n {% endif %}\r\n </a>\r\n {% else %}\r\n <a href=\"http://mr0.homeflow.co.uk/{{ floorplan.image }}\" style=\"display:none;\" title=\"Floor plan\"></a>\r\n {% endif %}\r\n{% endfor %}\r\n```\r\n\r\nThe collection of floor plans. This loop could output the floor plans to a light box e.g Fancybox, Colorbox, etc.\r\n\r\n```\r\n{% for brochure in property.brochures %}\r\n <li><a href=\"{{ brochure | url_for_property_asset }}\">Download brochure</a></li>\r\n{% endfor %}\r\n```\r\n\r\nThis for loop would output all the brochures supplied.\r\n\r\n```\r\n{% for epc_chart in property.epc_charts %}\r\n {% if forloop.first %}\r\n <a href=\"{{ epc_chart | url_for_property_asset }}\">\r\n {% if property.epc_charts.size == 1 %}\r\n View EPC chart\r\n {% else %}\r\n View EPC charts\r\n {% endif %}\r\n </a>\r\n {% else %}\r\n <a href=\"{{ epc_chart | url_for_property_asset }}\" style=\"display:none\"></a>\r\n {% endif %}\r\n{% endfor %}\r\n```\r\n\r\nAs per above and floor plans.\r\n\r\n##Working with maps\r\n\r\nMany developers employ the tabbing system for property maps so the user can cycle through the different types: road, streetview and satellite. The first requirement is some events:\r\n\r\n```\r\n<script>\r\n Ctesius.addConfig('small_map_element', 'contact_map')\r\n Ctesius.registerEvent('render_tab', function(tab_name){\r\n switch(tab_name){\r\n case 'streetview':\r\n {% gmap_for property as streetview in streetview %}\r\n break;\r\n case 'satellite':\r\n {% gmap_for property as satellite in satellite %}\r\n break;\r\n }\r\n });\r\n</script>\r\n```\r\n\r\nThe first line here adds our map to the ``contact_map`` ID or class (seen below). The ``render_tab`` event registers a callback function that renders the appropriate Google map depending on the tab clicked. We then have our anchors and togglable areas:\r\n\r\n```\r\n<a class=\"selected\" id=\"tab_map\" href=\"#tabs/map\">MAP</a>\r\n<a id=\"tab_streetview\" href=\"#tabs/streetview\">STREETVIEW</a>\r\n<a id=\"tab_satellite\" href=\"#tabs/satellite\">SATELLITE</a>\r\n```\r\n\r\n```\r\n<div id=\"togglable_map\" class=\"togglable_area\">\r\n <div id=\"contact_map\"></div>\r\n</div>\r\n<div id=\"togglable_streetview\" class=\"togglable_area hidden\">\r\n <div id='streetview' class=\"google_map_container\"></div>\r\n</div>\r\n<div id=\"togglable_satellite\" class=\"togglable_area hidden\">\r\n <div id='satellite' class=\"google_map_container\"></div>\r\n</div>\r\n```\r\n\r\n##Submitting a lead\r\n\r\nEmail type leads are submitted to Homeflow and then on to the agent by ubiquitous web forms. Here's a simplified version:\r\n\r\n```\r\n <form action=\"/properties/{{property.property_id}}/{{property.primary_channel}}/leads\" method=\"post\">\r\n <div id='form_error'></div>\r\n <label class=\"text\" for=\"firstname\">First name</label>\r\n \t<input id=\"firstname\" name=\"lead_client[first_name]\" type=\"text\">\r\n <label class=\"text\" for=\"surname\">Last name</label>\r\n \t<input id=\"surname\" name=\"lead_client[last_name]\" type=\"text\">\r\n <label class=\"text\" for=\"email\">Email</label>\r\n \t<input id=\"email\" name=\"lead_client[email]\" type=\"email\">\r\n <label class=\"text\" for=\"telephone\">Telephone</label>\r\n \t<input id=\"telephone\" name=\"lead_client[tel_home]\" type=\"text\">\r\n <label class=\"text\" for=\"message\">Message</label>\r\n \t<textarea id=\"message\" name=\"lead[message]\" rows=\"3\"></textarea>\r\n <button type=\"submit\">Send enquiry</button>\r\n</form>\r\n```\r\n\r\nIf you are familiar with forms, which we're sure you are, there will be nothing new here to you. The only requirements are the names of the fields as well as the form action. The form error div near the top is reserved for any lead sending errors. Once a lead is sent, a ``flash message`` can be displayed. We have a whole array of flash notices that are used depending on the response back from the server and to display the notices, all you need to do is and the alert location div to your ``application.liquid`` or on the subject page itself:\r\n\r\n```\r\n<div id='alert_location'></div>\r\n```\r\n\r\n#Working with agencies\r\n\r\nMore commonly found on portals, the agency page acts as the top level holdall for the agency's branches, staff, contact details and so on. The Ctesius app comes with a URL pattern that can describe the agency, the branch and the staff, should you need it to. Let's look at what a typical agency page might contain.\r\n\r\n##The agency show page\r\n\r\nAnything 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:\r\n\r\n```\r\n<h1>{{agency.name}}</h1>\r\n```\r\n\r\n```\r\n{% if agency.portal_logo %}\r\n\t<img src=\"{{agency.portal_logo | url_for_agency_logo : \"200x_\"}}\" />\r\n{% elsif agency.logo %}\r\n\t<img src=\"{{agency.logo | url_for_agency_logo : \"200x_\"}}\" />\r\n{% endif %}\r\n```\r\n\r\n```\r\n{{agency.description}}\r\n```\r\n\r\nNext, let's add a Google style map to our show page - note that this will show the branches belonging to an agency:\r\n\r\n```\r\n<div id='agency_map'></div>\r\n```\r\n\r\n```\r\n<script>\r\n\t{% gmap_for agency.branches as roadmap in agency_map %}\r\n</script>\r\n```\r\n\r\n\r\nDon't forget to give your map div a height and a width setting in your CSS. \r\n\r\nIf you would prefer to use a Leaflet style map:\r\n\r\n```\r\n<div id='branches_map'></div>\r\n```\r\n\r\n```\r\n<script type=\"text/javascript\">\r\n Ctesius.addConfig('branch_map_element', 'branches_map');\r\n Ctesius.addConfig('branches', {% include_as_json branches/branches_list %});\r\n</script>\r\n```\r\n\r\nNow let's extract the branches of an agency, including their branch pic or logo, description etc:\r\n\r\n```\r\n{% for branch in agency.branches_ordered_alphanumerically %}\r\n {% include \"branches/branch_small\" %}\r\n{% endfor %}\r\n```\r\n\r\nNote 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.\r\n\r\nFinally, let's see how we can extract some social media links from the CRM:\r\n\r\n```\r\n{% if agency.has_social_links %}\r\n\t<div class=\"agency_social\">\r\n {% if agency.facebook_uri %}\r\n \t<a href=\"{{agency.facebook_uri }}\" target=\"_blank\"><img src=\"{{'facebook' | theme_image_url}}\" width=\"32\" height=\"32\"></a>\r\n {% endif %}\r\n {% if agency.twitter_uri %}\r\n \t<a href=\"{{agency.twitter_uri }}\" target=\"_blank\"><img src=\"{{'twitter' | theme_image_url}}\" width=\"32\" height=\"32\"></a>\r\n {% endif %}\r\n {% if agency.linkedin_uri %}\r\n \t<a href=\"{{agency.linkedin_uri }}\" target=\"_blank\"><img src=\"{{'linkedin' | theme_image_url}}\" width=\"32\" height=\"32\"></a>\r\n {% endif %}\r\n {% if agency.googleplus_uri %}\r\n \t<a href=\"{{agency.googleplus_uri }}\" target=\"_blank\"><img src=\"{{'google-plus' | theme_image_url}}\" width=\"32\" height=\"32\"></a>\r\n {% endif %}\r\n\t</div>\r\n{% endif %}\r\n```\r\n\r\nThis 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.\r\n\r\n#Working with branches\r\n\r\nWay back at beginning of the Wiki we outlined the Rails folder structure we must use in order to retrieve property, agency, branch information and so on. To retrieve everything related to a branch, to perform branch searches and generally build the template up, we need to work in our ``branches`` folder. Let's start with the index file.\r\n\r\n##The branches index\r\n\r\nAs we saw with the ``properties index``, our index pages are called when no seach criteria is given and we just want a flat list of all properties, branches, etc. A branches index route would simply be: ``http://www.agency_domain.com/branches``. On our index page we can add the following code:\r\n\r\n```\r\n{% if branches != empty %}\r\n\t{% for branch in branches %}\r\n\t\t{% include \"branches/branch_small\" %}\r\n\t{% endfor %}\r\n{% endif %}\r\n```\r\n\r\nThis construct is exactly the same as a properties loop seen before except we are referencing our branches collection as well as including a ``branch_small`` partial for each returned branch. A ``branch_small`` might look something like:\r\n\r\n```\r\n<div class=\"branch\">\r\n\t{% if branch.agency.portal_logo %}\r\n\t <img src=\"{{ branch.agency.portal_logo | url_for_agency_logo : \"150!\" }}\" />\r\n\t{% else %}\r\n\t <img src=\"{{ 'awaiting-image.png' | theme_image_url }}\" />\r\n\t{% endif %}\t\r\n\t<div class=\"details\">\r\n\t\t<h3>\r\n\t\t\t<a href=\"{{ branch | url_for_branch}}\">{{branch.name}} branch</a>\r\n\t\t</h3>\r\n\t\t<p class=\"content\">\r\n\t\t\t{{branch.description | strip_tags | truncate : 250}}\r\n\t\t</p>\r\n\t\t<p>\r\n\t\t\t<a href=\"{{ branch | url_for_branch}}\">More Information</a>\r\n\t\t</p>\r\n\t</div>\r\n</div>\r\n```\r\n\r\nHere we are checking whether the agency's portal logo has been set and if it has, we output it in the source. Note you could use ``{{ branch.photo | url_for_generic_image: \"150!\" }}`` instead, which would retrieve the branch photo as set in the branches area of the agency or portal admin. This photo is normally a shop front image or something similar. As another alternative, you could use the overall agency logo: ``{{ agency.logo | url_for_agency_logo : '150!'}}``. Note that we've got a backup coded in to output a standard holding image if no portal logo is available. This is a ``theme_image_url`` - you may remember theme images reside in ``/assets/images``.\r\n\r\nOne new element here is the bang (explanation mark) after the width dimension. We've built in some nifty Liquid filters that give you some flexiblity when requesting images from the server. In this instance we're saying: get us the agency portal logo and resize it so the width and height are no more than 150 pixels. Other options here are to specify the dimensions exactly or specify a height or a width, then get Liquid to automatically set the other dimension whilst retaining the aspect ratio - we do this by using an underscore where the dimension you want to calculate would normally be, e.g: \"150x_\".\r\n\r\nNext we're outputting the branch name and wrapping it in the URL for the branch. We then go on to output the branch description. Note that in some instances you might be able to guarantee that the description has been added, if you can't then you can wrap the output in an ``{% if branch.description %}``. Note the truncate filter that we've seen before. There's also a new filter here called ``strip_tags``. Along with ``strip_html`` and ``strip_links`` it strips the description of any unwanted HTML tags and links.\r\n\r\nNot every theme will call for a ``branch_small`` partial to be used - some might just have the name of the branch and a link, whilst others might have the name, link and a map of the branches.\r\n\r\n##Working with branch maps\r\n\r\nHomeflow supports a variety of map types which you can extend with custom pins, overlays and so on. The first and easiest map to set-up is the Leafleft.js map type. To get this up and running on the branches index page, start by adding:\r\n\r\n```\r\n<script>\r\n\tCtesius.addConfig('branch_map_element', 'branch_map');\r\n\tCtesius.addConfig('branches', {% include_as_json branches/branches_list %});\r\n</script>\r\n```\r\n\r\nThis is the first time we've seen a built-in Ctesius ``addConfig`` function - the first ``addConfig`` assigns our branch map to the element ``branch_map`` whilst the second outputs a dump of JSON branch information for use on the front end. Next we need to declare our ``div`` to apply the map to:\r\n\r\n``<div id=\"branch_map\"></div>``\r\n\r\nDon't forget to give your map ID or class and height and/or width to get it to show up. This should be enough to get your Leaflet branch map showing with a pin for each branch. The map bubbles have a fairly basic presentation that's fine for most, but if you would like to customise your pin, you can override ``_branch_map_pin.liquid`` in your ``js_templates`` folder and customise the layout and styles as necessary. Note that you'll need the basic layout code in the override, if you don't have this, pop us a line or grab it from another theme if we've given you access.\r\n\r\nIf you would prefer a Google style map you still need the ``addConfig branches`` code seen before, but this time, instead of your ``addConfig branch_map``, we need:\r\n\r\n``{% gmap_for agency.branches as roadmap in branch_map %}``\r\n\r\nThis should then populate your ``branch_map`` div with a Google style map. Note that we're using the ``agency.branches`` ``drop`` to access the branches belonging to an agency.\r\n\r\n##Branch searching\r\n\r\nIf you're building a portal or larger agency theme, you will pleased to know that users can search for your branches using our geo location database. This comes complete with a handy AJAX style auto suggest location based on the town or city the user enters. To get up and running, first we need to add our form:\r\n\r\n```\r\n<form action=\"/branches\" id=\"search\" method=\"get\"> \r\n <input type=\"text\" name=\"location\" id=\"location\" class=\"autocomplete_location\">\r\n <input type='hidden' name='place_id' value='{{place_id}}' class='autocomplete_location_result' />\r\n <button value=\"Search\" type=\"submit\"></button> \r\n</form>\r\n```\r\n\r\nNext where you branch results need to be, we have:\r\n\r\n```\r\n{% if branches != empty %}\r\n\t{% for branch in branches %}\r\n\t\t{% include 'branches/branch_small' %}\r\n\t{% endfor %}\r\n{% else %}\r\n\t<h1>Sorry, no branches were found.</h1>\r\n{% endif %}\r\n```\r\n\r\nThe output here will be an index of branches, but if we submit our form with a location, our branches controller will go off, fetch the results and display them in place of the index results.\r\n\r\n##Branch titles and pagination\r\n\r\nMuch like we saw earlier in teh Wiki with property results, it's useful to output some titles and especially useful to output pagination if the branch results are on several pages. There's a number of ways that you can deal with titles - here's one such example:\r\n\r\n```\r\n{% if location %}\r\n\t{% if location.name != ''%}Branches in {{ location.name }}{% if county %}, {{county.name}}{% endif %}{% endif %}\r\n{% elsif county %}\r\n\tBranches in {{ county.name }}\r\n{% elsif postcode %}\r\n\tBranches in {{ postcode.postcode }}\r\n{% else %}\r\n\tBranches Index\r\n{% endif %}\r\n```\r\n\r\nAs you can see, the IF statement checks for the location or location type and outputs the appropriate heading between a heading tag. Remember that if you use the construct multiple times, you can add it to a partial if you wish.\r\n\r\nThe branches index results comes loaded with the same pagination figures and options we saw in the property results earlier. Here's an example construct:\r\n\r\n```\r\nPage {{pagination.current_page}} of \r\n{% if pagination.has_next_page %}\r\n\t{{pagination.total_count}}\r\n{% else %}\r\n\t{{pagination.current_page}}\r\n{% endif %}<br>\t\t\r\n{% if pagination.has_prev_page %}\r\n\t<a href=\"{{pagination.previous_page_link}}\">&laquo; Previous page</a>\r\n{% endif %}\r\n{% if pagination.has_prev_page and pagination.has_next_page %} \r\n\t- \r\n{% endif %}\r\n{% if pagination.has_next_page %}\r\n\t<a href=\"{{pagination.next_page_link}}\">Next page &raquo;</a>\r\n{% endif %}\r\n```\r\n\r\nThis might output something like:\r\n\r\n```\r\n\t\tPage 2 of 178\r\n« Previous page - Next page »\r\n```\r\n\r\nBy running various IF checks, we can essentially figure out whether there's a next and/or previous page (for example) and format the output accordingly.\r\n\r\n##The branch show\r\n\r\nWherever we have a Liquid tag that looks like ``{{ branch | url_for_branch}}`` or if the branch URL is called, the branch show page will get called into action. As with all of the subjects, the branch show page is simply titled ``show.liquid`` and lives in the branches folder.\r\n\r\nThe branch show page supports many of the things we saw on the property show page - for instance, you could have a JavaScript based carousel showing branch photos, list the staff members belonging to a branch, output the branch description and so on. What information you fetch and how you display it will of course depend on your design, but let's run through the basics:\r\n\r\nTo get the branch name we use the branch drop and name: ``{{branch.name}}``. Moving on, we can then fetch the branch description:\r\n\r\n```\r\n{% if branch.description_with_agency_fallback %}\r\n\t<p>\r\n\t\t{{branch.description_with_agency_fallback | strip_html}}\r\n\t</p>\r\n{% endif %}\r\n```\r\n\r\nThis nifty bit of code will try and get the branch description, but if it's empty, we'll get the agency description. Note that it is unlikely an agent will not have a description for their branch AND their agency, but it's always good practice to check. Notice also we're stripping the HTML as sometimes some links and other formatting gets added to the description which can wreak havoc on our layout.\r\n\r\nStaff profiles are a whole subject unto themselves which we will look at later in the Wiki but for now, if you wanted to display some mini profiles with links to full profiles, or just give you branch pages the human touch, you could use something like:\r\n\r\n```\r\n{% unless branch.staff_profiles.size == 0 %}\r\n\t<div class=\"sm_staff_gallery\">\r\n\t\t{% for staff_member in branch.staff_profiles limit:6 %}\r\n \t\t{% if staff_member.avatar %}\r\n\t\t <a href=\"{{ staff_member | url_for_staff_member}}\" title=\"{{staff_member.name}}\">\r\n\t\t \t<img src=\"{{ staff_member.avatar | url_for_staff_profile_avatar : \"40x40\" }}\" title=\"{{staff_member.name}}\">\r\n\t\t </a>\r\n\t\t\t{% else %}\r\n\t\t \t<a href=\"{{ staff_member | url_for_staff_member}}\" title=\"{{staff_member.name}}\">\r\n \t\t\t\t\t<img src=\"/liquid_assets/images/sp.jpg\" height=\"40\" width=\"40\" title=\"{{staff_member.name}}\">\r\n \t\t\t\t</a>\r\n \t\t{% endif %}\r\n \t{% endfor %}\r\n </div>\r\n{% endunless %}\r\n```\r\n\r\nEverything here should be reasonably familiar to you, though note we've added a ``limit`` to our for loop so that a maximum of six profiles are extracted. Also note that we're referencing a fallback image directly. Whilst this is a quirk of this code copied from a theme, sometimes you might need to reference an image using its relative path. On the whole though, you can just use Liquid and ``theme_image_url``.\r\n\r\n##Displaying branch properties\r\n\r\nThe branch properties page is one where we can thankfully reuse our property loops and pagination figures as seen on the property results. Alternatively we can make use of the tabbing facility and include a function that will return some recent sales or recent lettings. If you would like to get the full results and make use of pagination, we'll need to use the former of the two options as the properties method in the branches controller needs to run to return the results and pagination.\r\n\r\nTypically branch pages will make use of our built-in tabbing facility as seen earlier for property results. To get the tabs up and running, you will need the following code:\r\n\r\n```\r\n<ul class=\"nav-menu nav-tabs\">\r\n <li><a href=\"#tabs/summary\" id=\"tab_summary\" class=\"selected\">Summary</a></li>\r\n <li><a href=\"#tabs/team\" id=\"tab_team\">Meet our team</a></li>\r\n <li><a href=\"#tabs/sales\" id=\"tab_sales\">Our sales</a></li>\r\n <li><a href=\"#tabs/lettings\" id=\"tab_lettings\">Our lettings</a></li>\r\n</ul>\r\n```\r\n\r\nNB: the Ctesius app will take care of adding ``selected active`` classes to your tabs but you will need to style them.\r\n\r\n###Recent sales and lettings\r\n\r\nNow we have our tabs, we can add the area that will be toggled on a click. Here's what a togglable sales tab and recent branch sales function looks like:\r\n\r\n```\r\n{% if branch.recent_sales_properties != empty %}\r\n <script>\r\n {% assign properties = branch.recent_sales_properties %}\r\n sales_property_for_config = {% include_as_json properties/properties_list %}.properties\r\n </script>\r\n <div id=\"togglable_sales\" class=\"togglable_area clearfix hidden\">\r\n \t<h2>Latest sale listings for {{branch.name}}</h2> \r\n\t {% for property in branch.recent_sales_properties limit: 20 %}\r\n\t {% include \"properties/property_small\" %}\r\n\t {% endfor %}\r\n </div>\r\n{% endif %}\r\n```\r\n\r\nHere we're making us of one of Ctesius's many built-in functions - this one gets recent properties that the branch has added or we have received via a feed. To get this up and running we literally call the function which returns the JSON we need. We then use the good ol' properties loop to output the results, whilst reusing our ``property_small``. Note that we've wrapped this whole block in an IF statement that checks if the function returns empty. It would be good practice to hide the link to the tab if the function has no results too.\r\n\r\nTo get this up and running for lettings, just substitute any reference to sales for lettings.\r\n\r\n###All branch properties\r\n\r\nIf you would like to display all properties that belong to a branch with pagination, we'll need a ``properties.liquid`` file within the branches folder. Once you have this you can start to build up the layout. This will most likely be a hybrid of your properties result page and your branch show page so use partials where possible and reuse what you've already written. \r\n\r\nTo start with, you might want to add a title:\r\n\r\n```\r\n<h1>{{agency.name}} - {{branch.name}} branch - All {{current_channel}}</h1>\r\n```\r\n\r\nNot much new here but it's worth knowing that ``{{current_channel}}`` will return either a 'Sales' or 'Lettings' string. Next you might want some tabs that will enable the user to navigate around:\r\n\r\n```\r\n<ul class=\"nav-menu nav-tabs\">\r\n\t<li><a href=\"{{branch | url_for_branch : branch.agency}}#tabs/summary\" id=\"tab_summary\">Summary</a></li>\r\n\t<li><a href=\"#tabs/team\" id=\"tab_team\">Meet our team</a></li>\r\n\t{% if branch.sales_branch_properties_count > 0 %}\r\n\t\t<li><a href=\"{{branch | url_for_branch : branch.agency}}/sales\" id=\"sales\">Our sales</a></li>\r\n\t{% endif %}\r\n\t{% if branch.lettings_branch_properties_count > 0 %}\r\n\t\t<li><a href=\"{{branch | url_for_branch : branch.agency}}/lettings\" id=\"lets\">Our lettings</a></li>\r\n\t{% endif %}\r\n</ul>\r\n```\r\n\r\nThe first two tabs here would be hidden tabs on the page that get selected and displayed on a click. The branch properties tabs however, need to go through the branch properties controller to get the results. All we need do here is specify the appropriate branch URL with ``/sales`` or ``/lettings``. If you're developing a portal with agencies that have multiple branches, you will need to use ``{{branch | url_for_branch : branch.agency}}`` in your URL, else you can just use ``{{branch | url_for_branch}}``.\r\n\r\nNext we need to output the actual results that are returned from our request. Thankfully this is just the same as outputting our property results seen earlier so you will have your pagination header, property loop, property small output and footer pagination (if required).","google":"","note":"Don't delete this file! It's used internally to help with page regeneration."}
@@ -0,0 +1,226 @@
1
+ html, body, div, span, applet, object, iframe,
2
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
3
+ a, abbr, acronym, address, big, cite, code,
4
+ del, dfn, em, img, ins, kbd, q, s, samp,
5
+ small, strike, strong, sub, sup, tt, var,
6
+ b, u, i, center,
7
+ dl, dt, dd, ol, ul, li,
8
+ fieldset, form, label, legend,
9
+ table, caption, tbody, tfoot, thead, tr, th, td,
10
+ article, aside, canvas, details, embed,
11
+ figure, figcaption, footer, header, hgroup,
12
+ menu, nav, output, ruby, section, summary,
13
+ time, mark, audio, video {
14
+ margin: 0;
15
+ padding: 0;
16
+ border: 0;
17
+ font-size: 100%;
18
+ font: inherit;
19
+ vertical-align: baseline;
20
+ }
21
+ /* HTML5 display-role reset for older browsers */
22
+ article, aside, details, figcaption, figure,
23
+ footer, header, hgroup, menu, nav, section {
24
+ display: block;
25
+ }
26
+ body {
27
+ line-height: 1;
28
+ }
29
+ ol, ul {
30
+ list-style: none;
31
+ }
32
+ blockquote, q {
33
+ quotes: none;
34
+ }
35
+ blockquote:before, blockquote:after,
36
+ q:before, q:after {
37
+ content: '';
38
+ content: none;
39
+ }
40
+ table {
41
+ border-collapse: collapse;
42
+ border-spacing: 0;
43
+ }
44
+ body {
45
+ font-size: 13px;
46
+ line-height: 1.5;
47
+ font-family: 'Helvetica Neue', Helvetica, Arial, serif;
48
+ color: #000;
49
+ }
50
+
51
+ a {
52
+ color: #d5000d;
53
+ font-weight: bold;
54
+ }
55
+
56
+ header {
57
+ padding-top: 35px;
58
+ padding-bottom: 10px;
59
+ }
60
+
61
+ header h1 {
62
+ font-weight: bold;
63
+ letter-spacing: -1px;
64
+ font-size: 48px;
65
+ color: #303030;
66
+ line-height: 1.2;
67
+ }
68
+
69
+ header h2 {
70
+ letter-spacing: -1px;
71
+ font-size: 24px;
72
+ color: #aaa;
73
+ font-weight: normal;
74
+ line-height: 1.3;
75
+ }
76
+ #downloads {
77
+ display: none;
78
+ }
79
+ #main_content {
80
+ padding-top: 20px;
81
+ }
82
+
83
+ code, pre {
84
+ font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal;
85
+ color: #222;
86
+ margin-bottom: 30px;
87
+ font-size: 12px;
88
+ }
89
+
90
+ code {
91
+ padding: 0 3px;
92
+ }
93
+
94
+ pre {
95
+ border: solid 1px #ddd;
96
+ padding: 20px;
97
+ overflow: auto;
98
+ }
99
+ pre code {
100
+ padding: 0;
101
+ }
102
+
103
+ ul, ol, dl {
104
+ margin-bottom: 20px;
105
+ }
106
+
107
+
108
+ /* COMMON STYLES */
109
+
110
+ table {
111
+ width: 100%;
112
+ border: 1px solid #ebebeb;
113
+ }
114
+
115
+ th {
116
+ font-weight: 500;
117
+ }
118
+
119
+ td {
120
+ border: 1px solid #ebebeb;
121
+ text-align: center;
122
+ font-weight: 300;
123
+ }
124
+
125
+ form {
126
+ background: #f2f2f2;
127
+ padding: 20px;
128
+
129
+ }
130
+
131
+
132
+ /* GENERAL ELEMENT TYPE STYLES */
133
+
134
+ h1 {
135
+ font-size: 2.8em;
136
+ }
137
+
138
+ h2 {
139
+ font-size: 22px;
140
+ font-weight: bold;
141
+ color: #303030;
142
+ margin-bottom: 8px;
143
+ }
144
+
145
+ h3 {
146
+ color: #d5000d;
147
+ font-size: 18px;
148
+ font-weight: bold;
149
+ margin-bottom: 8px;
150
+ }
151
+
152
+ h4 {
153
+ font-size: 16px;
154
+ color: #303030;
155
+ font-weight: bold;
156
+ }
157
+
158
+ h5 {
159
+ font-size: 1em;
160
+ color: #303030;
161
+ }
162
+
163
+ h6 {
164
+ font-size: .8em;
165
+ color: #303030;
166
+ }
167
+
168
+ p {
169
+ font-weight: 300;
170
+ margin-bottom: 20px;
171
+ }
172
+
173
+ a {
174
+ text-decoration: none;
175
+ }
176
+
177
+ p a {
178
+ font-weight: 400;
179
+ }
180
+
181
+ blockquote {
182
+ font-size: 1.6em;
183
+ border-left: 10px solid #e9e9e9;
184
+ margin-bottom: 20px;
185
+ padding: 0 0 0 30px;
186
+ }
187
+
188
+ ul li {
189
+ list-style: disc inside;
190
+ padding-left: 20px;
191
+ }
192
+
193
+ ol li {
194
+ list-style: decimal inside;
195
+ padding-left: 3px;
196
+ }
197
+
198
+ dl dd {
199
+ font-style: italic;
200
+ font-weight: 100;
201
+ }
202
+
203
+ footer {
204
+ margin-top: 40px;
205
+ padding-top: 20px;
206
+ padding-bottom: 30px;
207
+ font-size: 13px;
208
+ color: #aaa;
209
+ }
210
+
211
+ footer a {
212
+ color: #666;
213
+ }
214
+
215
+ /* MISC */
216
+ .clearfix:after {
217
+ clear: both;
218
+ content: '.';
219
+ display: block;
220
+ visibility: hidden;
221
+ height: 0;
222
+ }
223
+
224
+ .clearfix {display: inline-block;}
225
+ * html .clearfix {height: 1%;}
226
+ .clearfix {display: block;}
@@ -0,0 +1,69 @@
1
+ .highlight { background: #ffffff; }
2
+ .highlight .c { color: #999988; font-style: italic } /* Comment */
3
+ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
4
+ .highlight .k { font-weight: bold } /* Keyword */
5
+ .highlight .o { font-weight: bold } /* Operator */
6
+ .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
7
+ .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
8
+ .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
9
+ .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
10
+ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
11
+ .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
12
+ .highlight .ge { font-style: italic } /* Generic.Emph */
13
+ .highlight .gr { color: #aa0000 } /* Generic.Error */
14
+ .highlight .gh { color: #999999 } /* Generic.Heading */
15
+ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
16
+ .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
17
+ .highlight .go { color: #888888 } /* Generic.Output */
18
+ .highlight .gp { color: #555555 } /* Generic.Prompt */
19
+ .highlight .gs { font-weight: bold } /* Generic.Strong */
20
+ .highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */
21
+ .highlight .gt { color: #aa0000 } /* Generic.Traceback */
22
+ .highlight .kc { font-weight: bold } /* Keyword.Constant */
23
+ .highlight .kd { font-weight: bold } /* Keyword.Declaration */
24
+ .highlight .kn { font-weight: bold } /* Keyword.Namespace */
25
+ .highlight .kp { font-weight: bold } /* Keyword.Pseudo */
26
+ .highlight .kr { font-weight: bold } /* Keyword.Reserved */
27
+ .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
28
+ .highlight .m { color: #009999 } /* Literal.Number */
29
+ .highlight .s { color: #d14 } /* Literal.String */
30
+ .highlight .na { color: #008080 } /* Name.Attribute */
31
+ .highlight .nb { color: #0086B3 } /* Name.Builtin */
32
+ .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
33
+ .highlight .no { color: #008080 } /* Name.Constant */
34
+ .highlight .ni { color: #800080 } /* Name.Entity */
35
+ .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
36
+ .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
37
+ .highlight .nn { color: #555555 } /* Name.Namespace */
38
+ .highlight .nt { color: #000080 } /* Name.Tag */
39
+ .highlight .nv { color: #008080 } /* Name.Variable */
40
+ .highlight .ow { font-weight: bold } /* Operator.Word */
41
+ .highlight .w { color: #bbbbbb } /* Text.Whitespace */
42
+ .highlight .mf { color: #009999 } /* Literal.Number.Float */
43
+ .highlight .mh { color: #009999 } /* Literal.Number.Hex */
44
+ .highlight .mi { color: #009999 } /* Literal.Number.Integer */
45
+ .highlight .mo { color: #009999 } /* Literal.Number.Oct */
46
+ .highlight .sb { color: #d14 } /* Literal.String.Backtick */
47
+ .highlight .sc { color: #d14 } /* Literal.String.Char */
48
+ .highlight .sd { color: #d14 } /* Literal.String.Doc */
49
+ .highlight .s2 { color: #d14 } /* Literal.String.Double */
50
+ .highlight .se { color: #d14 } /* Literal.String.Escape */
51
+ .highlight .sh { color: #d14 } /* Literal.String.Heredoc */
52
+ .highlight .si { color: #d14 } /* Literal.String.Interpol */
53
+ .highlight .sx { color: #d14 } /* Literal.String.Other */
54
+ .highlight .sr { color: #009926 } /* Literal.String.Regex */
55
+ .highlight .s1 { color: #d14 } /* Literal.String.Single */
56
+ .highlight .ss { color: #990073 } /* Literal.String.Symbol */
57
+ .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
58
+ .highlight .vc { color: #008080 } /* Name.Variable.Class */
59
+ .highlight .vg { color: #008080 } /* Name.Variable.Global */
60
+ .highlight .vi { color: #008080 } /* Name.Variable.Instance */
61
+ .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
62
+
63
+ .type-csharp .highlight .k { color: #0000FF }
64
+ .type-csharp .highlight .kt { color: #0000FF }
65
+ .type-csharp .highlight .nf { color: #000000; font-weight: normal }
66
+ .type-csharp .highlight .nc { color: #2B91AF }
67
+ .type-csharp .highlight .nn { color: #000000 }
68
+ .type-csharp .highlight .s { color: #A31515 }
69
+ .type-csharp .highlight .sc { color: #A31515 }
@@ -0,0 +1,479 @@
1
+ /* http://meyerweb.com/eric/tools/css/reset/
2
+ v2.0 | 20110126
3
+ License: none (public domain)
4
+ */
5
+ html, body, div, span, applet, object, iframe,
6
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
7
+ a, abbr, acronym, address, big, cite, code,
8
+ del, dfn, em, img, ins, kbd, q, s, samp,
9
+ small, strike, strong, sub, sup, tt, var,
10
+ b, u, i, center,
11
+ dl, dt, dd, ol, ul, li,
12
+ fieldset, form, label, legend,
13
+ table, caption, tbody, tfoot, thead, tr, th, td,
14
+ article, aside, canvas, details, embed,
15
+ figure, figcaption, footer, header, hgroup,
16
+ menu, nav, output, ruby, section, summary,
17
+ time, mark, audio, video {
18
+ margin: 0;
19
+ padding: 0;
20
+ border: 0;
21
+ font-size: 100%;
22
+ font: inherit;
23
+ vertical-align: baseline;
24
+ }
25
+ /* HTML5 display-role reset for older browsers */
26
+ article, aside, details, figcaption, figure,
27
+ footer, header, hgroup, menu, nav, section {
28
+ display: block;
29
+ }
30
+ body {
31
+ line-height: 1;
32
+ }
33
+ ol, ul {
34
+ list-style: none;
35
+ }
36
+ blockquote, q {
37
+ quotes: none;
38
+ }
39
+ blockquote:before, blockquote:after,
40
+ q:before, q:after {
41
+ content: '';
42
+ content: none;
43
+ }
44
+ table {
45
+ border-collapse: collapse;
46
+ border-spacing: 0;
47
+ }
48
+
49
+ /* LAYOUT STYLES */
50
+ body {
51
+ font-size: 15px;
52
+ line-height: 1.5;
53
+ background: #fafafa url(../images/body-bg.jpg) 0 0 repeat;
54
+ font-family: 'Helvetica Neue', Helvetica, Arial, serif;
55
+ font-weight: 400;
56
+ color: #666;
57
+ }
58
+
59
+ a {
60
+ color: #2879d0;
61
+ }
62
+ a:hover {
63
+ color: #2268b2;
64
+ }
65
+
66
+ header {
67
+ padding-top: 40px;
68
+ padding-bottom: 40px;
69
+ font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif;
70
+ background: #2e7bcf url(../images/header-bg.jpg) 0 0 repeat-x;
71
+ border-bottom: solid 1px #275da1;
72
+ }
73
+
74
+ header h1 {
75
+ letter-spacing: -1px;
76
+ font-size: 72px;
77
+ color: #fff;
78
+ line-height: 1;
79
+ margin-bottom: 0.2em;
80
+ width: 540px;
81
+ }
82
+
83
+ header h2 {
84
+ font-size: 26px;
85
+ color: #9ddcff;
86
+ font-weight: normal;
87
+ line-height: 1.3;
88
+ width: 540px;
89
+ letter-spacing: 0;
90
+ }
91
+
92
+ .inner {
93
+ position: relative;
94
+ width: 940px;
95
+ margin: 0 auto;
96
+ }
97
+
98
+ #content-wrapper {
99
+ border-top: solid 1px #fff;
100
+ padding-top: 30px;
101
+ }
102
+
103
+ #main-content {
104
+ width: 690px;
105
+ float: left;
106
+ }
107
+
108
+ #main-content img {
109
+ max-width: 100%;
110
+ }
111
+
112
+ aside#sidebar {
113
+ width: 200px;
114
+ padding-left: 20px;
115
+ min-height: 504px;
116
+ float: right;
117
+ background: transparent url(../images/sidebar-bg.jpg) 0 0 no-repeat;
118
+ font-size: 12px;
119
+ line-height: 1.3;
120
+ }
121
+
122
+ aside#sidebar p.repo-owner,
123
+ aside#sidebar p.repo-owner a {
124
+ font-weight: bold;
125
+ }
126
+
127
+ #downloads {
128
+ margin-bottom: 40px;
129
+ }
130
+
131
+ a.button {
132
+ width: 134px;
133
+ height: 58px;
134
+ line-height: 1.2;
135
+ font-size: 23px;
136
+ color: #fff;
137
+ padding-left: 68px;
138
+ padding-top: 22px;
139
+ font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif;
140
+ }
141
+ a.button small {
142
+ display: block;
143
+ font-size: 11px;
144
+ }
145
+ header a.button {
146
+ position: absolute;
147
+ right: 0;
148
+ top: 0;
149
+ background: transparent url(../images/github-button.png) 0 0 no-repeat;
150
+ }
151
+ aside a.button {
152
+ width: 138px;
153
+ padding-left: 64px;
154
+ display: block;
155
+ background: transparent url(../images/download-button.png) 0 0 no-repeat;
156
+ margin-bottom: 20px;
157
+ font-size: 21px;
158
+ }
159
+
160
+ code, pre {
161
+ font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
162
+ color: #222;
163
+ margin-bottom: 30px;
164
+ font-size: 13px;
165
+ }
166
+
167
+ code {
168
+ background-color: #f2f8fc;
169
+ border: solid 1px #dbe7f3;
170
+ padding: 0 3px;
171
+ }
172
+
173
+ pre {
174
+ padding: 20px;
175
+ background: #fff;
176
+ text-shadow: none;
177
+ overflow: auto;
178
+ border: solid 1px #f2f2f2;
179
+ }
180
+ pre code {
181
+ color: #2879d0;
182
+ background-color: #fff;
183
+ border: none;
184
+ padding: 0;
185
+ }
186
+
187
+ ul, ol, dl {
188
+ margin-bottom: 20px;
189
+ }
190
+
191
+
192
+ /* COMMON STYLES */
193
+
194
+ hr {
195
+ height: 1px;
196
+ line-height: 1px;
197
+ margin-top: 1em;
198
+ padding-bottom: 1em;
199
+ border: none;
200
+ background: transparent url('../images/hr.png') 0 0 no-repeat;
201
+ }
202
+
203
+ table {
204
+ width: 100%;
205
+ border: 1px solid #ebebeb;
206
+ }
207
+
208
+ th {
209
+ font-weight: 500;
210
+ }
211
+
212
+ td {
213
+ border: 1px solid #ebebeb;
214
+ text-align: center;
215
+ font-weight: 300;
216
+ }
217
+
218
+ form {
219
+ background: #f2f2f2;
220
+ padding: 20px;
221
+
222
+ }
223
+
224
+
225
+ /* GENERAL ELEMENT TYPE STYLES */
226
+
227
+ #main-content h1 {
228
+ font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif;
229
+ font-size: 2.8em;
230
+ letter-spacing: -1px;
231
+ color: #474747;
232
+ }
233
+
234
+ #main-content h1:before {
235
+ content: "/";
236
+ color: #9ddcff;
237
+ padding-right: 0.3em;
238
+ margin-left: -0.9em;
239
+ }
240
+
241
+ #main-content h2 {
242
+ font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif;
243
+ font-size: 22px;
244
+ font-weight: bold;
245
+ margin-bottom: 8px;
246
+ color: #474747;
247
+ }
248
+ #main-content h2:before {
249
+ content: "//";
250
+ color: #9ddcff;
251
+ padding-right: 0.3em;
252
+ margin-left: -1.5em;
253
+ }
254
+
255
+ #main-content h3 {
256
+ font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif;
257
+ font-size: 18px;
258
+ font-weight: bold;
259
+ margin-top: 24px;
260
+ margin-bottom: 8px;
261
+ color: #474747;
262
+ }
263
+
264
+ #main-content h3:before {
265
+ content: "///";
266
+ color: #9ddcff;
267
+ padding-right: 0.3em;
268
+ margin-left: -2em;
269
+ }
270
+
271
+ #main-content h4 {
272
+ font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif;
273
+ font-size: 15px;
274
+ font-weight: bold;
275
+ color: #474747;
276
+ }
277
+
278
+ h4:before {
279
+ content: "////";
280
+ color: #9ddcff;
281
+ padding-right: 0.3em;
282
+ margin-left: -2.8em;
283
+ }
284
+
285
+ #main-content h5 {
286
+ font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif;
287
+ font-size: 14px;
288
+ color: #474747;
289
+ }
290
+ h5:before {
291
+ content: "/////";
292
+ color: #9ddcff;
293
+ padding-right: 0.3em;
294
+ margin-left: -3.2em;
295
+ }
296
+
297
+ #main-content h6 {
298
+ font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif;
299
+ font-size: .8em;
300
+ color: #474747;
301
+ }
302
+ h6:before {
303
+ content: "//////";
304
+ color: #9ddcff;
305
+ padding-right: 0.3em;
306
+ margin-left: -3.7em;
307
+ }
308
+
309
+ p {
310
+ margin-bottom: 20px;
311
+ }
312
+
313
+ a {
314
+ text-decoration: none;
315
+ }
316
+
317
+ p a {
318
+ font-weight: 400;
319
+ }
320
+
321
+ blockquote {
322
+ font-size: 1.6em;
323
+ border-left: 10px solid #e9e9e9;
324
+ margin-bottom: 20px;
325
+ padding: 0 0 0 30px;
326
+ }
327
+
328
+ ul {
329
+ list-style: disc inside;
330
+ padding-left: 20px;
331
+ }
332
+
333
+ ol {
334
+ list-style: decimal inside;
335
+ padding-left: 3px;
336
+ }
337
+
338
+ dl dd {
339
+ font-style: italic;
340
+ font-weight: 100;
341
+ }
342
+
343
+ footer {
344
+ background: transparent url('../images/hr.png') 0 0 no-repeat;
345
+ margin-top: 40px;
346
+ padding-top: 20px;
347
+ padding-bottom: 30px;
348
+ font-size: 13px;
349
+ color: #aaa;
350
+ }
351
+
352
+ footer a {
353
+ color: #666;
354
+ }
355
+ footer a:hover {
356
+ color: #444;
357
+ }
358
+
359
+ /* MISC */
360
+ .clearfix:after {
361
+ clear: both;
362
+ content: '.';
363
+ display: block;
364
+ visibility: hidden;
365
+ height: 0;
366
+ }
367
+
368
+ .clearfix {display: inline-block;}
369
+ * html .clearfix {height: 1%;}
370
+ .clearfix {display: block;}
371
+
372
+ /* #Media Queries
373
+ ================================================== */
374
+
375
+ /* Smaller than standard 960 (devices and browsers) */
376
+ @media only screen and (max-width: 959px) {}
377
+
378
+ /* Tablet Portrait size to standard 960 (devices and browsers) */
379
+ @media only screen and (min-width: 768px) and (max-width: 959px) {
380
+ .inner {
381
+ width: 740px;
382
+ }
383
+ header h1, header h2 {
384
+ width: 340px;
385
+ }
386
+ header h1 {
387
+ font-size: 60px;
388
+ }
389
+ header h2 {
390
+ font-size: 30px;
391
+ }
392
+ #main-content {
393
+ width: 490px;
394
+ }
395
+ #main-content h1:before,
396
+ #main-content h2:before,
397
+ #main-content h3:before,
398
+ #main-content h4:before,
399
+ #main-content h5:before,
400
+ #main-content h6:before {
401
+ content: none;
402
+ padding-right: 0;
403
+ margin-left: 0;
404
+ }
405
+ }
406
+
407
+ /* All Mobile Sizes (devices and browser) */
408
+ @media only screen and (max-width: 767px) {
409
+ .inner {
410
+ width: 93%;
411
+ }
412
+ header {
413
+ padding: 20px 0;
414
+ }
415
+ header .inner {
416
+ position: relative;
417
+ }
418
+ header h1, header h2 {
419
+ width: 100%;
420
+ }
421
+ header h1 {
422
+ font-size: 48px;
423
+ }
424
+ header h2 {
425
+ font-size: 24px;
426
+ }
427
+ header a.button {
428
+ background-image: none;
429
+ width: auto;
430
+ height: auto;
431
+ display: inline-block;
432
+ margin-top: 15px;
433
+ padding: 5px 10px;
434
+ position: relative;
435
+ text-align: center;
436
+ font-size: 13px;
437
+ line-height: 1;
438
+ background-color: #9ddcff;
439
+ color: #2879d0;
440
+ -moz-border-radius: 5px;
441
+ -webkit-border-radius: 5px;
442
+ border-radius: 5px;
443
+ }
444
+ header a.button small {
445
+ font-size: 13px;
446
+ display: inline;
447
+ }
448
+ #main-content,
449
+ aside#sidebar {
450
+ float: none;
451
+ width: 100% ! important;
452
+ }
453
+ aside#sidebar {
454
+ background-image: none;
455
+ margin-top: 20px;
456
+ border-top: solid 1px #ddd;
457
+ padding: 20px 0;
458
+ min-height: 0;
459
+ }
460
+ aside#sidebar a.button {
461
+ display: none;
462
+ }
463
+ #main-content h1:before,
464
+ #main-content h2:before,
465
+ #main-content h3:before,
466
+ #main-content h4:before,
467
+ #main-content h5:before,
468
+ #main-content h6:before {
469
+ content: none;
470
+ padding-right: 0;
471
+ margin-left: 0;
472
+ }
473
+ }
474
+
475
+ /* Mobile Landscape Size to Tablet Portrait (devices and browsers) */
476
+ @media only screen and (min-width: 480px) and (max-width: 767px) {}
477
+
478
+ /* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */
479
+ @media only screen and (max-width: 479px) {}