Getting started with themes

Hi, and welcome to the SDK documentation for MrSite. The SDK allows you to build custom themes and widgets for all four MrSite packages, with the ability to submit your works of art to the MrSite Marketplace. You can make your themes as simple, or complicated as you like.

This documentation assumes that you're at an intermediate level in CSS.

Structure

The most important files in the template are common.less.css and calculate.less.css which you can find in Assets/css folder. Both of these files use LESS syntax and are compiled immediately after saving in the editor.

Development Tools

All the work on the template is done using our Development Tools. These consist of file browser and tabs with text files that you can edit right inside of your browser.

Text editor

For editing text files we are using the open source ACE editor. It's got code highlighting and stuff. We like it.

Uploading files

To upload files just drag and drop them into the folder. There's a limit as to what type of files you can upload. Here is a full list of allowed extensions: html, htm, css, js, png, gif, jpeg, jpg, txt, eot, ttf, woff, svg, swf, mp3, mp4

Previewing your changes

In the top right corner you will find a "Preview" button. Clicking it will either open a new window or refresh the contents, if it was previously opened.

Editables

Editables are a series of objects that you can add to your common.less.css file in order to extend it's customisation to the users of your theme or widget.

We'll start with the available editables that you can use in your theme. You can use as many editables (or none at all) as you like, it all depends on how much customisation you'd like to give your users. All editables are based on {Less}CSS, and requires some knowledge.

Font "type":"font"

Give your users a selection of fonts for any element in your theme. In the example below, I've added a second option to the dropdown, which will add font inheritance to the element, in the event the user doesn't want to use a custom font.

@font:'OswaldBook', Helvetica, Arial, sans-serif;/*[{"type":"dropdown","name":"My font","group":"My group", "settings": {"'OswaldBook', Helvetica, Arial, sans-serif":"Oswald Book","inherit":"Same as body font"}}]*/

Applying this editable:

.element{
	font-family:@font;
}

You can use any font you like with this editable, including @font-face fonts. Define your font stack using the following code:
"settings": {"'OswaldBook', Helvetica, Arial, sans-serif":"Oswald Book"}.

Substitute "name":"My font" with the name of the element you'd like to display to the user, and "group":"My group" as it's grouped editable.

Colour "type":"color"

This editable will provide a colour picker for whenever you need one, for any element.

@colour:#00B4FF;/*[{"type":"color","name":"My colour","group":"My group"}]*/

Applying this editable:

.element{
	color:@colour;
}

You can use HEX, RGB or RGBa.
Substitute "name":"My colour" with the title of this editable, and "name":"My group" as it's grouped editable.

Dropdown "type":"dropdown"

This editable will give you a dropdown, with extended theme options you'd like to give the user of your theme.

@dropdown:block;/*[{"type":"dropdown","name":"My dropdown","group":"My group", "settings": {"label":"none","label":"block"}}]*/

Applying this editable:

.element{
	display:@dropdown;
}

You can add as many options as you like to this editable. In this example, we've used display:block.
Substitute "name":"My dropdown" with the title of this editable, and "name":"My group" as it's grouped editable.


Slider "type":"size"

The slider is useful for size editables in your theme. You can either use this, or a dropdown - however it's simpler to use a slider in some cases when a range of sizes can be applied. E.g the border size of images.

@slider:0px;/*[{"type":"size","name":"My size","group":"My group", "settings": {"min":0,"max":5}}]*/

Applying this editable:

.element{
	width:@slider;
}

Substitute "name":"My size" with the title of this editable, and "name":"My group" as it's grouped editable.

To get the slider working, define a minimum value "min":0 and a maximum value "max":0.

Background "type":"image" "type":"backgroundrepeat" "type":"position" "type":"backgroundattachment"

The background editable can be attached to any element, with the following options available.

@backgroundimage:none;/*[{"type":"image","name":"My image","group":"My group"}]*/
@backgroundrepeat:no-repeat;/*[{"type":"backgroundrepeat","name":"My image repeat","group":"My group"}]*/
@backgroundposition:top left;/*[{"type":"position","name":"My image position","group":"My group"}]*/
@backgroundattachment:scroll;/*[{"type":"backgroundattachment","name":"My image attachment","group":"My group"}]*/

Applying this editable (the long way):

.element{
	background-url:@backgroundimage;
	background-repeat:@backgroundrepeat;
	background-position:@backgroundposition;
	background-attachment:@backgroundattachment;
}

Applying this editable (short-hand):

.element{
	background:@backgroundimage @backgroundrepeat @backgroundattachment @backgroundposition;
}

You can use all, or one of the above settings, however for full control over how users will upload background images, it's recommended that they're all used.

Theme

Useful if you want to do a few variations on your theme. The outputted CSS will be: html .theme_1_class {/* My awesome css */}

html {
	.theme_1_class;/*[{"type":"dropdown","name":"My theme","group":"global", "settings": {"theme_1_class":"My theme 1","theme_2_class":"My theme 2"}}]*/
}

Applying this editable:

.theme_1_class{
	/*	Define your theme specific styles in here */
}

Note: You need to wrap the theme editable in html {} for it to work.
When the CSS is processed, it will write the output as: html .theme_1_class { /* styles in here */}

Thumbnails

The thumbnail settings below give you control over how the system will crop the users images. Keeping in mind that if you specify more images in your product grid, the sizes of the thumbnails will change. Below are some default sizes that we've found work across the board.

/*
Template.Product.Thumbnail:230,222
Template.Category.Thumbnail:265,255
Template.Showcase.Thumbnail:80,80
Template.Showcase.Big.Thumbnail:370,0
Template.Showcase.Zoom.Thumbnail:600,0
Template.VariantProduct.Thumbnail:80,80
*/

Note: Set the 'y' value to 0 to stop image cropping for Template.Product.Thumbnail and the Template.Showcase.Zoom.Thumbnail.

Product page thumbnail image

Template.Showcase.Thumbnail & Template.VariantProduct.Thumbnail


Products in grid image

Template.Product.Thumbnail


Categories in grid image

Template.Category.Thumbnail


Product page image

Template.Showcase.Big.Thumbnail


Product page image zoomed or popup

Template.Showcase.Zoom.Thumbnail

Common {Less}CSS functions

Here are a few functions that you can use to save yourself time. To apply it to any element, simply call the LessCSS function with the defined variable and the SDK will do the rest.

Rounded corners

We all love rounded corners.

.rounded(@radius: 2px) {
	-moz-border-radius:@radius;
	-webkit-border-radius:@radius;
	-o-border-radius:@radius;
	-ms-border-radius:@radius;
	-khtml-border-radius:@radius;
	border-radius:@radius;
}

Applying this function:

.element{
	.rounded(5px);
}

Note: You won't be able to see the rounded corners in IE6, or IE7.

Gradients

.gradient(@from, @to, @fallback) {
	@ffgradient: "-moz-linear-gradient(center bottom, {0} 0%, {1} 100%)";
	@wkgradient: "-webkit-gradient(linear,left top,left bottom,color-stop(0, {0}), color-stop(1, {1}))";
	@iegradient: "progid:DXImageTransform.Microsoft.gradient(startColorstr='{1}', endColorstr='{0}')";
	@ie8gradient: "\"progid:DXImageTransform.Microsoft.gradient(startColorstr='{1}', endColorstr='{0}')\"";

	background : @fallback;                             /* for non-css3 browsers */
	background : formatstring(@ffgradient, @from, @to); /* FF3.6+ */
	background: formatstring(@wkgradient, @from, @to);  /* Saf4+, Chrome */
	filter: formatstring(@iegradient, @from, @to);      /* IE6,IE7 */
	-ms-filter: formatstring(@ie8gradient, @from, @to); /* IE8 */
}

Applying this function:

.element{
	.gradient(#000, #fff, #686868);
}

Drop shadows

.dropshadow(@a:0px, @b:1px, @c:10px, @colour:rgba(0, 0, 0, 1)) {
    -moz-box-shadow:@a @b @c @colour;
    -webkit-box-shadow:@a @b @c @colour;
    box-shadow:@a @b @c @colour;
    -moz-box-shadow:@a @b @c @colour;
    -webkit-box-shadow:@a @b @c @colour;
    box-shadow:@a @b @c @colour;
}

Applying this function:

.element{
    .dropshadow(0px, 1px, 10px, rgba(0, 0, 0, 1));
}

Opacity

.opacity(@opacity: 0.7){
    @ie7opacity: "progid:DXImageTransform.Microsoft.Alpha(Opacity={0})";
    @ieopacity: alpha(opacity={0});
    -ms-filter:formatstring(@ie7opacity, (@opacity * 100));
    filter:formatstring(@ieopacity, @opacity);
    -moz-opacity:@opacity;
    -khtml-opacity:@opacity;	
    opacity:@opacity;
}

Applying this function:

.element{
    .opacity(0.7);
}

Calculate {Less}CSS functions

Along with the common.less.css file, we've provided a calculate.less.css file that does (yep, you guessed it) all of the template calculations. As a web designer, I'm sure you've probably heard of the 960 grid system. Due to the nature and complexity of the drag and drop page builder in MrSite, we had to tackle the issue of page layouts a little differently. In the calculate.less.css file, we've added the Grid calculator which does all of the hard work for you.

Grid calculator

Whenever a user drops a widget (Content, Twitter feed, Contact form) on their page, they're given a few choices. The first choice is the drop-zone, or content area. These can be seen in the calculator as:

ContentColumnOne, ContentColumnTwo, ContentColumnThree, ContentTop, ContentBottom & footerWrapper.


Once they've dropped the widget in the zone, they'll choose a widget size - defined in the calculator as:

WrapClass0, WrapClass1, WrapClass2, WrapClass3 & WrapClass4


WrapClass4 will be 100% of the content width, while WrapClass2 will be 50% and so on.

At any time, customers may have a product grid, at any size, in any content area of their website. You couldn't manually write CSS for all of these variables, so the grid calculator does all of this work for you. The width of everything is automatically created from a bunch of global sizes defined at the top of the theme.

Note: You don't need to understand how the grid calculator works, rather know what variables you need to put into it.

.GenerateWidgets(){
    .ContentColumnOne{
        .WrapClass0{.BuildSDK(@ColumnOneWidth, 1, 1, (2 * @ColumnOnePadding);}
        .WrapClass1{.BuildSDK(@ColumnOneWidth, 1, 1, (2 * @ColumnOnePadding);}
        .WrapClass2{.BuildSDK(@ColumnOneWidth, 1, 1, (2 * @ColumnOnePadding);}
        .WrapClass3{.BuildSDK(@ColumnOneWidth, 1, 1, (2 * @ColumnOnePadding);}
        .WrapClass4{.BuildSDK(@ColumnOneWidth, 1, 1, (2 * @ColumnOnePadding);}
    }
    .ContentColumnTwo{
        .WrapClass0{.BuildSDK(@ColumnTwoWidth, 4, 1, (2 * @ColumnTwoPadding);}
        .WrapClass1{.BuildSDK(@ColumnTwoWidth, 4, 1, (2 * @ColumnTwoPadding);}
        .WrapClass2{.BuildSDK(@ColumnTwoWidth, 2, 2, (2 * @ColumnTwoPadding);}
        .WrapClass3{.BuildSDK(@ColumnTwoWidth, (4/3), 3, (2 * @ColumnTwoPadding);}
        .WrapClass4{.BuildSDK(@ColumnTwoWidth, 1, 4, (2 * @ColumnTwoPadding);}
    }
    .ContentColumnTwo_Small{
        .WrapClass0{.BuildSDK(@ColumnTwoWidth_Small, 4, 1, (2 * @ColumnTwoPadding);}
        .WrapClass1{.BuildSDK(@ColumnTwoWidth_Small, 4, 1, (2 * @ColumnTwoPadding);}
        .WrapClass2{.BuildSDK(@ColumnTwoWidth_Small, 2, 2, (2 * @ColumnTwoPadding);}
        .WrapClass3{.BuildSDK(@ColumnTwoWidth_Small, (4/3), 3, (2 * @ColumnTwoPadding);}
        .WrapClass4{.BuildSDK(@ColumnTwoWidth_Small, 1, 3, (2 * @ColumnTwoPadding);}
    }
    .ContentColumnTwo_Full{
        .WrapClass0{.BuildSDK(@ColumnTwoWidth_Full, 4, 1, (2 * @ColumnTwoPadding);}
        .WrapClass1{.BuildSDK(@ColumnTwoWidth_Full, 4, 1, (2 * @ColumnTwoPadding);}
        .WrapClass2{.BuildSDK(@ColumnTwoWidth_Full, 2, 3, (2 * @ColumnTwoPadding);}
        .WrapClass3{.BuildSDK(@ColumnTwoWidth_Full, (4/3), 3, (2 * @ColumnTwoPadding);}
        .WrapClass4{.BuildSDK(@ColumnTwoWidth_Full, 1, 4, (2 * @ColumnTwoPadding);}
    }
    .ContentColumnThree{
        .WrapClass0{.BuildSDK(@ColumnThreeWidth, 1, 1, (2 * @ColumnThreePadding);}
        .WrapClass1{.BuildSDK(@ColumnThreeWidth, 1, 1, (2 * @ColumnThreePadding);}
        .WrapClass2{.BuildSDK(@ColumnThreeWidth, 1, 1, (2 * @ColumnThreePadding);}
        .WrapClass3{.BuildSDK(@ColumnThreeWidth, 1, 1, (2 * @ColumnThreePadding);}
        .WrapClass4{.BuildSDK(@ColumnThreeWidth, 1, 1, (2 * @ColumnThreePadding);}
    }
    .ContentTop{
        .WrapClass0{.BuildSDK(@ContentTopWidth, 4, 2, (2 * @TopContentPadding);}
        .WrapClass1{.BuildSDK(@ContentTopWidth, 4, 2, (2 * @TopContentPadding);}
        .WrapClass2{.BuildSDK(@ContentTopWidth, 2, 3, (2 * @TopContentPadding);}
        .WrapClass3{.BuildSDK(@ContentTopWidth, (4/3), 4, (2 * @TopContentPadding);}
        .WrapClass4{.BuildSDK(@ContentTopWidth, 1, 5, (2 * @TopContentPadding);}
    }
    .ContentBottom{
        .WrapClass0{.BuildSDK(@ContentBottomWidth, 4, 2, (2 * @BottomContentPadding);}
        .WrapClass1{.BuildSDK(@ContentBottomWidth, 4, 2, (2 * @BottomContentPadding);}
        .WrapClass2{.BuildSDK(@ContentBottomWidth, 2, 3, (2 * @BottomContentPadding);}
        .WrapClass3{.BuildSDK(@ContentBottomWidth, (4/3), 4, (2 * @BottomContentPadding);}
        .WrapClass4{.BuildSDK(@ContentBottomWidth, 1, 5, (2 * @BottomContentPadding);}
    }
    #footerWrapper{
        .WrapClass0{.BuildSDK(@FooterWidth, 4, 2, (2 * @FooterPadding);}
        .WrapClass1{.BuildSDK(@FooterWidth, 4, 2, (2 * @FooterPadding);}
        .WrapClass2{.BuildSDK(@FooterWidth, 2, 3, (2 * @FooterPadding);}
        .WrapClass3{.BuildSDK(@FooterWidth, (4/3), 4, (2 * @FooterPadding);}
        .WrapClass4{.BuildSDK(@FooterWidth, 1, 5, (2 * @FooterPadding);}
    }
	
    //Start generating the CSS
    .BuildSDK(@width, @divider, @thumbcount, @padding){
	
        @wrapclasswidth:(((@width - @padding) / @divider) - ((2 * @WidgetPadding) + (2 * @WidgetMargin) + (2 * @WidgetBorderWidth)));
        width:@wrapclasswidth;
		
        .productWrapper{
            width:((@wrapclasswidth - (2 * @WidgetBodyPadding)) / @thumbcount);
        }
    }
}
.GenerateWidgets();

Defining your template variables

Template sizes (At the top of calculate.less.css)

//  Template width
    @OuterTemplateWidth:960px;
    @TemplateWidth:960px;
    
//  Column width
    @ColumnOneWidth:220px;
    
//  Template outer spacing
    @TemplateOuterSpacing:0px; 
    
//  Calculating the other columns
    @ColumnThreeWidth:@ColumnOneWidth;
    @ColumnTwoWidth:@TemplateWidth - @ColumnOneWidth;
    @ColumnTwoWidth_Small:@TemplateWidth - @ColumnOneWidth - @ColumnThreeWidth;
    @ColumnTwoWidth_Full:@TemplateWidth;
    @ContentTopWidth:@TemplateWidth;
    @ContentBottomWidth:@TemplateWidth;
    @FooterWidth:@TemplateWidth;

Template padding (At the top of calculate.less.css)

//  Column one dropzone
    @ColumnOnePadding:0px;
    @ColumnOneVerticalPadding:30px;
    
//  Column two dropzone
    @ColumnTwoPadding:0px;
    @ColumnTwoVerticalPadding:30px;
    
//  Column three dropzone
    @ColumnThreePadding:0px;
    @ColumnThreeVerticalPadding:30px;
    
//  Top dropzone
    @TopContentPadding:0px;
    @TopContentVerticalPadding:30px;
    
//  Bottom dropzone
    @BottomContentPadding:0px;
    @BottomContentVerticalPadding:30px;
    
//  Footer dropzone
    @FooterPadding:0px;
    @FooterPaddingVerticalPadding:30px;

Widget padding and borders (At the top of calculate.less.css)

//  Widget paddings
    @WidgetPadding:10px;
    @WidgetVerticalTopPadding:0px;
    @WidgetVerticalBottomPadding:0px;
        
//  Widget internal paddings
    @WidgetTitlePadding:0px 0px 0px;
    @WidgetBodyPadding:0px;
    @WidgetBodyVerticalTopPadding:0px;
    @WidgetBodyVerticalBottomPadding:0px;
            
//  Widget margins
    @WidgetMargin:0px;
    @WidgetVerticalTopMargin:0px;
    @WidgetVerticalBottomMargin:10px;
        
//  Widget internal margins
    @WidgetTitleBottomMargin:0px;
    
//  Widget border width
    @WidgetBorderWidth:0px;

Submitting your theme

When you're ready to submit your theme, there are a few details that we need from you first. Each theme has two icons that we display to users when they're browsing the Marketplace, along with screenshots, a description and a few other bits.

Theme images

To apply your image, simply drag and drop the image onto the appropriate placeholder.


Small image

JPG format: 50px x 50px


Large image

JPG format: 148px x 148px

Submit to MrSite

Clicking on the Submit to MrSite button will pop up a dialog box with a few details you need to submit. If you have already submitted this theme, you'll have the option to submit an update to it. If you submit an update, any customers using your theme will be notified of the update via a small Update button in the list of themes. If you are submitting a new theme, then you'll be presented with the Theme submit form.


Add to categories

Select the categories in which this theme will be applicable.


Details

Fill in the Name, Description, Instructions, Tags, Price and Exclusive price.

The Description and the Instructions will be shown to the customer in the Marketplace. You can submit your theme as FREE by leaving the Price and Exclusive price as 0.


Screenshot image (up to 6)

JPG format: 800px x 600px