HTML Logo by World Wide Web Consortium (www.w3.org). 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 compo.sr for our new site, and to our migration roadmap. Existing ocPortal member accounts have been mirrored.


Visual customisation

Use this space to share information relating to visual customisation


In addition to the community-editable documentation above, we have the following official tutorials:

Posted
Submitted by Jean
Basic CSS Map of a typical ocPortal Front page

Cascading Style Sheets (CSS) control most visual aspects of your website
Anyone can easily find this information with the Firebug add-on to the Firefox browser, as its CSS tabs tell you everything you need to know about the styles in your web pages, and if you don't like what it's telling you, you can even make "virtual" changes and see them take effect instantly. Firebug can be your eyes as it will measure and illustrate all the offsets, margins, borders, padding, and sizes for you.

However, I wanted to have a visual representation of the space allocated by the most important CSS Classes on a typical ocPortal front page and be able to refer to it at anytime without having to "fire up":cyborg:Firebug ; some kind of a "CSS Map".

So here is my compilation:

There is a whole lot going on the top and bottom tiers to make it difficult to capture the elements in an uncluttered visual, so I've limited the discovery to the most important classes. Each class can have several elements of style with multiple properties and values. It is also important to note that they are layered (cascading) on the page; the last ones could blot out some of the real-estate of the top ones like so:

  1. .re_body
  2. .global_top
  3. .global_zones
  4. .menu_type__zone
  5. .logo
  6. .global_banner
  7. .global_side "panel_left"
  8. .global_side "panel_right"
  9. .global_middle
  10. .float_surrounder
  11. .global_copyright
  12. .global_minilinks
I will address these Properties: background, border, display, position, height, width, font, list-style, margin, padding, bottom, left, right, top, color, text-align, text-decoration, text-indent in subsequent mapping exercises.

I'm hoping that this first attempt might be useful to gain a better understanding of ocPortal's basic webpage.

Jean
 
Posted
Submitted by Chris Graham
A basic theme modification tutorial by Jean: (Updated to v9)
ocPortal.com - View topic: Basic Theme Modifications - Part 1
ocPortal.com - View topic: Basic Theme Modifications - Part 2
ocPortal.com - View topic: Basic Theme Modifications - Part 3
 
Posted
Submitted by Chris Graham
A themeing tutorial by Chris Graham:
ocPortal.com - View topic: Example theme: Spring Bloom
 
Posted
Submitted by Chris Graham
How to make all the standard-boxes curved.

 
Posted
Submitted by Chris Graham
To make every box curved…

Add this to global.css:

Code


.standardbox_wrap_panel, .standardbox_wrap_classic, .lightborder, .medborder {
  border-radius: 10px;
  margin: 0.5em 0;
}

.standardbox_t_panel, .standardbox_classic, ul.ocf_profile_friends li, .ocf_profile_column {
  border-radius: 10px;
}

.standardbox_title_panel, .standardbox_title_classic, .standardbox_title_med, .standardbox_title_light {
  border-top-left-radius: 9px;
  border-top-right-radius: 9px;
}

.menu_type__dropdown ul.nlevel {
  border-radius: 10px;
}

.menu_type__dropdown ul.nlevel li:first-child {
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
}

.menu_type__dropdown ul.nlevel li:last-child {
  border-bottom-left-radius: 10px;
  border-bottom-right-radius: 10px;
}

.boxes_together + .boxes_together {
  border-top: 1px solid #7C4D09;
}

.dottedborder {
  border-radius: 10px;
}

.index_page_fancier_page_entries {
  margin-left: 0;
}


+ override STANDARDBOX_curved.tpl to simply be…

Code

{+START,INCLUDE,STANDARDBOX_classic}{+END}
 
Posted
Submitted by Chris Graham
Here's a little template change to make sound play on each click:

Attachment
» Download: JAVASCRIPT_CUSTOM_GLOBALS.tpl (614 Bytes, 468 downloads so far)


(liable to drive your users crazy though! ;))
 
Posted
Submitted by Chris Graham
You may notice only panel boxes have the expand/contract feature (and only then if you have it enabled in the configuration). This is by design. The expand/contract is quite a stylistic imposition so we only have it on for panels (as often people put a lot on panels but space there is limited). This is all controlled in templates, so ultimately you can do edits to meet your needs. The defaults are just there for the average user.

Edit the BLOCK_SIDE_RSStemplate and change

Code

{+START,BOX,{TITLE},,{$?,{$GET,in_panel},panel,classic},tray_open}

to…

Code

{+START,BOX,{TITLE},,{$?,{$GET,in_panel},panel,classic},tray_open,,,1}

The need for this change is that by default only panel boxes show the expand/contract. The extra 1 I put in there changes that default and makes it use the tray_open as the initial state.

Alternatively

If you want most non-panel boxes to support expand/contract, edit the STANDARDBOX_classictemplate and change…



Code

{+START,IF,{EXPAND}}{+START,IF,{$JS_ON}}{+START,IF_IN_ARRAY,tray_open,OPTIONS}<a class="standardbox_tray hide_button" href="#" onclick="SetCookie('tray_{TITLE|}',(get_elements_by_class_name(this.parentNode.parentNode,'hide_tag')[0].style.display=='none')?'open':'closed'); hideTag(this.parentNode.parentNode); return false;"><img alt="{!CONTRACT}: {$STRIP_TAGS,{TITLE}}" title="{!CONTRACT}" src="{$IMG*,contract}" /></a>{+END}{+START,IF_IN_ARRAY,tray_closed,OPTIONS}<a class="standardbox_tray hide_button" href="#" onclick="SetCookie('tray_{TITLE|}',(get_elements_by_class_name(this.parentNode.parentNode,'hide_tag')[0].style.display=='none')?'open':'closed'); hideTag(this.parentNode.parentNode); return false;"><img alt="{!EXPAND}: {$STRIP_TAGS,{TITLE}}" title="{!EXPAND}" src="{$IMG*,expand}" /></a>{+END}{+END}{+END}
to

Code

 {+START,IF,{$JS_ON}}{+START,IF_IN_ARRAY,tray_open,OPTIONS}<a class="standardbox_tray hide_button" href="#" onclick="SetCookie('tray_{TITLE|}',(get_elements_by_class_name(this.parentNode.parentNode,'hide_tag')[0].style.display=='none')?'open':'closed'); hideTag(this.parentNode.parentNode); return false;"><img alt="{!CONTRACT}: {$STRIP_TAGS,{TITLE}}" title="{!CONTRACT}" src="{$IMG*,contract}" /></a>{+END}{+START,IF_IN_ARRAY,tray_closed,OPTIONS}<a class="standardbox_tray hide_button" href="#" onclick="SetCookie('tray_{TITLE|}',(get_elements_by_class_name(this.parentNode.parentNode,'hide_tag')[0].style.display=='none')?'open':'closed'); hideTag(this.parentNode.parentNode); return false;"><img alt="{!EXPAND}: {$STRIP_TAGS,{TITLE}}" title="{!EXPAND}" src="{$IMG*,expand}" /></a>{+END}{+END}

(which removes the check for expansion, effectively making the classic boxes work the same as the panel boxes)
 
Posted
Submitted by Duck
Add Alternating Row Colours To Your Forums:

To add them to your Forum index:

Edit ocf_forum_in_grouping.tpl and save into templates_custom folder.

Make the following changes (in red):


Code

<tr class="{$CYCLE,forum_rows,row_even,row_odd}">
    {+START,IF,{$NOT,{$MOBILE}}}
        <td class="ocf_forum_new_post_indicator ocf_column1">
            <img alt="{LANG_NEW_POST_OR_NOT*}" src="{$IMG*,ocf_general/{NEW_POST_OR_NOT*}}" />
        </td>
    {+END}
    <td class="ocf_forum_in_category_forum ocf_column2">
        <a class="field_name" href="{FORUM_URL*}">{+START,FRACTIONAL_EDITABLE,{FORUM_NAME},name,_SEARCH:admin_ocf_forums:type=__ed:id={ID}}{FORUM_NAME*}{+END}</a>

        {+START,IF_NON_EMPTY,{EDIT_URL}}
            <a class="horiz_field_sep associated_link suggested_link" rel="edit" href="{EDIT_URL*}" title="{!EDIT}: {FORUM_NAME*}">{!EDIT}</a>
        {+END}
        {+START,IF_NON_EMPTY,{FORUM_RULES_URL}}
            <a class="horiz_field_sep associated_link suggested_link" target="_blank" onclick="window.faux_open(maintain_theme_in_link('{FORUM_RULES_URL*}'),'','width=600,height=500,status=yes,resizable=yes,scrollbars=yes'); return false;" href="{FORUM_RULES_URL*}" title="{!FORUM_RULES}: {FORUM_NAME*} {!LINK_NEW_WINDOW}">{!FORUM_RULES}</a>
        {+END}
        {+START,IF_NON_EMPTY,{INTRO_QUESTION_URL}}
            <a class="horiz_field_sep associated_link suggested_link" target="_blank" onclick="window.faux_open(maintain_theme_in_link('{INTRO_QUESTION_URL*}'),'','width=600,height=500,status=yes,resizable=yes,scrollbars=yes'); return false;" href="{INTRO_QUESTION_URL*}" title="{!INTRO_QUESTION}: {FORUM_NAME*} {!LINK_NEW_WINDOW}">{!INTRO_QUESTION}</a>
        {+END}

        {+START,IF_NON_EMPTY,{DESCRIPTION}}
            <div class="ocf_forum_description">
                {DESCRIPTION}
            </div>
        {+END}

        {+START,IF_NON_EMPTY,{SUBFORUMS}}
            <div class="ocf_forum_subforums">
                <p><span class="field_name">{!SUBFORUMS}:</span> {SUBFORUMS}</p>
            </div>
        {+END}

        {+START,IF,{$MOBILE}}
            <ul class="horizontal_meta_details associated_details" role="contentinfo">
                <li><span class="field_name">{!COUNT_TOPICS}:</span> {$PREG_REPLACE,([^<>/\s\w]),1 ,{NUM_TOPICS*}}</li>
                <li><span class="field_name">{!COUNT_POSTS}:</span> {$PREG_REPLACE,([^<>/\s\w]),1 ,{NUM_POSTS*}}</li>
            </ul>
        {+END}
    </td>
    {+START,IF,{$NOT,{$MOBILE}}}
        <td class="ocf_forum_num_topics ocf_column4">
            {$PREG_REPLACE,([^<>/\s\w]),1 ,{NUM_TOPICS*}}
        </td>
        <td class="ocf_forum_num_posts ocf_column5">
            {$PREG_REPLACE,([^<>/\s\w]),1 ,{NUM_POSTS*}}
        </td>
    {+END}
    <td class="ocf_forum_latest ocf_column6">
        {LATEST}
    </td>
</tr>


Add the CSS definitions to your global.css file and save to css_custom folder


eg:

.row_even td{
background-color: #F00;
}

To add it to the Topic Listings page edit and save into templates_custom folder the ocf_forum_topic_row.tpl

*Also note that the $CYCLE can take more arguments so instead of row_odd and row_even you could have row_1, row_2, row_3 in case you wanted to get even fancier.
 
Posted
Submitted by Chris Graham
Advanced panel layout changes:
2012-08-25_1947 - ocProducts's library
2012-08-25_1953 - ocProducts's library
2012-08-25_1958 - ocProducts's library
http://www.screencast.com/t/1s4WGLs5k3k3
http://www.screencast.com/t/AIXTk850AUJ
 
Posted
Submitted by Chris Graham

Using Tempcode within Comcode parameters

You may wish to use some Tempcode, e.g. the symbol to insert the current user's username, into a parameter of a Comcode tag. This is not supported, mainly for architectural and performance reasons.

However, there is a very easy workaround, just wrap it all within {$COMCODE,...}. For example:

Code

{$COMCODE,[block="22" ocselect="Student ID={$USERNAME}" sorting="0" max="30" start="0" cache="0"]main_cc_embed[/block]}

This essentially pipes it all through the Tempcode processor, which probably seems very counter-intuitive. As 'COMCODE' is a Tempcode symbol, it means everything sent through it would be treated as if it was written in Tempcode - yet the nature of the 'COMCODE' Tempcode symbol also means Comcode will be parsed in there.
i.e. it activates different processing rules by pushing things directly through the main Tempcode parser.
 
Posted
Submitted by Chris Graham
To edit e-mail subject line's compositions…

Go to Admin Zone > Style > Themes. Choose "Edit Templates" for the default theme. Ignore the warning. Select MAIL_SUBJECT.tpl and click Choose.

You will see the default template is:

Code

{+START,IF,{$NOT,{$IN_STR,{SUBJECT_LINE},{$SITE_NAME}}}}{$SITE_NAME}: {+END}{SUBJECT_LINE}
The complex bit at the start prepends the site name, if the mail-specific subject line itself does not contain the site name. This means the site name usually is included.
If you never want the site name, you can strip it right down to:

Code

{SUBJECT_LINE}
and Save.

Visual demonstration:
2013-06-23_1409 - ocProducts's library
 
Posted
Submitted by Chris Graham
Simplifying the main_image_fader block…

ocPortal v8 and earlier had a simple image fader block, but v9 changed it to a more complex high impact layout piece.

To have it back as the simpler image fader, change the BLOCK_MAIN_IMAGE_FADER template to:

Code

{$SET,RAND,{$RAND}}

<div class="float_surrounder">
   <div class="img_thumb_wrap">
      <a href="{GALLERY_URL*}"><img class="img_thumb" id="image_fader_{$GET,RAND}" src="{FIRST_URL*}" alt="" /></a>
   </div>

   <div class="gallery_tease_pic_teaser" id="image_fader_scrolling_text_{$GET,RAND}">
   </div>
</div>

<noscript>
   {+START,LOOP,HTML}
      {_loop_var}
   {+END}
</noscript>

<script type="text/javascript">// <![CDATA[
   add_event_listener_abstract(window,'load',function () {
      var fp_animation=document.getElementById('image_fader_{$GET,RAND}');
      var fp_animation_fader=document.createElement('img');
      var tease_scrolling_text=document.getElementById('image_fader_scrolling_text_{$GET,RAND}');
      fp_animation_fader.className='img_thumb';
      fp_animation.parentNode.insertBefore(fp_animation_fader,fp_animation);
      fp_animation.parentNode.style.position='relative';
      fp_animation.parentNode.style.display='block';
      fp_animation_fader.style.position='absolute';
      fp_animation_fader.src='{$IMG;,blank}';

      {+START,LOOP,HTML}
         var html{_loop_key%}='{_loop_var;^}';
         {+START,IF,{$EQ,{_loop_key},0}}
            if (tease_scrolling_text) set_inner_html(tease_scrolling_text,html{_loop_key%});
         {+END}
      {+END}
      {+START,LOOP,IMAGES}
         var url{_loop_key%}='{_loop_var;}';
         new Image().src=url{_loop_key%}; // precache
         window.setTimeout(function()
         {
            var func{_loop_key%}=function()
            {
               fp_animation_fader.src=fp_animation.src;
               set_opacity(fp_animation_fader,1.0);
               fade_transition(fp_animation_fader,0,50,-3);
               set_opacity(fp_animation,0.0);
               fade_transition(fp_animation,100,50,3);
               fp_animation.src=url{_loop_key%};
               window.setTimeout(function() {
                  fp_animation_fader.style.left=((find_width(fp_animation_fader.parentNode)-find_width(fp_animation_fader))/2)+'px';
                  fp_animation_fader.style.top=((find_height(fp_animation_fader.parentNode)-find_height(fp_animation_fader))/2)+'px';
               },0);
               if (tease_scrolling_text)
               {
                  set_inner_html(tease_scrolling_text,html{_loop_key%});
               }
            };
            if ({_loop_key%}!=0) func{_loop_key%}();
            window.setInterval(func{_loop_key%},{MILL%}*{IMAGES});
         },{_loop_key%}*{MILL%});
      {+END}
   } );
//]]></script>
 
Posted
Submitted by Chris Graham
Putting a counter on member profiles:

Code (diff)

diff --git a/themes/default/css/counting_blocks.css b/themes/default/css/counting_blocks.css
index ecec32f..35e3e7c 100644
--- a/themes/default/css/counting_blocks.css
+++ b/themes/default/css/counting_blocks.css
@@ -5,10 +5,17 @@
 
 .hit_counter {
        font-family: 'Courier New', 'Courier', monospace;
-       font-size: 1.5em;
+       font-size: 1.2em;
 }
 
 .hit_counter, .hit_counter div {
        display: inline-block;
 }
 
+.hit_counter>div {
+       margin: 0 0 0.2em 0;
+}
+
+.hit_counter .box_inner {
+       margin: 0.4em 0.4em 0.25em 0.4em;
+}
diff --git a/themes/default/templates/OCF_MEMBER_PROFILE_ABOUT.tpl b/themes/default/templates/OCF_MEMBER_PROFILE_ABOUT.tpl
index 58e114f..dcd4504 100755
--- a/themes/default/templates/OCF_MEMBER_PROFILE_ABOUT.tpl
+++ b/themes/default/templates/OCF_MEMBER_PROFILE_ABOUT.tpl
@@ -173,6 +173,11 @@
 
                                        <tbody>
+                                               <tr>
+                                                       <th class="de_th">{!_VIEWS}:</th>
+                                                       <td>{$BLOCK,block=main_count,param=member_{MEMBER_ID}}<br /><span class="associated_details">(since 21st July 2013)</span></td>
+                                               </tr>
+
                                                <tr>
                                                        <th class="de_th">{!ONLINE_NOW}:</th>
                                                        <td>{ONLINE_NOW*} <span class="associated_details">({$DATE_AND_TIME*,1,0,0,{LAST_VISIT_TIME_RAW}})</span></td>
                                                </tr>
diff --git a/themes/default/templates/OCF_MEMBER_PROFILE_SCREEN.tpl b/themes/default/templates/OCF_MEMBER_PROFILE_SCREEN.tpl
index b09d875..be45c98 100644
--- a/themes/default/templates/OCF_MEMBER_PROFILE_SCREEN.tpl
+++ b/themes/default/templates/OCF_MEMBER_PROFILE_SCREEN.tpl
@@ -1,3 +1,5 @@
+{$REQUIRE_CSS,counting_blocks}
+
 {$SET,name_set_elsewhere,1}
 
 <div class="vcard" itemscope="itemscope" itemtype="http://schema.org/ProfilePage">
 
 
Posted
Submitted by Chris Graham
Discussion about how the ocPortal helper panel works:
View topic: Understanding Panels in templates. - ocPortal.com
 
Posted
Submitted by Chris Graham
Blog post on mobile viewports:
Understanding viewports on mobile devices - ocPortal.com
 
Posted
Submitted by Chris Graham
To allow members to rate each other, but optionally:

Add this to the OCF_MEMBER_PROFILE_ABOUT template:

Code

      {+START,IF,{$CPF_VALUE,Let users rate me,{MEMBER_ID}}}
         {$BLOCK,block=main_rating,page=members,param={MEMBER_ID}}
      {+END}

And set up the custom profile field:
 
Posted
Submitted by Chris Graham
If you are adding an external Javascript library to ocPortal, there are two ways…

Simple

You could just add normal HTML into the HTML_HEAD.tpl template.

If you are storing it locally, by convention the file would go in uploads/website_specific and you'd add code like this…

Code

<script src="{$BASE_URL*}/uploads/website_specific/jquery.min.js"></script>

You can put the full URL, or whatever URL you choose, but this is neater and more portable.

Sophisticated

Put the Javascript into a themes/default/templates_custom/JAVASCRIPT_WHATEVER.tpl file.

Choose the non-minified version of whatever Javascript library you wish to use, as ocPortal automatically performs minification. It is better that you be able to customise the library's code easily, should you wish to.

At the top of that file, also put:

Code

{$,Parser hint: .innerHTML okay}
{$,Parser hint: pure}
to tell ocPortal to not parse the file for Tempcode. If you don't do this, you'll possibly need to add some Tempcode escaping symbols in certain places.

To load up the Javascript file, use {$REQUIRE_JAVASCRIPT,javascript_whatever} in whatever template will require the Javascript dependency.
 
CEDI change-log Post