HTML Logo by World Wide Web Consortium ( Click to learn more about our commitment to accessibility and standards.

Moving forward with Composr

ocPortal has been relaunched as Composr CMS, which is now in beta. ocPortal 9 will be superseded by Composr 10.

Head over to for our new site, and to our migration roadmap. Existing ocPortal member accounts have been mirrored.

ocPortal Tutorial: Filtering using ocSelect syntax

Written by Chris Graham, ocProducts
ocPortal contains a filtering system for selecting content based upon defined filters. ocSelect is the language for defining filter strings, and is an advanced feature of ocPortal. It is not to be confused with ocFilter, which is the language for determining what categories to return results from.

An introductory example

An ocSelect filter string consists of comparisons, separated by commas. Here is an example:


This defines two comparisons. Both must hold true for any result returned (i.e. they are ANDd).

In this example, the first is an '=' comparison, and the second is an '>' comparison. Anyone who knows very basic maths will understand what these mean.

'something' and 'somethingelse' would be database field names for the main database table of whatever content type is being filtered.

The full language

Security note

For security reasons, some fields are not available to ocSelect, such as password fields
The field names must match field names in the content type's main database table, or one of the following special values:
  • compound_rating (the rating)
  • meta_keywords (the SEO keywords / tagging)
  • meta_description (the SEO description)
  • field_<id> (custom fields, where <id> is the field ID of the custom field)
You are allowed to specify that comparisons may work on multiple fields, by separating field names with pipe (|) symbols. This is particular useful for a search filter, to make the typed string look across multiple fields.


GET/POST parameters are the technical name for how parameters are passed to web pages. The &something=value stuff you see in URLs are GET parameters, and POST parameters are what forms pass around behind-the-scenes.
We support the following comparison types:
  • < (Less than)
  • > (Greater than)
  • <= (Less than or equal to)
  • >= (Greater than or equal to)
  • = (Equal to, where blank means skip)
  • == (Equal to, where blank means only a blank value will be matched)
  • ~= (Contains substring)
  • ~ (Seems to match, according to database full-text search matching)

The comparison value can either by given directly, like in the introductory example, or it can be written like <name>, which will tell it to look within a GET/POST parameter called filter_<name>. This is the mechanism by which you hook up forms to the filter strings.

You can also specify that comparison types are read via GET/POST parameter in the same way, if you want users to define how each field should match.

Where the filters can be used

There is an ocSelect-based parameter for the following blocks:
  • main_multi_content
  • main_gallery_embed
  • main_cc_embed

As well as active support within the following modules:
  • catalogues
  • downloads
  • galleries
  • members
  • news
(the filter used will be read from any GET/POST active_filter parameter that is set)

As explained above, ocSelect works by reading GET/POST parameters and matching them using the rules specified in the defined ocSelect filter string. In the case of the filtering for the modules, the filter string is also supplied as a GET/POST parameter.

Generating filters

Thumbnail: Inspecting the block's HTML to get the auto-generated ocSelect filter string, which we'll use as a starting point

Inspecting the block's HTML to get the auto-generated ocSelect filter string, which we'll use as a starting point

Thumbnail: An automatic news filter form

An automatic news filter form

The concept of writing ocSelect filter strings, and matching forms, can be a bit daunting. This is why the main_content_filtering block exists. It will automatically construct filters and forms for content types.

You don't actually need to use this block in production at all. It is a good way to build up a default form, which you can then get HTML from as a starting point.

There are two steps in getting your HTML ready:
  1. Show the block for your content type, with no parameters
  2. Grab the auto-generated ocSelect filter string and customise it, then show the block using your customised filter

Once you have built a default form for a content type, inspect the HTML to get the auto-generated active_filter value (see the image above).

In our case the auto-generated ocSelect filter string was:



We will take that and modify it. In this case I think the following filter is much better:



Thumbnail: A refined filter form

A refined filter form

We then feed into the block's "param" setting to get our refined filter form (see the image below).

Putting the filter form into the site

If we are happy with how our refined filter form looks, we can continue with the main_content_filtering block.
Otherwise, we can grab the HTML that the block output and tune it. The only thing that ocPortal needs is the GET/POST fields to match what the ocSelect filter string wants, otherwise you can use whatever HTML you want.

We'll assume we'll continue to use the main_content_filtering block for the following continuations of our news filtering example.

Putting into a panel

If you want to place a filter on the news page, with it shown in a panel only on the news page, you'd put something like this into your panel's Comcode:


{+START,IF,{$MATCH_KEY_MATCH,site:news}}[block="author~=<author>,date_and_time><date_and_time>,news|news_article|title|meta_keywords|meta_description~=<news>,submitter=<submitter>,compound_rating>=<compound_rating>" content_type="news" labels="date_and_time=Newer than,news=Containing,submitter=Submitted by,compound_rating=Minimum rating" types="date_and_time=days"]main_content_filtering[/block]{+END}

Putting into a news template

If you wanted it on the news archive screen, you'd edit the NEWS_ARCHIVE_SCREEN template and add:


{$BLOCK,block=main_content_filtering,param=author~=<author>\,date_and_time><date_and_time>\,news|news_article|title|meta_keywords|meta_description~=<news>\,submitter=<submitter>\,compound_rating>=<compound_rating>,content_type=news,labels=date_and_time=Newer than\,news=Containing\,submitter=Submitted by\,compound_rating=Minimum rating,types=date_and_time=days}


ocPortal's syntax for filtering returned content

See also