https://oxpedia.org/wiki/api.php?action=feedcontributions&user=Alexander.quast&feedformat=atomOpen-Xchange - User contributions [en]2024-03-28T22:15:41ZUser contributionsMediaWiki 1.31.0https://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=22884AppSuite:Theming2017-02-10T08:44:24Z<p>Alexander.quast: /* Favicons and mobile homescreen icons */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>/opt/open-xchange/appsuite/apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
Variables are defined in variables.less from twitter-bootstrap and our default definitions.less. Variables that are defined in definitions.less always override variables from bootstrap's variables.less<br />
<br />
=== Most relevant variables ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @topbar-background || @topbarBackground || #3774A8 (blue)<br />
|-<br />
| --- || @topbarBackgroundAlt || No longer used<br />
|-<br />
| @topbar-launcher-color || @topbarLauncherColor || rgba(255, 255, 255, 0.70)<br />
|-<br />
| @topbar-launcher-color-hover || @topbarLauncherColor-hover || #fff<br />
|-<br />
| @topbar-launcher-color-active || @topbarLauncherColorActive || #fff<br />
|-<br />
| @topbar-launcher-background-hover || @topbarLauncherBackgroundHover || rgba(0, 0, 0, 0.30)<br />
|-<br />
| @topbar-launcher-background-active || @topbarLauncherBackgroundActive || rgba(0, 0, 0, 0.20);<br />
|-<br />
| @topbar-icon-color || @topbarIconColor || #fff<br />
|-<br />
| @selected-background || @selectedBackground || #428BCA (blue)<br />
|-<br />
| @contact-picture-radius || @contactPictureRadius || 50%<br />
|-<br />
|}<br />
:<br />
<br />
<br />
The most significant visual change is achieved by changing the following variables:<br />
* '''@topbar-background''' (top navigation bar)<br />
* '''@selected-background''' (selection background color in list views and folder tree)<br />
* '''@link-color''' (almost all hyperlinks)<br />
<br />
=== Font ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @font-family-sans-serif || @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @font-family-serif || @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @font-family-monospace || @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @font-size-base || @baseFontSize || 14px<br />
|-<br />
| || @baseFontFamily ||<br />
|-<br />
| @line-height-base || @baseLineHeight || 1.428571429; // 20/14<br />
|-<br />
| || @altFontFamily ||<br />
|-<br />
| @font-size-touch || @touchFontSize || 15px<br />
|-<br />
| @headings-font-family || @headingsFontFamily || inherit<br />
|-<br />
| @headings-font-weight || @headingsFontWeight || 500<br />
|-<br />
| @font-size-large || @fontSizeLarge || ceil((@font-size-base * 1.25)); // ~18px<br />
|-<br />
| @font-size-small || @fontSizeSmall || ceil((@font-size-base * 0.85)); // ~12px<br />
|-<br />
| || @fontSizeMini ||<br />
|-<br />
| @vgrid-font-size || @vgridFontSize || 13px<br />
|}<br />
<br />
=== Colors ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @background || @bodyBackground || #fff<br />
|-<br />
| @text-color || @textColor || @gray-dark<br />
|-<br />
| @link-color || @linkColor || @brand-primary<br />
|-<br />
| @link-hover-color || @linkColorHover || darken(@link-color, 15%)<br />
|-<br />
| @link-accent-color || @linkAccentColor || #ffad00<br />
|-<br />
| || @linkAccentColorHover ||<br />
|-<br />
| @badge-color || @badgeColor || @white<br />
|-<br />
| @badge-bg || @badgeBackground || #aaa<br />
|-<br />
| @headings-color || @headingsColor || inherit<br />
|-<br />
| @black || @black || #000<br />
|-<br />
| @gray-darker || @grayDarker || #222<br />
|-<br />
| @gray-dark || @grayDark || #333<br />
|-<br />
| @gray || @gray || #555<br />
|-<br />
| @gray-light || @grayLight || #999<br />
|-<br />
| @gray-lighter || @grayLighter || #eee<br />
|-<br />
| @white || @white || #fff<br />
|-<br />
| @blue || @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blue-dark || @blueDark || #0064cd<br />
|-<br />
| @blue-light || @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || @green || #1A8D1A<br />
|-<br />
| @green-light || @greenLight || #92D050<br />
|-<br />
| @red || @red || #cc0000<br />
|-<br />
| @yellow || @yellow || #F8E400<br />
|-<br />
| @orange || @orange || #f89406<br />
|-<br />
| @pink || @pink || #E01CD9<br />
|-<br />
| @purple || @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
=== Space ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| || @paddingLarge ||<br />
|-<br />
| || @paddingSmall ||<br />
|-<br />
| || @paddingMini ||<br />
|-<br />
| @border-radius-base || @baseBorderRadius || 4px<br />
|-<br />
| @border-radius-large || @borderRadiusLarge || 6px<br />
|-<br />
| @border-radius-small || @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @pagination-bg || @paginationBackground || #fff<br />
|-<br />
| @pagination-border || @paginationBorder || #ddd<br />
|-<br />
| @pagination-active-bg || @paginationActiveBackground || @brand-primary<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| || @btnBackground ||<br />
|-<br />
| || @btnBackgroundHighlight ||<br />
|-<br />
| || @btnBorder ||<br />
|-<br />
| @btn-primary-bg || @btnPrimaryBackground || @link-color<br />
|-<br />
| || @btnPrimaryBackgroundHighlight ||<br />
|-<br />
| @btn-info-bg || @btnInfoBackground || #5bc0de<br />
|-<br />
| || @btnInfoBackgroundHighlight ||<br />
|-<br />
| @btn-success-bg || @btnSuccessBackground || #62c462<br />
|-<br />
| || @btnSuccessBackgroundHighlight ||<br />
|-<br />
| @btn-warning-bg || @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| || @btnWarningBackgroundHighlight ||<br />
|-<br />
| @btn-danger-bg || @btnDangerBackground || #ee5f5b<br />
|-<br />
| || @btnDangerBackgroundHighlight ||<br />
|-<br />
| @btn-inverse-bg || @btnInverseBackground || #444<br />
|-<br />
| || @btnInverseBackgroundHighlight ||<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @dropdown-bg || @dropdownBackground || #fff<br />
|-<br />
| @dropdown-border || @dropdownBorder || rgba(0,0,0,.15)<br />
|-<br />
| @dropdown-divider-bg || @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdown-divider-bg || @dropdownDividerBottom || #e5e5e5<br />
|-<br />
| @dropdown-link-color || @dropdownLinkColor || @gray-dark<br />
|-<br />
| @dropdown-link-hover-color || @dropdownLinkColorHover || darken(@gray-dark, 5%)<br />
|-<br />
| @dropdown-link-active-color || @dropdownLinkColorActive || @component-active-color<br />
|-<br />
| @dropdown-link-active-bg || @dropdownLinkBackgroundActive || @component-active-bg<br />
|-<br />
| @dropdown-link-hover-bg || @dropdownLinkBackgroundHover || #f5f5f5<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @foldertree-sidepane-background || @foldertreeSidepanelBackground || #f5f5f5 ||<br />
|-<br />
| @foldertee-section-title-color || @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertree-active-label-color || @foldertreeActiveLabelColor || #333 || ''Active'' means, user can perform an action on this item<br />
|-<br />
|@foldertree-passive-label-color || @foldertreePassiveLabelColor ||@hc-gray || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertree-hover-background || @foldertreeHoverBackground || rgba(0, 0, 0, 0.05) ||<br />
|-<br />
| @foldertree-selected-background || @foldertreeSelectedBackground || rgba(0, 0, 0, 0.10) ||<br />
|-<br />
| @foldertree-badge-background || @foldertreeBadgeBackground || @bagde-bg || see [[#Colors]] for definition of @badge-bg<br />
|-<br />
| @foldertree-badge-color || @foldertreeBadgeColor ||@badge-color || see [[#Colors]] for definition of @badge-color<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @appointment-reserved || @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointment-temporary || @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointment-absent || @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointment-free || @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointment-private || @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointment-declined-font || @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointment-unconfirmed-alpha || @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointment-declined-alpha || @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointment-hover-pct || @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @weekview-appointment-lasso || @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekview-day-in || @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekview-day-out || @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekview-timeline || @weekviewTimeline || rgba(243, 15, 170, 0.4) || Color of the Line indicating the current time<br />
|-<br />
| @weekview-time-width || @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendar-toolbar-height || @calendarToolbarHeight || 47px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @monthview-appointment-out || @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthview-today || @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| || @monthview@calendarToolbarHeight || ||<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(path/to/mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. Reference the entire path to the file, relative to the folder containing your ui, but without the leading slash. For example, the Core reference would be <code>apps/themes/default/logo-small.png</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
=== Mobile and retina screens ===<br />
<br />
Almost any mobile device and some newer desktop devices use retina screens. These screens do have a very high pixel density which offer very sharp text rendering. To offer sharp and correctly sized images on retina screens there is and additional CSS directive encapsulated in a media query which must be set in your custom theme.<br />
<br />
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),<br />
only screen and (-moz-min-device-pixel-ratio: 1.5),<br />
only screen and (min-device-pixel-ratio: 1.5),<br />
only screen and (min-resolution: 240dppx) {<br />
#io-ox-top-logo-small {<br />
background-size: 60px 22px;<br />
background-image: url('apps/themes/default/logo-large.png');<br />
}<br />
}<br />
<br />
'''It is important that you provide your brand logo in two sizes''', the standard size of 60x22px and a large version with doubled pixel sizes of 120x44px. All retina devices will use the large logo and scale it down the CSS pixel size of 60x22px. This will result in a sharp image as the retina screen can make use of the additional available pixels in the source image.<br />
<br />
'''Important note''': Your logo must not be wider than 70px (including margins) for mobile devices. Otherwise the toolbar will be broken on mobile devices as the large logo will cause a line wrap in the toolbar. If you need a larger logo use a custom, smaller one for mobiles. <br />
<br />
Always test your theme on mobiles, too. You can emulate popular screen sizes with the Google Chrome Dev-Tools.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
'''This documentation applies for AppSuite from 7.4.2 up'''<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon<br />
# set of touch icons which are mainly used by iOS and Android devices<br />
<br />
These icons are used as default for all devices and browsers as long as you don't deliver your own icons with your theme. To provide your own icons, put them into your theme's directory, e.g. <tt>apps/themes/<var>theme-name</var>/favicon.ico</tt>.<br />
<br />
=== Favicon ===<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
You should provide your custom favicon within your custom theme. If you do not add a custom favicon to your theme the global OX default will be used. The default icon is located under <tt>apps/themes/icons/default</tt> on the web server.<br />
<br />
'''Attention:''' Safari and Internet Explorer do not support dynamic changes to the favicon for a webpage. This means, the default icon will be shown even if a custom favicon is provided within a custom theme. To enable the right favicon for a theme on Safari and IE, the overall standard <tt>favicon.ico</tt> located under <tt>apps/themes/icons/default</tt> on the web server must be replaced with a custom version.<br />
<br />
=== Apple and Android touch icons ===<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. Chrome on Android also support these homescreen bookmarks. AppSuite offers full support for Webclips by providing all needed App icons. If a user uses the "Add to homescreen" button on his iOS oder Android device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format. In most cases modern devices will use the best resolution fitted for the current display resolution.<br />
<br />
* 57 x 57 px<br />
* 72 x 72 px<br />
* 76 x 76 px<br />
* 114 x 114 px<br />
* 120 x 120 px<br />
* 144 x 144 px (Android xxhdpi)<br />
* 152 x 152 px<br />
* 167 x 167 px<br />
* 180 x 180 px<br />
* 190 x 190 px (Android xxxhdpi)<br />
<br />
From version '''7.8.4''' on there will be '''no splashscreens''' anymore. <br />
<br />
For previous releases there are three splashscreen sizes supported:<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
All splashscreens must be JPG files.<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change due to vendor updates. We recommend providing all of this resolutions when customizing the Webclip icons. This can easily be done by using a simple Imagemagick script to convert all icons via batch operation.<br />
<br />
=== Providing custom icons ===<br />
To provide custom Webclip icons locate the following path in the AppSuite installation on your web server:<br />
pathToAppSuite/apps/themes/icons/default<br />
<br />
This folder contains all OX default icons for Webclips icons and splashscreens. Use these as samples for your own versions.<br />
<br />
A clean installation will have all our default icons in the "default" directory. To customize the icons we recommend using our default icons as samples and save your customized version in your theme. '''Note''': The filename has to be the same as in the default folder. Otherwise the fallback will be applied and the default icons will be used. If more advanced rewriting is needed one should edit the contents of the <tt>.htaccess</tt> file located under <tt>apps/themes</tt><br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
=== Providing domain based login themes ===<br />
<br />
This is only needed when using the default login screen shipped with the Core UI and for versions older than the 7.8.0 release. Since 7.8.0, the normal way via as-config.yml will work just fine ([[AppSuite:Theming the login page|Learn how to do this here]]).<br />
<br />
If you have a multibrand installation and you want to deliver not only custom themes but also custom login-themes this can be done via Apache mod_rewrite. You can do so by a domain-based rewrite rule to deliver custom themes to a user based on the URI he's using. The needed config file <tt>.htaccess</tt> is located under <tt>apps/themes</tt><br />
<br />
<pre><br />
# Sample config for domain based login theme<br />
RewriteCond %{HTTP_HOST} ^www\.domain\.com$<br />
RewriteCond %{REQUEST_FILENAME} -f<br />
RewriteRule ^login/(.*)$ domain_com_logintheme/$1 [L]<br />
</pre><br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]<br />
[[Category:Custom development]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=22883AppSuite:Theming2017-02-10T08:43:10Z<p>Alexander.quast: /* Apple touch icons */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>/opt/open-xchange/appsuite/apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
Variables are defined in variables.less from twitter-bootstrap and our default definitions.less. Variables that are defined in definitions.less always override variables from bootstrap's variables.less<br />
<br />
=== Most relevant variables ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @topbar-background || @topbarBackground || #3774A8 (blue)<br />
|-<br />
| --- || @topbarBackgroundAlt || No longer used<br />
|-<br />
| @topbar-launcher-color || @topbarLauncherColor || rgba(255, 255, 255, 0.70)<br />
|-<br />
| @topbar-launcher-color-hover || @topbarLauncherColor-hover || #fff<br />
|-<br />
| @topbar-launcher-color-active || @topbarLauncherColorActive || #fff<br />
|-<br />
| @topbar-launcher-background-hover || @topbarLauncherBackgroundHover || rgba(0, 0, 0, 0.30)<br />
|-<br />
| @topbar-launcher-background-active || @topbarLauncherBackgroundActive || rgba(0, 0, 0, 0.20);<br />
|-<br />
| @topbar-icon-color || @topbarIconColor || #fff<br />
|-<br />
| @selected-background || @selectedBackground || #428BCA (blue)<br />
|-<br />
| @contact-picture-radius || @contactPictureRadius || 50%<br />
|-<br />
|}<br />
:<br />
<br />
<br />
The most significant visual change is achieved by changing the following variables:<br />
* '''@topbar-background''' (top navigation bar)<br />
* '''@selected-background''' (selection background color in list views and folder tree)<br />
* '''@link-color''' (almost all hyperlinks)<br />
<br />
=== Font ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @font-family-sans-serif || @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @font-family-serif || @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @font-family-monospace || @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @font-size-base || @baseFontSize || 14px<br />
|-<br />
| || @baseFontFamily ||<br />
|-<br />
| @line-height-base || @baseLineHeight || 1.428571429; // 20/14<br />
|-<br />
| || @altFontFamily ||<br />
|-<br />
| @font-size-touch || @touchFontSize || 15px<br />
|-<br />
| @headings-font-family || @headingsFontFamily || inherit<br />
|-<br />
| @headings-font-weight || @headingsFontWeight || 500<br />
|-<br />
| @font-size-large || @fontSizeLarge || ceil((@font-size-base * 1.25)); // ~18px<br />
|-<br />
| @font-size-small || @fontSizeSmall || ceil((@font-size-base * 0.85)); // ~12px<br />
|-<br />
| || @fontSizeMini ||<br />
|-<br />
| @vgrid-font-size || @vgridFontSize || 13px<br />
|}<br />
<br />
=== Colors ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @background || @bodyBackground || #fff<br />
|-<br />
| @text-color || @textColor || @gray-dark<br />
|-<br />
| @link-color || @linkColor || @brand-primary<br />
|-<br />
| @link-hover-color || @linkColorHover || darken(@link-color, 15%)<br />
|-<br />
| @link-accent-color || @linkAccentColor || #ffad00<br />
|-<br />
| || @linkAccentColorHover ||<br />
|-<br />
| @badge-color || @badgeColor || @white<br />
|-<br />
| @badge-bg || @badgeBackground || #aaa<br />
|-<br />
| @headings-color || @headingsColor || inherit<br />
|-<br />
| @black || @black || #000<br />
|-<br />
| @gray-darker || @grayDarker || #222<br />
|-<br />
| @gray-dark || @grayDark || #333<br />
|-<br />
| @gray || @gray || #555<br />
|-<br />
| @gray-light || @grayLight || #999<br />
|-<br />
| @gray-lighter || @grayLighter || #eee<br />
|-<br />
| @white || @white || #fff<br />
|-<br />
| @blue || @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blue-dark || @blueDark || #0064cd<br />
|-<br />
| @blue-light || @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || @green || #1A8D1A<br />
|-<br />
| @green-light || @greenLight || #92D050<br />
|-<br />
| @red || @red || #cc0000<br />
|-<br />
| @yellow || @yellow || #F8E400<br />
|-<br />
| @orange || @orange || #f89406<br />
|-<br />
| @pink || @pink || #E01CD9<br />
|-<br />
| @purple || @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
=== Space ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| || @paddingLarge ||<br />
|-<br />
| || @paddingSmall ||<br />
|-<br />
| || @paddingMini ||<br />
|-<br />
| @border-radius-base || @baseBorderRadius || 4px<br />
|-<br />
| @border-radius-large || @borderRadiusLarge || 6px<br />
|-<br />
| @border-radius-small || @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @pagination-bg || @paginationBackground || #fff<br />
|-<br />
| @pagination-border || @paginationBorder || #ddd<br />
|-<br />
| @pagination-active-bg || @paginationActiveBackground || @brand-primary<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| || @btnBackground ||<br />
|-<br />
| || @btnBackgroundHighlight ||<br />
|-<br />
| || @btnBorder ||<br />
|-<br />
| @btn-primary-bg || @btnPrimaryBackground || @link-color<br />
|-<br />
| || @btnPrimaryBackgroundHighlight ||<br />
|-<br />
| @btn-info-bg || @btnInfoBackground || #5bc0de<br />
|-<br />
| || @btnInfoBackgroundHighlight ||<br />
|-<br />
| @btn-success-bg || @btnSuccessBackground || #62c462<br />
|-<br />
| || @btnSuccessBackgroundHighlight ||<br />
|-<br />
| @btn-warning-bg || @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| || @btnWarningBackgroundHighlight ||<br />
|-<br />
| @btn-danger-bg || @btnDangerBackground || #ee5f5b<br />
|-<br />
| || @btnDangerBackgroundHighlight ||<br />
|-<br />
| @btn-inverse-bg || @btnInverseBackground || #444<br />
|-<br />
| || @btnInverseBackgroundHighlight ||<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @dropdown-bg || @dropdownBackground || #fff<br />
|-<br />
| @dropdown-border || @dropdownBorder || rgba(0,0,0,.15)<br />
|-<br />
| @dropdown-divider-bg || @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdown-divider-bg || @dropdownDividerBottom || #e5e5e5<br />
|-<br />
| @dropdown-link-color || @dropdownLinkColor || @gray-dark<br />
|-<br />
| @dropdown-link-hover-color || @dropdownLinkColorHover || darken(@gray-dark, 5%)<br />
|-<br />
| @dropdown-link-active-color || @dropdownLinkColorActive || @component-active-color<br />
|-<br />
| @dropdown-link-active-bg || @dropdownLinkBackgroundActive || @component-active-bg<br />
|-<br />
| @dropdown-link-hover-bg || @dropdownLinkBackgroundHover || #f5f5f5<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @foldertree-sidepane-background || @foldertreeSidepanelBackground || #f5f5f5 ||<br />
|-<br />
| @foldertee-section-title-color || @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertree-active-label-color || @foldertreeActiveLabelColor || #333 || ''Active'' means, user can perform an action on this item<br />
|-<br />
|@foldertree-passive-label-color || @foldertreePassiveLabelColor ||@hc-gray || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertree-hover-background || @foldertreeHoverBackground || rgba(0, 0, 0, 0.05) ||<br />
|-<br />
| @foldertree-selected-background || @foldertreeSelectedBackground || rgba(0, 0, 0, 0.10) ||<br />
|-<br />
| @foldertree-badge-background || @foldertreeBadgeBackground || @bagde-bg || see [[#Colors]] for definition of @badge-bg<br />
|-<br />
| @foldertree-badge-color || @foldertreeBadgeColor ||@badge-color || see [[#Colors]] for definition of @badge-color<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @appointment-reserved || @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointment-temporary || @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointment-absent || @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointment-free || @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointment-private || @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointment-declined-font || @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointment-unconfirmed-alpha || @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointment-declined-alpha || @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointment-hover-pct || @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @weekview-appointment-lasso || @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekview-day-in || @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekview-day-out || @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekview-timeline || @weekviewTimeline || rgba(243, 15, 170, 0.4) || Color of the Line indicating the current time<br />
|-<br />
| @weekview-time-width || @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendar-toolbar-height || @calendarToolbarHeight || 47px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @monthview-appointment-out || @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthview-today || @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| || @monthview@calendarToolbarHeight || ||<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(path/to/mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. Reference the entire path to the file, relative to the folder containing your ui, but without the leading slash. For example, the Core reference would be <code>apps/themes/default/logo-small.png</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
=== Mobile and retina screens ===<br />
<br />
Almost any mobile device and some newer desktop devices use retina screens. These screens do have a very high pixel density which offer very sharp text rendering. To offer sharp and correctly sized images on retina screens there is and additional CSS directive encapsulated in a media query which must be set in your custom theme.<br />
<br />
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),<br />
only screen and (-moz-min-device-pixel-ratio: 1.5),<br />
only screen and (min-device-pixel-ratio: 1.5),<br />
only screen and (min-resolution: 240dppx) {<br />
#io-ox-top-logo-small {<br />
background-size: 60px 22px;<br />
background-image: url('apps/themes/default/logo-large.png');<br />
}<br />
}<br />
<br />
'''It is important that you provide your brand logo in two sizes''', the standard size of 60x22px and a large version with doubled pixel sizes of 120x44px. All retina devices will use the large logo and scale it down the CSS pixel size of 60x22px. This will result in a sharp image as the retina screen can make use of the additional available pixels in the source image.<br />
<br />
'''Important note''': Your logo must not be wider than 70px (including margins) for mobile devices. Otherwise the toolbar will be broken on mobile devices as the large logo will cause a line wrap in the toolbar. If you need a larger logo use a custom, smaller one for mobiles. <br />
<br />
Always test your theme on mobiles, too. You can emulate popular screen sizes with the Google Chrome Dev-Tools.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
'''This documentation applies for AppSuite v.7.4.2'''<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers as long as you don't deliver your own icons with your theme. To provide your own icons, put them into your theme's directory, e.g. <tt>apps/themes/<var>theme-name</var>/favicon.ico</tt>.<br />
<br />
=== Favicon ===<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
You should provide your custom favicon within your custom theme. If you do not add a custom favicon to your theme the global OX default will be used. The default icon is located under <tt>apps/themes/icons/default</tt> on the web server.<br />
<br />
'''Attention:''' Safari and Internet Explorer do not support dynamic changes to the favicon for a webpage. This means, the default icon will be shown even if a custom favicon is provided within a custom theme. To enable the right favicon for a theme on Safari and IE, the overall standard <tt>favicon.ico</tt> located under <tt>apps/themes/icons/default</tt> on the web server must be replaced with a custom version.<br />
<br />
=== Apple and Android touch icons ===<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. Chrome on Android also support these homescreen bookmarks. AppSuite offers full support for Webclips by providing all needed App icons. If a user uses the "Add to homescreen" button on his iOS oder Android device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format. In most cases modern devices will use the best resolution fitted for the current display resolution.<br />
<br />
* 57 x 57 px<br />
* 72 x 72 px<br />
* 76 x 76 px<br />
* 114 x 114 px<br />
* 120 x 120 px<br />
* 144 x 144 px (Android xxhdpi)<br />
* 152 x 152 px<br />
* 167 x 167 px<br />
* 180 x 180 px<br />
* 190 x 190 px (Android xxxhdpi)<br />
<br />
From version '''7.8.4''' on there will be '''no splashscreens''' anymore. <br />
<br />
For previous releases there are three splashscreen sizes supported:<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
All splashscreens must be JPG files.<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change due to vendor updates. We recommend providing all of this resolutions when customizing the Webclip icons. This can easily be done by using a simple Imagemagick script to convert all icons via batch operation.<br />
<br />
=== Providing custom icons ===<br />
To provide custom Webclip icons locate the following path in the AppSuite installation on your web server:<br />
pathToAppSuite/apps/themes/icons/default<br />
<br />
This folder contains all OX default icons for Webclips icons and splashscreens. Use these as samples for your own versions.<br />
<br />
A clean installation will have all our default icons in the "default" directory. To customize the icons we recommend using our default icons as samples and save your customized version in your theme. '''Note''': The filename has to be the same as in the default folder. Otherwise the fallback will be applied and the default icons will be used. If more advanced rewriting is needed one should edit the contents of the <tt>.htaccess</tt> file located under <tt>apps/themes</tt><br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
=== Providing domain based login themes ===<br />
<br />
This is only needed when using the default login screen shipped with the Core UI and for versions older than the 7.8.0 release. Since 7.8.0, the normal way via as-config.yml will work just fine ([[AppSuite:Theming the login page|Learn how to do this here]]).<br />
<br />
If you have a multibrand installation and you want to deliver not only custom themes but also custom login-themes this can be done via Apache mod_rewrite. You can do so by a domain-based rewrite rule to deliver custom themes to a user based on the URI he's using. The needed config file <tt>.htaccess</tt> is located under <tt>apps/themes</tt><br />
<br />
<pre><br />
# Sample config for domain based login theme<br />
RewriteCond %{HTTP_HOST} ^www\.domain\.com$<br />
RewriteCond %{REQUEST_FILENAME} -f<br />
RewriteRule ^login/(.*)$ domain_com_logintheme/$1 [L]<br />
</pre><br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]<br />
[[Category:Custom development]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:OX_Mail&diff=22284AppSuite:OX Mail2016-08-10T08:14:20Z<p>Alexander.quast: /* Using your own middleware server */</p>
<hr />
<div>= OX Mail =<br />
<br />
OX Mail is a native mobile phone app built specifically for smartphone users who already have a valid OX App Suite account. The app is designed to let users access their OX App Suite email environment directly from a smartphone native client.<br />
<br />
OX Mail enables users to synchronize mails between a variety of smartphone devices and OX App Suite. OX Mail consists of two elements: The OX Mail component that is built into OX App Suite and the native OX Mail app.<br />
<br />
The OX Mail app has been designed specifically for ease-of-use and is available for both iOS and Android.<br />
<br />
'''Please Note: With this app Open-Xchange has also created a new branding concept for the customers and partners. More information can be found in the chapter [http://oxpedia.org/wiki/index.php?title=AppSuite:OX_Mail#Integrated_Branding.2FCustomization_Concept_for_Partners_and_Customers Branding/Customization Concept for Partners and Customers]'''<br />
<br />
== Requirements ==<br />
<br />
=== Server-side Installation and Configuration ===<br />
<br />
With OX Mail, OX App Suite supports server based PUSH functionality.<br />
<br />
Dovecot customers can use the special PUSH plugin without any additional costs. The plugin will be provided via the Dovecot software repository for Dovecot Pro and community edition. '''Please Note, the installation of the latest Dovecot v2.2.19 release is required'''<br />
<br />
'''Please Note: The Open-Xchange package 'open-xchange-push-imapidle' which provides mail push functionality by using the IMAP IDLE command to generate push events when new mail arrives, is not officially supported with OX Mail (app).'''<br />
<br />
If you are not using the Dovecot Push Plugin your mail backend has to actively notify the Open-Xchange middleware servers of new emails. This might require the creation of an additional OX middleware plugin to receive those notifications. For further details please contact your assigned pre-sales / prof. services contact.<br />
<br />
'''Please Note, the installation of the latest OX App Suite version is required.'''<br />
<br />
You will finde the client requirements under [[AppSuite:OX_System_Requirements#OX_Mail_for_Clients|OX Mail requirements]]<br />
<br />
== Key Benefits ==<br />
<br />
* Supports email PUSH notification for personal Inbox – emails show up immediately on the device<br />
* Quick and easy to set up with the start-up wizard<br />
* Intuitive, simple to use, design <br />
* Familiar smartphone experience<br />
* Available for both iOS and Android – download app from App Store for free<br />
<br />
A more detailed overview of OX Mail, can be found at: http://software.open-xchange.com/products/mail/doc/OX_Mail_Product_Guide.pdf<br />
<br />
== Pricing & Availability ==<br />
<br />
This email app is available for both iOS and Android and can be downloaded for free from the corresponding App Stores. Availability will be confirmed by Open-Xchange via the usual communication channels. <br />
<br />
'''Please note:''' The exact date when the clients become available depends on the approval process of the respective app stores. <br />
<br />
The Open-Xchange Middleware components can be downloaded from the respective download repositories as normal.<br />
<br />
Please contact your Open-Xchange account manager for further information and pricing details.<br />
<br />
= Enabling OX Mail =<br />
<br />
In order to support multi-tenancy/multi-brands systems the mail app functionality can be enabled or disabled per hostname. For this reason with version 1.4 the "mailapp-config.yml" property file was introduced:<br />
<br />
default:<br />
host: all<br />
mail_app_enabled: true<br />
<br />
# Override mail_app_enabled setting for certain hosts<br />
#myhost:<br />
# host: myexchange.myhost.mytld<br />
# mail_app_enabled: true <br />
<br />
One can for example disable the mail app feature for the default case and enable it for specific hosts. Wether a user is able to perform a login request within the mail app depends on the configured hostname of the mail app. If the configured hostname matches any hostname in the mailapp-config.yml which has mail_app_enabled set to true then the user is allowed to perform a login request.<br />
<br />
In addition OX Mail is only enabled for all users that have the capability ''com.openexchange.capability.mobile_mail_app'' <br />
<br />
More details about capabilities can be found at [[AppSuite:Capabilities]]. Furthermore, this capability can be defined in a more granular way using the Config Cascade as described at [[ConfigCascade]].<br />
<br />
IMPORTANT: <br />
By default, the capability for the OX Mail app is set to false for all users. It can be changed by editing the corresponding capability in the "permissions.properties" config file, or if you need a more fine grained selection of enabled users, you can use the well known provisioning tools / config cascade.<br />
<br />
= Installation of the Clients =<br />
<br />
The OX Mail is available via the different App Stores for iOS and Android:<br />
<br />
* [https://itunes.apple.com/us/app/ox-mail/id1008644994?l=de&ls=1&mt=8 OX Mail in Apple App Store]<br />
* [https://play.google.com/store/apps/details?id=com.openexchange.mobile.mailapp.enterprise OX Mail in GooglePlay]<br />
<br />
== Using your own middleware server ==<br />
<br />
If you are not listed on our provider list you may want to use your own middleware server by typing in the URI manually. Enter the path where your App Suite middleware instance is listening, i.e. https://gold.ox.io . The App will search for the typical API paths automatically based on your input. <br />
<br />
You can simply re-check where your App Suite middleware instance is listening by typing the full API path in a web browser, i.e. https://gold.ox.io/appsuite/api/. If you see a "Not found" status page from Grizzly, the path is correct. A simple "404 not found" from Apache indicates the path is not correct. <br />
<br />
Please note: Do not enter the full API path in the App, just the base URL like https://gold.ox.io. Also you will need a valid and fully trusted SSL certificate on the webserver, otherwise the App will refuse to connect.<br />
<br />
= OX Mail Server-side Installation and Configuration on OX App Suite v7.8.x =<br />
<br />
This chapter describes how the backend components of OX Mail are installed and configured on the server.<br />
<br />
== Available packages ==<br />
<br />
OX Mail is available with the following backend packages:<br />
<br />
* ''open-xchange-mobile-push-certificates'' - Certificates for cloud-based push notifications<br />
* ''open-xchange-mailapp-backend'' - The main server components for OX Mail<br />
* ''open-xchange-mobile-push-plugin'' - Provides Push functionality<br />
<br />
Installation on the server varies depending on the underlying distribution, details are available in the following chapters.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ yum install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 7.0 (Wheezy) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 8.0 (Jessie) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianJessie|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=debianname|pc2v=DebianJessie|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|backend/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=susename|pc2v=SLES11|mail|mailapp}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== SUSE Linux Enterprise Server 12 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLE_12|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|backend/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=susename|pc2v=SLE_12|mail|mailapp}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
= OX Mail Server-side Installation and Configuration on OX App Suite v7.6.2 =<br />
<br />
This chapter describes how the backend components of OX Mail are installed and configured on the server.<br />
<br />
== Enforced SSL connection on iOS clients ==<br />
<br />
With iOS 9 Apple introduced ATS (App Transport Security) which by default blocks all unencrypted network connections for Apps using http. To enable OX Mail for iOS on your server you will need to provide a valid SSL certificate for your system, otherwise the iOS client will refuse to connect to your system. Using a unencrypted http connection will not work.<br />
<br />
You can simply test if your certificate is valid by visiting your webserver with iOS Safari. If the browser accepts your https connection without showing any warning, your certificate is trusted by the system and OX Mail will also work.<br />
<br />
== Available packages ==<br />
<br />
OX Mail is available with the following backend packages:<br />
<br />
* ''open-xchange-mobile-push-certificates'' - Certificates for cloud-based push notifications<br />
* ''open-xchange-mailapp-backend'' - The main server components for OX Mail<br />
* ''open-xchange-mobile-push-plugin'' - Provides Push functionality<br />
<br />
Installation on the server varies depending on the underlying distribution, details are available in the following chapters.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ yum install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 6.0 (Squeeze) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=debianname|pc2v=DebianSqueeze|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=debianname|pc2v=DebianSqueeze|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 7.0 (Wheezy) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=debianname|pc2v=DebianWheezy|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|backend/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=susename|pc2v=SLES11|mail|mailapp}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
= Setup Description for Mobile Push =<br />
<br />
== Setup of the Open-Xchange Node==<br />
<br />
The existing push framework of the Open-Xchange Middleware has been extended by the capability to spawn "permanent" listeners for incoming new message deliveries. Up to that point the life cycle for a listener was bound to at least one active session, which is associated with a client that is allowed to receive push notifications.<br />
<br />
With introduction of the previously mentioned capability, listeners can be started without the need for an existent session right on the start of an Open-Xchange Middleware node. In addition those permanent listeners are spread approximately even over capable cluster members as - dependent on the underlying implementation - a listener representation may open/hold resources (socket connections) in order to receive notifications about new message deliveries.<br />
<br />
To prepare a certain Open-Xchange Middleware node to spawn permanent push listeners the following properties need to be configured in file '/opt/open-xchange/etc/mail-push.properties':<br />
<br />
* com.openexchange.push.allowPermanentPush<br>This is the general switch to enable/disable support for permanent listeners on a node. Thus needs to be set to "true"<br />
* com.openexchange.push.allowedClient<br>Specify the comma-separated list of clients which are allowed to receive notifications about new mails, “open-xchange-mailapp” should be added here if you plan to use it in combination with the new mobile-push feature.<br />
* com.openexchange.push.credstorage.enabled<br>As permanent listeners are required to run without an active session, the credential storage can be used to store user credentials in installations that do not support a master authentication to the mail storage Hence, if the property "com.openexchange.mail.passwordSource" (mail.properties) is not set to "global" this property is required to be set to "true"<br />
* com.openexchange.push.credstorage.passcrypt<br>This property is required if "com.openexchange.push.credstorage.enabled" is set to "true". It does specify the passphrase to use to symmetrically encrypt the stored credentials. The passphrase is required to be equal on each cluster member.<br />
* com.openexchange.push.credstorage.rdb<br>Once the credential storage is enabled, Open-Xchange offers two ways of storing the user-associated login/password combination. In cluster memory (default) or persisted to database. While the first way ensures that no user credentials are persisted nowhere in the Open-Xchange installation, it has the big disadvantage the stored credentials are gone once the last cluster members gets shut-down. Therefore there is also the possibility to store the credentials inside the database. Of course, no matter where the credentials are stored, they are encrypted using the value from com.openexchange.push.credstorage.passcrypt" property<br />
<br />
With setting the properties above the configuration on the Open-Xchange Middleware node is prepared to spawn permanent listeners.<br />
<br />
Now an appropriate push bundle/package needs to be installed that supports spawning permanent listeners. Currently Open-Xchange ships with three implementations:<br />
* open-xchange-push-dovecot (also requires the optional open-xchange-rest package)<br />
* open-xchange-push-imapidle (Not recommended, therefore disabled for IMAP-IDLE by default. com.openexchange.push.imapidle.supportsPermanentListeners=false)<br />
* open-xchange-push-mailnotify<br />
<br />
Putting all together the following execution flow is taken to decide whether permanent listeners are spawned or not:<br />
<br />
[[Image:ox_mail_push_configuration_2.png|500px]]<br />
<br />
To check at any time what listeners are currently running, there is a new command-line tool "/opt/open-xchange/sbin/listpushusers" that outputs the user-id/context-id pair along-side with the information if the listener is of permanent nature or bound to an active session:<br />
<br />
[[Image:ox_mail_push_configuration_3.png|500px]]<br />
<br />
An exemplary out put might look like:<br />
~# /opt/open-xchange/sbin/listpushusers<br />
user=249, context=1, permanent=true<br />
user=402, context=1, permanent=true<br />
<br />
== Setup of the Mobile Push ==<br />
An appropriate registration for a capable client is required to create a permanent listener for a certain user. As of now, only the Open-Xchange Mail App performs such a registration request to mark the user to have a permanent listener using the newly introduced Mobile Push interfaces of the Open-Xchange Middleware.<br />
The Mobile Push feature is installed by the following packages:<br />
* open-xchange-mobile-push-plugin<br />
* open-xchange-mobile-push-certificates (Only certificates and licenses)<br />
<br />
Simply said the main purpose of the Mobile Push functionality is to register an OSGi event handler converting an incoming OSGi event with topic "com/openexchange/push" to an appropriate native push reaching the mobile device using either<br />
* APN or<br />
* GCM<br />
<br />
=== Client subscription ===<br />
To be able to do so, the client has to perform a subscribe request against the Mobile Push interface. Such a subscribe call mainly performs two things<br />
<br />
1. Storing the data into the database that is needed to initiate a APN/GCM push request<br><br />
2. Registering & starting a permanent listener in the push framework<br><br />
<br />
=== Handling of OSGi events ===<br />
<br />
Moreover, the OSGi events with topic "com/openexchange/push" are spread remotely throughout the Open-Xchange cluster. To avoid that each node yields a native push event for the mobile device, the OSGi event handler of the Mobile Push does only consider local events. This fact implies that each node that broadcasts OSGi events with topic "com/openexchange/push" is required to have the open-xchange-mobile-push packages installed; otherwise the OSGi event is not handled.<br />
<br />
=== Mobile Push configuration ===<br />
The setup of the Mobile Push functionality includes proper configuration of the communication with the APN/GCM services, which is performed in file 'mobilepushevent.properties':<br />
* com.openxchange.mobilepush.events.gcm.enabled<br>General switch to enable/disable communication with GCM service<br />
* com.openxchange.mobilepush.events.gcm.key<br>Specifies the GCM key in order to authenticate against the GCM service and to forward push messages to that service. Required if "com.openxchange.mobilenotifier.events.gcm.enabled" is "true" and you want to use a different key than provided by open-xchange-mobile-push-certificates. Otherwise the key from open-xchange-mobile-push-certificates is used.<br />
* com.openxchange.mobilepush.events.apn.ios.enabled<br>General switch to enable/disable communication with APN service<br />
* com.openxchange.mobilepush.events.apn.ios.keystore<br>Specifies the path to the local keystore file (PKCS #12) containing the APNS certificate and keys for the iOS application. Required if "com.openxchange.mobilepush.events.apn.ios.enabled" is "true" and you want to use a different certificate than provided by open-xchange-mobile-push-certificates. Otherwise the certificate from open-xchange-mobile-push-certificates is used.<br />
* com.openxchange.mobilepush.events.apn.ios.password<br>Specifies the password used when creating the referenced keystore containing the certificate of the iOS application. Note that blank or null passwords are in violation of the PKCS #12 specifications. Required if "com.openxchange.mobilepush.events.apn.ios.enabled" is "true" and you want to use a different certificate than provided by open-xchange-mobile-push-certificates.<br />
<br />
= Setup of the Dovecot Push =<br />
<br />
== IMAP METADATA ==<br />
<br />
Dovecot Push plug-in requires METADATA support on Dovecot side, but it should only be enabled for OX IMAP sessions and not for any other IMAP clients directly. Enabling can be done with e.g. the remote directive "remote 1.2.3.0/24 { imap_metadata = yes }" and specifying the IP ranges of OX.<br />
<br />
Dovecot supports the [[https://tools.ietf.org/html/rfc5464|IMAP METADATA extension (RFC 5464)]], which allows per-mailbox, per-user data to be stored and accessed via IMAP commands.<br />
<br />
To activate metadata storage, a [[Dictionary|dictionary]] needs to be configured in the Dovecot configuration using the {{{mail_attribute_dict}}} option.<br />
<br />
To activate the IMAP METADATA commands, the imap_metadata and mail_attribute_dict options need to be activated.<br />
<br />
Example:<br />
<br />
<br />
# Store METADATA information within user's Maildir directory<br />
mail_attribute_dict = file:%h/Maildir/dovecot-attributes<br />
<br />
protocol imap {<br />
imap_metadata = yes<br />
}<br />
<br />
The following picture should demonstrate how the overall communication flow between Mail App, Open-Xchange Middleware, and the Dovecot Push plug-in takes place. That communication flow requires the "open-xchange-push-dovecot" and "open-xchange-rest" packages to be installed on the Open-Xchange Middleware nodes and the Dovecot "http-notify" plug-in.<br />
<br />
[[Image:ox_mail_push_configuration_4.png|500px]]<br />
<br />
Once the Open-Xchange Mail App is installed on the user’s mobile device and it is allowed to show notifications about a new message delivery, the Mail App performs a subscription call to the Open-Xchange Middleware Servers using a fully authenticated session.<br />
<br />
When the "open-xchange-push-dovecot" package is installed, the previous subscribe call requests it to spawn a permanent listener. Such a listener simply tells the Dovecot server to notify about new message delivery events for the associated user by executing a special SETMETADATA command. Hence, it does not open or use any resources other than firing a single IMAP command to the Dovecot IMAP Server.<br />
<br />
Whenever a "new message delivery" event occurs, the Dovecot Server performs a HTTP callback against a configurable HTTP end-point of the Open-Xchange Middleware providing crucial information about the newly delivered message with a simple JSON body. That incoming HTTP callback is then turned into an appropriate OSGi event with topic "com/openexchange/push".<br />
<br />
That event is in turn handled by the Mobile Push event handler, which uses the event’s information to request an APN/GCM push to the mobile device.<br />
<br />
== Configuration of Dovecot "http-notify" plug-in ==<br />
<br />
To use push notifications, both the "notify" and the "push_notification" plugins need to be activated. For LMTP delivery, this is required:<br />
<br />
protocol lmtp {<br />
mail_plugins = $mail_plugins notify push_notification<br />
}<br />
<br />
If you also want push notifications to work for LDA-based delivery, you would need additional configuration:<br />
<br />
protocol lda {<br />
mail_plugins = $mail_plugins notify push_notification<br />
}<br />
<br />
The HTTP end-point (URL + authentication information) to use is configured in the Dovecot configuration file. The appropriate configuration options will contain the HTTP URL denoting the end-point to connect to as well as the authentication information for Basic Authentication as configured by properties "com.openexchange.rest.services.basic-auth.login" and "com.openexchange.rest.services.basic-auth.password".<br />
The URL to configure in Dovecot configuration follows this pattern.<br />
<http|https> + "://" + <login> + ":" + <password> + "@" + <host> + ":" + <port> + "/preliminary/http-notify/v1/notify"<br />
<br />
E.g.<br />
plugin {<br />
push_notification_driver = ox:url=http://login:pass@node1.domain.tld:8009/preliminary/http-notify/v1/notify<br />
}<br />
<br />
Furthermore, it is also possible to specify more than one HTTP end-point to connect to if a new message delivery occurs. Thus the configuration section mentioned above may be extended by additional "push_notification_driver" entries; e.g. push_notification_driver2, push_notification_driver3, etc.<br />
<br />
Please note that the path "/preliminary/http-notify/v1/notify" denotes the internal REST API of the Open-Xchange Middleware, which is not publicly accessible. The administrator can decide whether to add that path to the Apache configuration (see also [[AppSuite:Apache_Configuration]] and [[AppSuite:Grizzly]]) through a Location/ProxyPass directive:<br />
<br />
<Location /preliminary><br />
Order Deny,Allow<br />
Deny from all<br />
# Only allow access from servers within the network. Do not expose this<br />
# location outside of your network. In case you use a load balancing service in front<br />
# of your Apache infrastructure you should make sure that access to /preliminary will<br />
# be blocked from the internet / outside clients. Examples:<br />
# Allow from 192.168.0.1<br />
# Allow from 192.168.1.1 192.168.1.2<br />
# Allow from 192.168.0.<br />
ProxyPass /preliminary balancer://oxcluster/preliminary<br />
</Location><br />
<br />
In case the "user=" sent by OX in the push_notification_driver url data does not match the IMAP login of a user, Dovecot ignores it. This can be overridden by defining "user_from_metadata" in the push_notification_driver url, e.g. <br />
<br />
push_notification_driver = ox:url=http://example.com/ user_from_metadata<br />
<br />
= Integrated Branding/Customization Concept for Partners and Customers =<br />
<br />
With OX Mail it is also possible for customers and partners to add branding elements to the app. During the installation of the app a user is presented with a list of preconfigured providers. When a provider is selected the app is automatically setup and branded for that provider.<br />
<br />
For both design reasons, as well as app store restrictions, branding in this context means:<br />
* The app design is “Super Flat”. This means there are not many elements that can be, or need to be, styled in order to match a particular brand.<br />
* The app does not contain or use any logos of any sort. <br />
* At install time the app uses a startup wizard in combination with a hosted configuration service. The wizard gives the end user the option to select a provider from a list. When this is done the app will retrieve the branding information from the configuration service and changes its theme accordingly. <br />
<br />
== Branding / Customization Process ==<br />
<br />
In order to participate you will need to provide specific information such as:<br />
<br />
* Confirmation that you are running OX App Suite 7.6.2 including the latest patch.<br />
* A full URL where your OX App Suite service can be reached by a web client.<br />
* Two test accounts on your OX App Suite service, where we can verify that the OX App Suite system works as expected.<br />
* A “logo” and “name” of your service. This information will be used in the app itself.<br />
* Optional: A preferred color (CI color) that Open-Xchange will use for the app if a user chooses their service from the provider list.<br />
<br />
=== Steps ===<br />
<br />
# Please download the Questionnaire from [http://knowledgebase.open-xchange.com/fileadmin/user_upload/open-xchange/document/misc/Questionnaire_OX_Mail_Branding.pdf Open-Xchange Download Server]<br />
# Please fill out the Questionnaire and send it to your Open-Xchange account manager.<br />
# Open-Xchange will check the data. If all information are available, Open-Xchange will add your personal brand to the live OX Mail app. Please Note: The exact date when your brand becomes available depends on the approval process and could take 5 to 10 days. Open-Xchange won't communicate an exact date. Please check by your self.<br />
<br />
[[Category: OX7]]<br />
[[Category: AppSuite]]<br />
[[Category: OXMailapp]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:OX_Mail&diff=22283AppSuite:OX Mail2016-08-10T08:05:49Z<p>Alexander.quast: /* Installation of the Clients */</p>
<hr />
<div>= OX Mail =<br />
<br />
OX Mail is a native mobile phone app built specifically for smartphone users who already have a valid OX App Suite account. The app is designed to let users access their OX App Suite email environment directly from a smartphone native client.<br />
<br />
OX Mail enables users to synchronize mails between a variety of smartphone devices and OX App Suite. OX Mail consists of two elements: The OX Mail component that is built into OX App Suite and the native OX Mail app.<br />
<br />
The OX Mail app has been designed specifically for ease-of-use and is available for both iOS and Android.<br />
<br />
'''Please Note: With this app Open-Xchange has also created a new branding concept for the customers and partners. More information can be found in the chapter [http://oxpedia.org/wiki/index.php?title=AppSuite:OX_Mail#Integrated_Branding.2FCustomization_Concept_for_Partners_and_Customers Branding/Customization Concept for Partners and Customers]'''<br />
<br />
== Requirements ==<br />
<br />
=== Server-side Installation and Configuration ===<br />
<br />
With OX Mail, OX App Suite supports server based PUSH functionality.<br />
<br />
Dovecot customers can use the special PUSH plugin without any additional costs. The plugin will be provided via the Dovecot software repository for Dovecot Pro and community edition. '''Please Note, the installation of the latest Dovecot v2.2.19 release is required'''<br />
<br />
'''Please Note: The Open-Xchange package 'open-xchange-push-imapidle' which provides mail push functionality by using the IMAP IDLE command to generate push events when new mail arrives, is not officially supported with OX Mail (app).'''<br />
<br />
If you are not using the Dovecot Push Plugin your mail backend has to actively notify the Open-Xchange middleware servers of new emails. This might require the creation of an additional OX middleware plugin to receive those notifications. For further details please contact your assigned pre-sales / prof. services contact.<br />
<br />
'''Please Note, the installation of the latest OX App Suite version is required.'''<br />
<br />
You will finde the client requirements under [[AppSuite:OX_System_Requirements#OX_Mail_for_Clients|OX Mail requirements]]<br />
<br />
== Key Benefits ==<br />
<br />
* Supports email PUSH notification for personal Inbox – emails show up immediately on the device<br />
* Quick and easy to set up with the start-up wizard<br />
* Intuitive, simple to use, design <br />
* Familiar smartphone experience<br />
* Available for both iOS and Android – download app from App Store for free<br />
<br />
A more detailed overview of OX Mail, can be found at: http://software.open-xchange.com/products/mail/doc/OX_Mail_Product_Guide.pdf<br />
<br />
== Pricing & Availability ==<br />
<br />
This email app is available for both iOS and Android and can be downloaded for free from the corresponding App Stores. Availability will be confirmed by Open-Xchange via the usual communication channels. <br />
<br />
'''Please note:''' The exact date when the clients become available depends on the approval process of the respective app stores. <br />
<br />
The Open-Xchange Middleware components can be downloaded from the respective download repositories as normal.<br />
<br />
Please contact your Open-Xchange account manager for further information and pricing details.<br />
<br />
= Enabling OX Mail =<br />
<br />
In order to support multi-tenancy/multi-brands systems the mail app functionality can be enabled or disabled per hostname. For this reason with version 1.4 the "mailapp-config.yml" property file was introduced:<br />
<br />
default:<br />
host: all<br />
mail_app_enabled: true<br />
<br />
# Override mail_app_enabled setting for certain hosts<br />
#myhost:<br />
# host: myexchange.myhost.mytld<br />
# mail_app_enabled: true <br />
<br />
One can for example disable the mail app feature for the default case and enable it for specific hosts. Wether a user is able to perform a login request within the mail app depends on the configured hostname of the mail app. If the configured hostname matches any hostname in the mailapp-config.yml which has mail_app_enabled set to true then the user is allowed to perform a login request.<br />
<br />
In addition OX Mail is only enabled for all users that have the capability ''com.openexchange.capability.mobile_mail_app'' <br />
<br />
More details about capabilities can be found at [[AppSuite:Capabilities]]. Furthermore, this capability can be defined in a more granular way using the Config Cascade as described at [[ConfigCascade]].<br />
<br />
IMPORTANT: <br />
By default, the capability for the OX Mail app is set to false for all users. It can be changed by editing the corresponding capability in the "permissions.properties" config file, or if you need a more fine grained selection of enabled users, you can use the well known provisioning tools / config cascade.<br />
<br />
= Installation of the Clients =<br />
<br />
The OX Mail is available via the different App Stores for iOS and Android:<br />
<br />
* [https://itunes.apple.com/us/app/ox-mail/id1008644994?l=de&ls=1&mt=8 OX Mail in Apple App Store]<br />
* [https://play.google.com/store/apps/details?id=com.openexchange.mobile.mailapp.enterprise OX Mail in GooglePlay]<br />
<br />
== Using your own middleware server ==<br />
<br />
If you are not listed on our provider list you may want to use your own middleware server by typing in the URI manually. Enter the path where your App Suite middleware instance is listening, i.e. https://gold.ox.io . The App will search for the typical API paths automatically based on your input. <br />
<br />
You can simply re-check where your App Suite middleware instance is listening by typing the full API path in a web browser, i.e. https://gold.ox.io/appsuite/api/. If you see a a "Not found" status page from Grizzly, the path is correct. A simple "404 not found" indicates the path is not correct. <br />
<br />
Please note: Do not enter the full API path in the App, just the base URL like https://gold.ox.io. Also you will need a valid and fully trusted SSL certificate on the webserver, otherwise the App will refuse to connect.<br />
<br />
= OX Mail Server-side Installation and Configuration on OX App Suite v7.8.x =<br />
<br />
This chapter describes how the backend components of OX Mail are installed and configured on the server.<br />
<br />
== Available packages ==<br />
<br />
OX Mail is available with the following backend packages:<br />
<br />
* ''open-xchange-mobile-push-certificates'' - Certificates for cloud-based push notifications<br />
* ''open-xchange-mailapp-backend'' - The main server components for OX Mail<br />
* ''open-xchange-mobile-push-plugin'' - Provides Push functionality<br />
<br />
Installation on the server varies depending on the underlying distribution, details are available in the following chapters.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ yum install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 7.0 (Wheezy) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 8.0 (Jessie) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianJessie|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=debianname|pc2v=DebianJessie|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|backend/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=susename|pc2v=SLES11|mail|mailapp}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== SUSE Linux Enterprise Server 12 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLE_12|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|backend/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=susename|pc2v=SLE_12|mail|mailapp}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
= OX Mail Server-side Installation and Configuration on OX App Suite v7.6.2 =<br />
<br />
This chapter describes how the backend components of OX Mail are installed and configured on the server.<br />
<br />
== Enforced SSL connection on iOS clients ==<br />
<br />
With iOS 9 Apple introduced ATS (App Transport Security) which by default blocks all unencrypted network connections for Apps using http. To enable OX Mail for iOS on your server you will need to provide a valid SSL certificate for your system, otherwise the iOS client will refuse to connect to your system. Using a unencrypted http connection will not work.<br />
<br />
You can simply test if your certificate is valid by visiting your webserver with iOS Safari. If the browser accepts your https connection without showing any warning, your certificate is trusted by the system and OX Mail will also work.<br />
<br />
== Available packages ==<br />
<br />
OX Mail is available with the following backend packages:<br />
<br />
* ''open-xchange-mobile-push-certificates'' - Certificates for cloud-based push notifications<br />
* ''open-xchange-mailapp-backend'' - The main server components for OX Mail<br />
* ''open-xchange-mobile-push-plugin'' - Provides Push functionality<br />
<br />
Installation on the server varies depending on the underlying distribution, details are available in the following chapters.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ yum install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 6.0 (Squeeze) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=debianname|pc2v=DebianSqueeze|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=debianname|pc2v=DebianSqueeze|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 7.0 (Wheezy) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=debianname|pc2v=DebianWheezy|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|backend/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=susename|pc2v=SLES11|mail|mailapp}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
= Setup Description for Mobile Push =<br />
<br />
== Setup of the Open-Xchange Node==<br />
<br />
The existing push framework of the Open-Xchange Middleware has been extended by the capability to spawn "permanent" listeners for incoming new message deliveries. Up to that point the life cycle for a listener was bound to at least one active session, which is associated with a client that is allowed to receive push notifications.<br />
<br />
With introduction of the previously mentioned capability, listeners can be started without the need for an existent session right on the start of an Open-Xchange Middleware node. In addition those permanent listeners are spread approximately even over capable cluster members as - dependent on the underlying implementation - a listener representation may open/hold resources (socket connections) in order to receive notifications about new message deliveries.<br />
<br />
To prepare a certain Open-Xchange Middleware node to spawn permanent push listeners the following properties need to be configured in file '/opt/open-xchange/etc/mail-push.properties':<br />
<br />
* com.openexchange.push.allowPermanentPush<br>This is the general switch to enable/disable support for permanent listeners on a node. Thus needs to be set to "true"<br />
* com.openexchange.push.allowedClient<br>Specify the comma-separated list of clients which are allowed to receive notifications about new mails, “open-xchange-mailapp” should be added here if you plan to use it in combination with the new mobile-push feature.<br />
* com.openexchange.push.credstorage.enabled<br>As permanent listeners are required to run without an active session, the credential storage can be used to store user credentials in installations that do not support a master authentication to the mail storage Hence, if the property "com.openexchange.mail.passwordSource" (mail.properties) is not set to "global" this property is required to be set to "true"<br />
* com.openexchange.push.credstorage.passcrypt<br>This property is required if "com.openexchange.push.credstorage.enabled" is set to "true". It does specify the passphrase to use to symmetrically encrypt the stored credentials. The passphrase is required to be equal on each cluster member.<br />
* com.openexchange.push.credstorage.rdb<br>Once the credential storage is enabled, Open-Xchange offers two ways of storing the user-associated login/password combination. In cluster memory (default) or persisted to database. While the first way ensures that no user credentials are persisted nowhere in the Open-Xchange installation, it has the big disadvantage the stored credentials are gone once the last cluster members gets shut-down. Therefore there is also the possibility to store the credentials inside the database. Of course, no matter where the credentials are stored, they are encrypted using the value from com.openexchange.push.credstorage.passcrypt" property<br />
<br />
With setting the properties above the configuration on the Open-Xchange Middleware node is prepared to spawn permanent listeners.<br />
<br />
Now an appropriate push bundle/package needs to be installed that supports spawning permanent listeners. Currently Open-Xchange ships with three implementations:<br />
* open-xchange-push-dovecot (also requires the optional open-xchange-rest package)<br />
* open-xchange-push-imapidle (Not recommended, therefore disabled for IMAP-IDLE by default. com.openexchange.push.imapidle.supportsPermanentListeners=false)<br />
* open-xchange-push-mailnotify<br />
<br />
Putting all together the following execution flow is taken to decide whether permanent listeners are spawned or not:<br />
<br />
[[Image:ox_mail_push_configuration_2.png|500px]]<br />
<br />
To check at any time what listeners are currently running, there is a new command-line tool "/opt/open-xchange/sbin/listpushusers" that outputs the user-id/context-id pair along-side with the information if the listener is of permanent nature or bound to an active session:<br />
<br />
[[Image:ox_mail_push_configuration_3.png|500px]]<br />
<br />
An exemplary out put might look like:<br />
~# /opt/open-xchange/sbin/listpushusers<br />
user=249, context=1, permanent=true<br />
user=402, context=1, permanent=true<br />
<br />
== Setup of the Mobile Push ==<br />
An appropriate registration for a capable client is required to create a permanent listener for a certain user. As of now, only the Open-Xchange Mail App performs such a registration request to mark the user to have a permanent listener using the newly introduced Mobile Push interfaces of the Open-Xchange Middleware.<br />
The Mobile Push feature is installed by the following packages:<br />
* open-xchange-mobile-push-plugin<br />
* open-xchange-mobile-push-certificates (Only certificates and licenses)<br />
<br />
Simply said the main purpose of the Mobile Push functionality is to register an OSGi event handler converting an incoming OSGi event with topic "com/openexchange/push" to an appropriate native push reaching the mobile device using either<br />
* APN or<br />
* GCM<br />
<br />
=== Client subscription ===<br />
To be able to do so, the client has to perform a subscribe request against the Mobile Push interface. Such a subscribe call mainly performs two things<br />
<br />
1. Storing the data into the database that is needed to initiate a APN/GCM push request<br><br />
2. Registering & starting a permanent listener in the push framework<br><br />
<br />
=== Handling of OSGi events ===<br />
<br />
Moreover, the OSGi events with topic "com/openexchange/push" are spread remotely throughout the Open-Xchange cluster. To avoid that each node yields a native push event for the mobile device, the OSGi event handler of the Mobile Push does only consider local events. This fact implies that each node that broadcasts OSGi events with topic "com/openexchange/push" is required to have the open-xchange-mobile-push packages installed; otherwise the OSGi event is not handled.<br />
<br />
=== Mobile Push configuration ===<br />
The setup of the Mobile Push functionality includes proper configuration of the communication with the APN/GCM services, which is performed in file 'mobilepushevent.properties':<br />
* com.openxchange.mobilepush.events.gcm.enabled<br>General switch to enable/disable communication with GCM service<br />
* com.openxchange.mobilepush.events.gcm.key<br>Specifies the GCM key in order to authenticate against the GCM service and to forward push messages to that service. Required if "com.openxchange.mobilenotifier.events.gcm.enabled" is "true" and you want to use a different key than provided by open-xchange-mobile-push-certificates. Otherwise the key from open-xchange-mobile-push-certificates is used.<br />
* com.openxchange.mobilepush.events.apn.ios.enabled<br>General switch to enable/disable communication with APN service<br />
* com.openxchange.mobilepush.events.apn.ios.keystore<br>Specifies the path to the local keystore file (PKCS #12) containing the APNS certificate and keys for the iOS application. Required if "com.openxchange.mobilepush.events.apn.ios.enabled" is "true" and you want to use a different certificate than provided by open-xchange-mobile-push-certificates. Otherwise the certificate from open-xchange-mobile-push-certificates is used.<br />
* com.openxchange.mobilepush.events.apn.ios.password<br>Specifies the password used when creating the referenced keystore containing the certificate of the iOS application. Note that blank or null passwords are in violation of the PKCS #12 specifications. Required if "com.openxchange.mobilepush.events.apn.ios.enabled" is "true" and you want to use a different certificate than provided by open-xchange-mobile-push-certificates.<br />
<br />
= Setup of the Dovecot Push =<br />
<br />
== IMAP METADATA ==<br />
<br />
Dovecot Push plug-in requires METADATA support on Dovecot side, but it should only be enabled for OX IMAP sessions and not for any other IMAP clients directly. Enabling can be done with e.g. the remote directive "remote 1.2.3.0/24 { imap_metadata = yes }" and specifying the IP ranges of OX.<br />
<br />
Dovecot supports the [[https://tools.ietf.org/html/rfc5464|IMAP METADATA extension (RFC 5464)]], which allows per-mailbox, per-user data to be stored and accessed via IMAP commands.<br />
<br />
To activate metadata storage, a [[Dictionary|dictionary]] needs to be configured in the Dovecot configuration using the {{{mail_attribute_dict}}} option.<br />
<br />
To activate the IMAP METADATA commands, the imap_metadata and mail_attribute_dict options need to be activated.<br />
<br />
Example:<br />
<br />
<br />
# Store METADATA information within user's Maildir directory<br />
mail_attribute_dict = file:%h/Maildir/dovecot-attributes<br />
<br />
protocol imap {<br />
imap_metadata = yes<br />
}<br />
<br />
The following picture should demonstrate how the overall communication flow between Mail App, Open-Xchange Middleware, and the Dovecot Push plug-in takes place. That communication flow requires the "open-xchange-push-dovecot" and "open-xchange-rest" packages to be installed on the Open-Xchange Middleware nodes and the Dovecot "http-notify" plug-in.<br />
<br />
[[Image:ox_mail_push_configuration_4.png|500px]]<br />
<br />
Once the Open-Xchange Mail App is installed on the user’s mobile device and it is allowed to show notifications about a new message delivery, the Mail App performs a subscription call to the Open-Xchange Middleware Servers using a fully authenticated session.<br />
<br />
When the "open-xchange-push-dovecot" package is installed, the previous subscribe call requests it to spawn a permanent listener. Such a listener simply tells the Dovecot server to notify about new message delivery events for the associated user by executing a special SETMETADATA command. Hence, it does not open or use any resources other than firing a single IMAP command to the Dovecot IMAP Server.<br />
<br />
Whenever a "new message delivery" event occurs, the Dovecot Server performs a HTTP callback against a configurable HTTP end-point of the Open-Xchange Middleware providing crucial information about the newly delivered message with a simple JSON body. That incoming HTTP callback is then turned into an appropriate OSGi event with topic "com/openexchange/push".<br />
<br />
That event is in turn handled by the Mobile Push event handler, which uses the event’s information to request an APN/GCM push to the mobile device.<br />
<br />
== Configuration of Dovecot "http-notify" plug-in ==<br />
<br />
To use push notifications, both the "notify" and the "push_notification" plugins need to be activated. For LMTP delivery, this is required:<br />
<br />
protocol lmtp {<br />
mail_plugins = $mail_plugins notify push_notification<br />
}<br />
<br />
If you also want push notifications to work for LDA-based delivery, you would need additional configuration:<br />
<br />
protocol lda {<br />
mail_plugins = $mail_plugins notify push_notification<br />
}<br />
<br />
The HTTP end-point (URL + authentication information) to use is configured in the Dovecot configuration file. The appropriate configuration options will contain the HTTP URL denoting the end-point to connect to as well as the authentication information for Basic Authentication as configured by properties "com.openexchange.rest.services.basic-auth.login" and "com.openexchange.rest.services.basic-auth.password".<br />
The URL to configure in Dovecot configuration follows this pattern.<br />
<http|https> + "://" + <login> + ":" + <password> + "@" + <host> + ":" + <port> + "/preliminary/http-notify/v1/notify"<br />
<br />
E.g.<br />
plugin {<br />
push_notification_driver = ox:url=http://login:pass@node1.domain.tld:8009/preliminary/http-notify/v1/notify<br />
}<br />
<br />
Furthermore, it is also possible to specify more than one HTTP end-point to connect to if a new message delivery occurs. Thus the configuration section mentioned above may be extended by additional "push_notification_driver" entries; e.g. push_notification_driver2, push_notification_driver3, etc.<br />
<br />
Please note that the path "/preliminary/http-notify/v1/notify" denotes the internal REST API of the Open-Xchange Middleware, which is not publicly accessible. The administrator can decide whether to add that path to the Apache configuration (see also [[AppSuite:Apache_Configuration]] and [[AppSuite:Grizzly]]) through a Location/ProxyPass directive:<br />
<br />
<Location /preliminary><br />
Order Deny,Allow<br />
Deny from all<br />
# Only allow access from servers within the network. Do not expose this<br />
# location outside of your network. In case you use a load balancing service in front<br />
# of your Apache infrastructure you should make sure that access to /preliminary will<br />
# be blocked from the internet / outside clients. Examples:<br />
# Allow from 192.168.0.1<br />
# Allow from 192.168.1.1 192.168.1.2<br />
# Allow from 192.168.0.<br />
ProxyPass /preliminary balancer://oxcluster/preliminary<br />
</Location><br />
<br />
In case the "user=" sent by OX in the push_notification_driver url data does not match the IMAP login of a user, Dovecot ignores it. This can be overridden by defining "user_from_metadata" in the push_notification_driver url, e.g. <br />
<br />
push_notification_driver = ox:url=http://example.com/ user_from_metadata<br />
<br />
= Integrated Branding/Customization Concept for Partners and Customers =<br />
<br />
With OX Mail it is also possible for customers and partners to add branding elements to the app. During the installation of the app a user is presented with a list of preconfigured providers. When a provider is selected the app is automatically setup and branded for that provider.<br />
<br />
For both design reasons, as well as app store restrictions, branding in this context means:<br />
* The app design is “Super Flat”. This means there are not many elements that can be, or need to be, styled in order to match a particular brand.<br />
* The app does not contain or use any logos of any sort. <br />
* At install time the app uses a startup wizard in combination with a hosted configuration service. The wizard gives the end user the option to select a provider from a list. When this is done the app will retrieve the branding information from the configuration service and changes its theme accordingly. <br />
<br />
== Branding / Customization Process ==<br />
<br />
In order to participate you will need to provide specific information such as:<br />
<br />
* Confirmation that you are running OX App Suite 7.6.2 including the latest patch.<br />
* A full URL where your OX App Suite service can be reached by a web client.<br />
* Two test accounts on your OX App Suite service, where we can verify that the OX App Suite system works as expected.<br />
* A “logo” and “name” of your service. This information will be used in the app itself.<br />
* Optional: A preferred color (CI color) that Open-Xchange will use for the app if a user chooses their service from the provider list.<br />
<br />
=== Steps ===<br />
<br />
# Please download the Questionnaire from [http://knowledgebase.open-xchange.com/fileadmin/user_upload/open-xchange/document/misc/Questionnaire_OX_Mail_Branding.pdf Open-Xchange Download Server]<br />
# Please fill out the Questionnaire and send it to your Open-Xchange account manager.<br />
# Open-Xchange will check the data. If all information are available, Open-Xchange will add your personal brand to the live OX Mail app. Please Note: The exact date when your brand becomes available depends on the approval process and could take 5 to 10 days. Open-Xchange won't communicate an exact date. Please check by your self.<br />
<br />
[[Category: OX7]]<br />
[[Category: AppSuite]]<br />
[[Category: OXMailapp]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=21933AppSuite:Theming2016-05-19T08:48:27Z<p>Alexander.quast: /* Mobile and retina screens */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>/opt/open-xchange/appsuite/apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
Variables are defined in variables.less from twitter-bootstrap and our default definitions.less. Variables that are defined in definitions.less always override variables from bootstrap's variables.less<br />
<br />
=== Most relevant variables ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @topbar-background || @topbarBackground || #3774A8 (blue)<br />
|-<br />
| --- || @topbarBackgroundAlt || No longer used<br />
|-<br />
| @topbar-launcher-color || @topbarLauncherColor || rgba(255, 255, 255, 0.70)<br />
|-<br />
| @topbar-launcher-color-hover || @topbarLauncherColor-hover || #fff<br />
|-<br />
| @topbar-launcher-color-active || @topbarLauncherColorActive || #fff<br />
|-<br />
| @topbar-launcher-background-hover || @topbarLauncherBackgroundHover || rgba(0, 0, 0, 0.30)<br />
|-<br />
| @topbar-launcher-background-active || @topbarLauncherBackgroundActive || rgba(0, 0, 0, 0.20);<br />
|-<br />
| @topbar-icon-color || @topbarIconColor || #fff<br />
|-<br />
| @selected-background || @selectedBackground || #428BCA (blue)<br />
|-<br />
| @contact-picture-radius || @contactPictureRadius || 50%<br />
|-<br />
|}<br />
:<br />
<br />
<br />
The most significant visual change is achieved by changing the following variables:<br />
* '''@topbar-background''' (top navigation bar)<br />
* '''@selected-background''' (selection background color in list views and folder tree)<br />
* '''@link-color''' (almost all hyperlinks)<br />
<br />
=== Font ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @font-family-sans-serif || @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @font-family-serif || @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @font-family-monospace || @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @font-size-base || @baseFontSize || 14px<br />
|-<br />
| || @baseFontFamily ||<br />
|-<br />
| @line-height-base || @baseLineHeight || 1.428571429; // 20/14<br />
|-<br />
| || @altFontFamily ||<br />
|-<br />
| @font-size-touch || @touchFontSize || 15px<br />
|-<br />
| @headings-font-family || @headingsFontFamily || inherit<br />
|-<br />
| @headings-font-weight || @headingsFontWeight || 500<br />
|-<br />
| @font-size-large || @fontSizeLarge || ceil((@font-size-base * 1.25)); // ~18px<br />
|-<br />
| @font-size-small || @fontSizeSmall || ceil((@font-size-base * 0.85)); // ~12px<br />
|-<br />
| || @fontSizeMini ||<br />
|-<br />
| @vgrid-font-size || @vgridFontSize || 13px<br />
|}<br />
<br />
=== Colors ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @background || @bodyBackground || #fff<br />
|-<br />
| @text-color || @textColor || @gray-dark<br />
|-<br />
| @link-color || @linkColor || @brand-primary<br />
|-<br />
| @link-hover-color || @linkColorHover || darken(@link-color, 15%)<br />
|-<br />
| @link-accent-color || @linkAccentColor || #ffad00<br />
|-<br />
| || @linkAccentColorHover ||<br />
|-<br />
| @badge-color || @badgeColor || @white<br />
|-<br />
| @badge-bg || @badgeBackground || #aaa<br />
|-<br />
| @headings-color || @headingsColor || inherit<br />
|-<br />
| @black || @black || #000<br />
|-<br />
| @gray-darker || @grayDarker || #222<br />
|-<br />
| @gray-dark || @grayDark || #333<br />
|-<br />
| @gray || @gray || #555<br />
|-<br />
| @gray-light || @grayLight || #999<br />
|-<br />
| @gray-lighter || @grayLighter || #eee<br />
|-<br />
| @white || @white || #fff<br />
|-<br />
| @blue || @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blue-dark || @blueDark || #0064cd<br />
|-<br />
| @blue-light || @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || @green || #1A8D1A<br />
|-<br />
| @green-light || @greenLight || #92D050<br />
|-<br />
| @red || @red || #cc0000<br />
|-<br />
| @yellow || @yellow || #F8E400<br />
|-<br />
| @orange || @orange || #f89406<br />
|-<br />
| @pink || @pink || #E01CD9<br />
|-<br />
| @purple || @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
=== Space ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| || @paddingLarge ||<br />
|-<br />
| || @paddingSmall ||<br />
|-<br />
| || @paddingMini ||<br />
|-<br />
| @border-radius-base || @baseBorderRadius || 4px<br />
|-<br />
| @border-radius-large || @borderRadiusLarge || 6px<br />
|-<br />
| @border-radius-small || @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @pagination-bg || @paginationBackground || #fff<br />
|-<br />
| @pagination-border || @paginationBorder || #ddd<br />
|-<br />
| @pagination-active-bg || @paginationActiveBackground || @brand-primary<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| || @btnBackground ||<br />
|-<br />
| || @btnBackgroundHighlight ||<br />
|-<br />
| || @btnBorder ||<br />
|-<br />
| @btn-primary-bg || @btnPrimaryBackground || @link-color<br />
|-<br />
| || @btnPrimaryBackgroundHighlight ||<br />
|-<br />
| @btn-info-bg || @btnInfoBackground || #5bc0de<br />
|-<br />
| || @btnInfoBackgroundHighlight ||<br />
|-<br />
| @btn-success-bg || @btnSuccessBackground || #62c462<br />
|-<br />
| || @btnSuccessBackgroundHighlight ||<br />
|-<br />
| @btn-warning-bg || @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| || @btnWarningBackgroundHighlight ||<br />
|-<br />
| @btn-danger-bg || @btnDangerBackground || #ee5f5b<br />
|-<br />
| || @btnDangerBackgroundHighlight ||<br />
|-<br />
| @btn-inverse-bg || @btnInverseBackground || #444<br />
|-<br />
| || @btnInverseBackgroundHighlight ||<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @dropdown-bg || @dropdownBackground || #fff<br />
|-<br />
| @dropdown-border || @dropdownBorder || rgba(0,0,0,.15)<br />
|-<br />
| @dropdown-divider-bg || @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdown-divider-bg || @dropdownDividerBottom || #e5e5e5<br />
|-<br />
| @dropdown-link-color || @dropdownLinkColor || @gray-dark<br />
|-<br />
| @dropdown-link-hover-color || @dropdownLinkColorHover || darken(@gray-dark, 5%)<br />
|-<br />
| @dropdown-link-active-color || @dropdownLinkColorActive || @component-active-color<br />
|-<br />
| @dropdown-link-active-bg || @dropdownLinkBackgroundActive || @component-active-bg<br />
|-<br />
| @dropdown-link-hover-bg || @dropdownLinkBackgroundHover || #f5f5f5<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @foldertree-sidepane-background || @foldertreeSidepanelBackground || #f5f5f5 ||<br />
|-<br />
| @foldertee-section-title-color || @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertree-active-label-color || @foldertreeActiveLabelColor || #333 || ''Active'' means, user can perform an action on this item<br />
|-<br />
|@foldertree-passive-label-color || @foldertreePassiveLabelColor ||@hc-gray || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertree-hover-background || @foldertreeHoverBackground || rgba(0, 0, 0, 0.05) ||<br />
|-<br />
| @foldertree-selected-background || @foldertreeSelectedBackground || rgba(0, 0, 0, 0.10) ||<br />
|-<br />
| @foldertree-badge-background || @foldertreeBadgeBackground || @bagde-bg || see [[#Colors]] for definition of @badge-bg<br />
|-<br />
| @foldertree-badge-color || @foldertreeBadgeColor ||@badge-color || see [[#Colors]] for definition of @badge-color<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @appointment-reserved || @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointment-temporary || @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointment-absent || @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointment-free || @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointment-private || @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointment-declined-font || @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointment-unconfirmed-alpha || @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointment-declined-alpha || @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointment-hover-pct || @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @weekview-appointment-lasso || @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekview-day-in || @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekview-day-out || @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekview-timeline || @weekviewTimeline || rgba(243, 15, 170, 0.4) || Color of the Line indicating the current time<br />
|-<br />
| @weekview-time-width || @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendar-toolbar-height || @calendarToolbarHeight || 47px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @monthview-appointment-out || @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthview-today || @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| || @monthview@calendarToolbarHeight || ||<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(path/to/mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. Reference the entire path to the file, relative to the folder containing your ui, but without the leading slash. For example, the Core reference would be <code>apps/themes/default/logo-small.png</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
=== Mobile and retina screens ===<br />
<br />
Almost any mobile device and some newer desktop devices use retina screens. These screens do have a very high pixel density which offer very sharp text rendering. To offer sharp and correctly sized images on retina screens there is and additional CSS directive encapsulated in a media query which must be set in your custom theme.<br />
<br />
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),<br />
only screen and (-moz-min-device-pixel-ratio: 1.5),<br />
only screen and (min-device-pixel-ratio: 1.5),<br />
only screen and (min-resolution: 240dppx) {<br />
#io-ox-top-logo-small {<br />
background-size: 60px 22px;<br />
background-image: url('apps/themes/default/logo-large.png');<br />
}<br />
}<br />
<br />
'''It is important that you provide your brand logo in two sizes''', the standard size of 60x22px and a large version with doubled pixel sizes of 120x44px. All retina devices will use the large logo and scale it down the CSS pixel size of 60x22px. This will result in a sharp image as the retina screen can make use of the additional available pixels in the source image.<br />
<br />
'''Important note''': Your logo must not be wider than 70px (including margins) for mobile devices. Otherwise the toolbar will be broken on mobile devices as the large logo will cause a line wrap in the toolbar. If you need a larger logo use a custom, smaller one for mobiles. <br />
<br />
Always test your theme on mobiles, too. You can emulate popular screen sizes with the Google Chrome Dev-Tools.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
'''This documentation applies for AppSuite v.7.4.2'''<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers as long as you don't deliver your own icons with your theme. To provide your own icons, put them into your theme's directory, e.g. <tt>apps/themes/<var>theme-name</var>/favicon.ico</tt>.<br />
<br />
=== Favicon ===<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
You should provide your custom favicon within your custom theme. If you do not add a custom favicon to your theme the global OX default will be used. The default icon is located under <tt>apps/themes/icons/default</tt> on the web server.<br />
<br />
'''Attention:''' Safari and Internet Explorer do not support dynamic changes to the favicon for a webpage. This means, the default icon will be shown even if a custom favicon is provided within a custom theme. To enable the right favicon for a theme on Safari and IE, the overall standard <tt>favicon.ico</tt> located under <tt>apps/themes/icons/default</tt> on the web server must be replaced with a custom version.<br />
<br />
=== Apple touch icons ===<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. AppSuite offers full support for Webclips by providing all needed App icons, splashscreens and full screen support. If a user uses the "Add to homescreen" button on his iOS device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format.<br />
<br />
* iPhone 3: 57 x 57 px<br />
* iPhone 4 retina: 114x114 px<br />
* iPhone iPhone 5 retina: 120 x 120 px<br />
* iPad: 72 x 72 px<br />
* iPad (iOS 7): 76 x 76px<br />
* iPad retina: 144 x 144 px <br />
* iPad retina (iOS 7): 152 x 152 px <br />
<br />
Furthermore a fullscreen Webclip App will show a splashscreen, a jpg file that is displayed on startup during app load. There are currently three different resolutions as jpg files available. '''Note''': Splashscreens must be JPG files<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change with Apple's iOS updates. We recommend providing all of this resolutions when customizing the Webclip icons and splashscreens, even if some iOS devices use the next best resolution for an icon if a certain file is missing.<br />
<br />
=== Providing custom icons ===<br />
To provide custom Webclip icons locate the following path in the AppSuite installation on your web server:<br />
pathToAppSuite/apps/themes/icons/default<br />
<br />
This folder contains all OX default icons for Webclips icons and splashscreens. Use these as samples for your own versions.<br />
<br />
A clean installation will have all our default icons in the "default" directory. To customize the icons we recommend using our default icons as samples and save your customized version in your theme. '''Note''': The filename has to be the same as in the default folder. Otherwise the fallback will be applied and the default icons will be used. If more advanced rewriting is needed one should edit the contents of the <tt>.htaccess</tt> file located under <tt>apps/themes</tt><br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
=== Providing domain based login themes ===<br />
<br />
This is only needed when using the default login screen shipped with the Core UI and for versions older than the 7.8.0 release. Since 7.8.0, the normal way via as-config.yml will work just fine ([[AppSuite:Theming the login page|Learn how to do this here]]).<br />
<br />
If you have a multibrand installation and you want to deliver not only custom themes but also custom login-themes this can be done via Apache mod_rewrite. You can do so by a domain-based rewrite rule to deliver custom themes to a user based on the URI he's using. The needed config file <tt>.htaccess</tt> is located under <tt>apps/themes</tt><br />
<br />
<pre><br />
# Sample config for domain based login theme<br />
RewriteCond %{HTTP_HOST} ^www\.domain\.com$<br />
RewriteCond %{REQUEST_FILENAME} -f<br />
RewriteRule ^login/(.*)$ domain_com_logintheme/$1 [L]<br />
</pre><br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]<br />
[[Category:Custom development]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=21932AppSuite:Theming2016-05-19T08:47:01Z<p>Alexander.quast: /* Mobile and retina screens */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>/opt/open-xchange/appsuite/apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
Variables are defined in variables.less from twitter-bootstrap and our default definitions.less. Variables that are defined in definitions.less always override variables from bootstrap's variables.less<br />
<br />
=== Most relevant variables ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @topbar-background || @topbarBackground || #3774A8 (blue)<br />
|-<br />
| --- || @topbarBackgroundAlt || No longer used<br />
|-<br />
| @topbar-launcher-color || @topbarLauncherColor || rgba(255, 255, 255, 0.70)<br />
|-<br />
| @topbar-launcher-color-hover || @topbarLauncherColor-hover || #fff<br />
|-<br />
| @topbar-launcher-color-active || @topbarLauncherColorActive || #fff<br />
|-<br />
| @topbar-launcher-background-hover || @topbarLauncherBackgroundHover || rgba(0, 0, 0, 0.30)<br />
|-<br />
| @topbar-launcher-background-active || @topbarLauncherBackgroundActive || rgba(0, 0, 0, 0.20);<br />
|-<br />
| @topbar-icon-color || @topbarIconColor || #fff<br />
|-<br />
| @selected-background || @selectedBackground || #428BCA (blue)<br />
|-<br />
| @contact-picture-radius || @contactPictureRadius || 50%<br />
|-<br />
|}<br />
:<br />
<br />
<br />
The most significant visual change is achieved by changing the following variables:<br />
* '''@topbar-background''' (top navigation bar)<br />
* '''@selected-background''' (selection background color in list views and folder tree)<br />
* '''@link-color''' (almost all hyperlinks)<br />
<br />
=== Font ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @font-family-sans-serif || @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @font-family-serif || @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @font-family-monospace || @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @font-size-base || @baseFontSize || 14px<br />
|-<br />
| || @baseFontFamily ||<br />
|-<br />
| @line-height-base || @baseLineHeight || 1.428571429; // 20/14<br />
|-<br />
| || @altFontFamily ||<br />
|-<br />
| @font-size-touch || @touchFontSize || 15px<br />
|-<br />
| @headings-font-family || @headingsFontFamily || inherit<br />
|-<br />
| @headings-font-weight || @headingsFontWeight || 500<br />
|-<br />
| @font-size-large || @fontSizeLarge || ceil((@font-size-base * 1.25)); // ~18px<br />
|-<br />
| @font-size-small || @fontSizeSmall || ceil((@font-size-base * 0.85)); // ~12px<br />
|-<br />
| || @fontSizeMini ||<br />
|-<br />
| @vgrid-font-size || @vgridFontSize || 13px<br />
|}<br />
<br />
=== Colors ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @background || @bodyBackground || #fff<br />
|-<br />
| @text-color || @textColor || @gray-dark<br />
|-<br />
| @link-color || @linkColor || @brand-primary<br />
|-<br />
| @link-hover-color || @linkColorHover || darken(@link-color, 15%)<br />
|-<br />
| @link-accent-color || @linkAccentColor || #ffad00<br />
|-<br />
| || @linkAccentColorHover ||<br />
|-<br />
| @badge-color || @badgeColor || @white<br />
|-<br />
| @badge-bg || @badgeBackground || #aaa<br />
|-<br />
| @headings-color || @headingsColor || inherit<br />
|-<br />
| @black || @black || #000<br />
|-<br />
| @gray-darker || @grayDarker || #222<br />
|-<br />
| @gray-dark || @grayDark || #333<br />
|-<br />
| @gray || @gray || #555<br />
|-<br />
| @gray-light || @grayLight || #999<br />
|-<br />
| @gray-lighter || @grayLighter || #eee<br />
|-<br />
| @white || @white || #fff<br />
|-<br />
| @blue || @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blue-dark || @blueDark || #0064cd<br />
|-<br />
| @blue-light || @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || @green || #1A8D1A<br />
|-<br />
| @green-light || @greenLight || #92D050<br />
|-<br />
| @red || @red || #cc0000<br />
|-<br />
| @yellow || @yellow || #F8E400<br />
|-<br />
| @orange || @orange || #f89406<br />
|-<br />
| @pink || @pink || #E01CD9<br />
|-<br />
| @purple || @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
=== Space ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| || @paddingLarge ||<br />
|-<br />
| || @paddingSmall ||<br />
|-<br />
| || @paddingMini ||<br />
|-<br />
| @border-radius-base || @baseBorderRadius || 4px<br />
|-<br />
| @border-radius-large || @borderRadiusLarge || 6px<br />
|-<br />
| @border-radius-small || @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @pagination-bg || @paginationBackground || #fff<br />
|-<br />
| @pagination-border || @paginationBorder || #ddd<br />
|-<br />
| @pagination-active-bg || @paginationActiveBackground || @brand-primary<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| || @btnBackground ||<br />
|-<br />
| || @btnBackgroundHighlight ||<br />
|-<br />
| || @btnBorder ||<br />
|-<br />
| @btn-primary-bg || @btnPrimaryBackground || @link-color<br />
|-<br />
| || @btnPrimaryBackgroundHighlight ||<br />
|-<br />
| @btn-info-bg || @btnInfoBackground || #5bc0de<br />
|-<br />
| || @btnInfoBackgroundHighlight ||<br />
|-<br />
| @btn-success-bg || @btnSuccessBackground || #62c462<br />
|-<br />
| || @btnSuccessBackgroundHighlight ||<br />
|-<br />
| @btn-warning-bg || @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| || @btnWarningBackgroundHighlight ||<br />
|-<br />
| @btn-danger-bg || @btnDangerBackground || #ee5f5b<br />
|-<br />
| || @btnDangerBackgroundHighlight ||<br />
|-<br />
| @btn-inverse-bg || @btnInverseBackground || #444<br />
|-<br />
| || @btnInverseBackgroundHighlight ||<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @dropdown-bg || @dropdownBackground || #fff<br />
|-<br />
| @dropdown-border || @dropdownBorder || rgba(0,0,0,.15)<br />
|-<br />
| @dropdown-divider-bg || @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdown-divider-bg || @dropdownDividerBottom || #e5e5e5<br />
|-<br />
| @dropdown-link-color || @dropdownLinkColor || @gray-dark<br />
|-<br />
| @dropdown-link-hover-color || @dropdownLinkColorHover || darken(@gray-dark, 5%)<br />
|-<br />
| @dropdown-link-active-color || @dropdownLinkColorActive || @component-active-color<br />
|-<br />
| @dropdown-link-active-bg || @dropdownLinkBackgroundActive || @component-active-bg<br />
|-<br />
| @dropdown-link-hover-bg || @dropdownLinkBackgroundHover || #f5f5f5<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @foldertree-sidepane-background || @foldertreeSidepanelBackground || #f5f5f5 ||<br />
|-<br />
| @foldertee-section-title-color || @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertree-active-label-color || @foldertreeActiveLabelColor || #333 || ''Active'' means, user can perform an action on this item<br />
|-<br />
|@foldertree-passive-label-color || @foldertreePassiveLabelColor ||@hc-gray || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertree-hover-background || @foldertreeHoverBackground || rgba(0, 0, 0, 0.05) ||<br />
|-<br />
| @foldertree-selected-background || @foldertreeSelectedBackground || rgba(0, 0, 0, 0.10) ||<br />
|-<br />
| @foldertree-badge-background || @foldertreeBadgeBackground || @bagde-bg || see [[#Colors]] for definition of @badge-bg<br />
|-<br />
| @foldertree-badge-color || @foldertreeBadgeColor ||@badge-color || see [[#Colors]] for definition of @badge-color<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @appointment-reserved || @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointment-temporary || @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointment-absent || @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointment-free || @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointment-private || @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointment-declined-font || @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointment-unconfirmed-alpha || @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointment-declined-alpha || @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointment-hover-pct || @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @weekview-appointment-lasso || @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekview-day-in || @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekview-day-out || @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekview-timeline || @weekviewTimeline || rgba(243, 15, 170, 0.4) || Color of the Line indicating the current time<br />
|-<br />
| @weekview-time-width || @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendar-toolbar-height || @calendarToolbarHeight || 47px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @monthview-appointment-out || @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthview-today || @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| || @monthview@calendarToolbarHeight || ||<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(path/to/mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. Reference the entire path to the file, relative to the folder containing your ui, but without the leading slash. For example, the Core reference would be <code>apps/themes/default/logo-small.png</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
=== Mobile and retina screens ===<br />
<br />
Almost any mobile device and some newer desktop devices use retina screens. These screens do have a very high pixel density which offer very sharp text rendering. To offer sharp and correctly sized images on retina screens there is and additional CSS directive encapsulated in a media query which must be set in your custom theme.<br />
<br />
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),<br />
only screen and (-moz-min-device-pixel-ratio: 1.5),<br />
only screen and (min-device-pixel-ratio: 1.5),<br />
only screen and (min-resolution: 240dppx) {<br />
#io-ox-top-logo-small {<br />
background-size: 60px 22px;<br />
background-image: url('apps/themes/default/logo-large.png');<br />
}<br />
}<br />
<br />
'''It is important that you provide your brand logo in two sizes''', the standard size of 60x22px and a large version with doubled pixel sizes of 120x44px. All retina devices will use the large logo and scale it down the CSS pixel size of 60x22px. This will result in a sharp image as the retina screen can make use of the additional available pixels in the source image.<br />
<br />
'''Important note''': Your logo must not be wider than 70px (including margins) for mobile devices. Otherwise the toolbar will be broken on mobile devices as the large logo will cause a line wrap in the toolbar. If you need a larger logo use a custom, smaller one for mobiles. <br />
<br />
Always test your theme on mobiles, too. You can emulate popular screen sizes with the Google Chrome Dev-Tools.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
'''This documentation applies for AppSuite v.7.4.2'''<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers as long as you don't deliver your own icons with your theme. To provide your own icons, put them into your theme's directory, e.g. <tt>apps/themes/<var>theme-name</var>/favicon.ico</tt>.<br />
<br />
=== Favicon ===<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
You should provide your custom favicon within your custom theme. If you do not add a custom favicon to your theme the global OX default will be used. The default icon is located under <tt>apps/themes/icons/default</tt> on the web server.<br />
<br />
'''Attention:''' Safari and Internet Explorer do not support dynamic changes to the favicon for a webpage. This means, the default icon will be shown even if a custom favicon is provided within a custom theme. To enable the right favicon for a theme on Safari and IE, the overall standard <tt>favicon.ico</tt> located under <tt>apps/themes/icons/default</tt> on the web server must be replaced with a custom version.<br />
<br />
=== Apple touch icons ===<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. AppSuite offers full support for Webclips by providing all needed App icons, splashscreens and full screen support. If a user uses the "Add to homescreen" button on his iOS device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format.<br />
<br />
* iPhone 3: 57 x 57 px<br />
* iPhone 4 retina: 114x114 px<br />
* iPhone iPhone 5 retina: 120 x 120 px<br />
* iPad: 72 x 72 px<br />
* iPad (iOS 7): 76 x 76px<br />
* iPad retina: 144 x 144 px <br />
* iPad retina (iOS 7): 152 x 152 px <br />
<br />
Furthermore a fullscreen Webclip App will show a splashscreen, a jpg file that is displayed on startup during app load. There are currently three different resolutions as jpg files available. '''Note''': Splashscreens must be JPG files<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change with Apple's iOS updates. We recommend providing all of this resolutions when customizing the Webclip icons and splashscreens, even if some iOS devices use the next best resolution for an icon if a certain file is missing.<br />
<br />
=== Providing custom icons ===<br />
To provide custom Webclip icons locate the following path in the AppSuite installation on your web server:<br />
pathToAppSuite/apps/themes/icons/default<br />
<br />
This folder contains all OX default icons for Webclips icons and splashscreens. Use these as samples for your own versions.<br />
<br />
A clean installation will have all our default icons in the "default" directory. To customize the icons we recommend using our default icons as samples and save your customized version in your theme. '''Note''': The filename has to be the same as in the default folder. Otherwise the fallback will be applied and the default icons will be used. If more advanced rewriting is needed one should edit the contents of the <tt>.htaccess</tt> file located under <tt>apps/themes</tt><br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
=== Providing domain based login themes ===<br />
<br />
This is only needed when using the default login screen shipped with the Core UI and for versions older than the 7.8.0 release. Since 7.8.0, the normal way via as-config.yml will work just fine ([[AppSuite:Theming the login page|Learn how to do this here]]).<br />
<br />
If you have a multibrand installation and you want to deliver not only custom themes but also custom login-themes this can be done via Apache mod_rewrite. You can do so by a domain-based rewrite rule to deliver custom themes to a user based on the URI he's using. The needed config file <tt>.htaccess</tt> is located under <tt>apps/themes</tt><br />
<br />
<pre><br />
# Sample config for domain based login theme<br />
RewriteCond %{HTTP_HOST} ^www\.domain\.com$<br />
RewriteCond %{REQUEST_FILENAME} -f<br />
RewriteRule ^login/(.*)$ domain_com_logintheme/$1 [L]<br />
</pre><br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]<br />
[[Category:Custom development]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=21931AppSuite:Theming2016-05-19T08:29:10Z<p>Alexander.quast: /* Replacing the logo */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>/opt/open-xchange/appsuite/apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
Variables are defined in variables.less from twitter-bootstrap and our default definitions.less. Variables that are defined in definitions.less always override variables from bootstrap's variables.less<br />
<br />
=== Most relevant variables ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @topbar-background || @topbarBackground || #3774A8 (blue)<br />
|-<br />
| --- || @topbarBackgroundAlt || No longer used<br />
|-<br />
| @topbar-launcher-color || @topbarLauncherColor || rgba(255, 255, 255, 0.70)<br />
|-<br />
| @topbar-launcher-color-hover || @topbarLauncherColor-hover || #fff<br />
|-<br />
| @topbar-launcher-color-active || @topbarLauncherColorActive || #fff<br />
|-<br />
| @topbar-launcher-background-hover || @topbarLauncherBackgroundHover || rgba(0, 0, 0, 0.30)<br />
|-<br />
| @topbar-launcher-background-active || @topbarLauncherBackgroundActive || rgba(0, 0, 0, 0.20);<br />
|-<br />
| @topbar-icon-color || @topbarIconColor || #fff<br />
|-<br />
| @selected-background || @selectedBackground || #428BCA (blue)<br />
|-<br />
| @contact-picture-radius || @contactPictureRadius || 50%<br />
|-<br />
|}<br />
:<br />
<br />
<br />
The most significant visual change is achieved by changing the following variables:<br />
* '''@topbar-background''' (top navigation bar)<br />
* '''@selected-background''' (selection background color in list views and folder tree)<br />
* '''@link-color''' (almost all hyperlinks)<br />
<br />
=== Font ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @font-family-sans-serif || @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @font-family-serif || @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @font-family-monospace || @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @font-size-base || @baseFontSize || 14px<br />
|-<br />
| || @baseFontFamily ||<br />
|-<br />
| @line-height-base || @baseLineHeight || 1.428571429; // 20/14<br />
|-<br />
| || @altFontFamily ||<br />
|-<br />
| @font-size-touch || @touchFontSize || 15px<br />
|-<br />
| @headings-font-family || @headingsFontFamily || inherit<br />
|-<br />
| @headings-font-weight || @headingsFontWeight || 500<br />
|-<br />
| @font-size-large || @fontSizeLarge || ceil((@font-size-base * 1.25)); // ~18px<br />
|-<br />
| @font-size-small || @fontSizeSmall || ceil((@font-size-base * 0.85)); // ~12px<br />
|-<br />
| || @fontSizeMini ||<br />
|-<br />
| @vgrid-font-size || @vgridFontSize || 13px<br />
|}<br />
<br />
=== Colors ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @background || @bodyBackground || #fff<br />
|-<br />
| @text-color || @textColor || @gray-dark<br />
|-<br />
| @link-color || @linkColor || @brand-primary<br />
|-<br />
| @link-hover-color || @linkColorHover || darken(@link-color, 15%)<br />
|-<br />
| @link-accent-color || @linkAccentColor || #ffad00<br />
|-<br />
| || @linkAccentColorHover ||<br />
|-<br />
| @badge-color || @badgeColor || @white<br />
|-<br />
| @badge-bg || @badgeBackground || #aaa<br />
|-<br />
| @headings-color || @headingsColor || inherit<br />
|-<br />
| @black || @black || #000<br />
|-<br />
| @gray-darker || @grayDarker || #222<br />
|-<br />
| @gray-dark || @grayDark || #333<br />
|-<br />
| @gray || @gray || #555<br />
|-<br />
| @gray-light || @grayLight || #999<br />
|-<br />
| @gray-lighter || @grayLighter || #eee<br />
|-<br />
| @white || @white || #fff<br />
|-<br />
| @blue || @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blue-dark || @blueDark || #0064cd<br />
|-<br />
| @blue-light || @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || @green || #1A8D1A<br />
|-<br />
| @green-light || @greenLight || #92D050<br />
|-<br />
| @red || @red || #cc0000<br />
|-<br />
| @yellow || @yellow || #F8E400<br />
|-<br />
| @orange || @orange || #f89406<br />
|-<br />
| @pink || @pink || #E01CD9<br />
|-<br />
| @purple || @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
=== Space ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| || @paddingLarge ||<br />
|-<br />
| || @paddingSmall ||<br />
|-<br />
| || @paddingMini ||<br />
|-<br />
| @border-radius-base || @baseBorderRadius || 4px<br />
|-<br />
| @border-radius-large || @borderRadiusLarge || 6px<br />
|-<br />
| @border-radius-small || @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @pagination-bg || @paginationBackground || #fff<br />
|-<br />
| @pagination-border || @paginationBorder || #ddd<br />
|-<br />
| @pagination-active-bg || @paginationActiveBackground || @brand-primary<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| || @btnBackground ||<br />
|-<br />
| || @btnBackgroundHighlight ||<br />
|-<br />
| || @btnBorder ||<br />
|-<br />
| @btn-primary-bg || @btnPrimaryBackground || @link-color<br />
|-<br />
| || @btnPrimaryBackgroundHighlight ||<br />
|-<br />
| @btn-info-bg || @btnInfoBackground || #5bc0de<br />
|-<br />
| || @btnInfoBackgroundHighlight ||<br />
|-<br />
| @btn-success-bg || @btnSuccessBackground || #62c462<br />
|-<br />
| || @btnSuccessBackgroundHighlight ||<br />
|-<br />
| @btn-warning-bg || @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| || @btnWarningBackgroundHighlight ||<br />
|-<br />
| @btn-danger-bg || @btnDangerBackground || #ee5f5b<br />
|-<br />
| || @btnDangerBackgroundHighlight ||<br />
|-<br />
| @btn-inverse-bg || @btnInverseBackground || #444<br />
|-<br />
| || @btnInverseBackgroundHighlight ||<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x)<br />
|-<br />
| @dropdown-bg || @dropdownBackground || #fff<br />
|-<br />
| @dropdown-border || @dropdownBorder || rgba(0,0,0,.15)<br />
|-<br />
| @dropdown-divider-bg || @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdown-divider-bg || @dropdownDividerBottom || #e5e5e5<br />
|-<br />
| @dropdown-link-color || @dropdownLinkColor || @gray-dark<br />
|-<br />
| @dropdown-link-hover-color || @dropdownLinkColorHover || darken(@gray-dark, 5%)<br />
|-<br />
| @dropdown-link-active-color || @dropdownLinkColorActive || @component-active-color<br />
|-<br />
| @dropdown-link-active-bg || @dropdownLinkBackgroundActive || @component-active-bg<br />
|-<br />
| @dropdown-link-hover-bg || @dropdownLinkBackgroundHover || #f5f5f5<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @foldertree-sidepane-background || @foldertreeSidepanelBackground || #f5f5f5 ||<br />
|-<br />
| @foldertee-section-title-color || @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertree-active-label-color || @foldertreeActiveLabelColor || #333 || ''Active'' means, user can perform an action on this item<br />
|-<br />
|@foldertree-passive-label-color || @foldertreePassiveLabelColor ||@hc-gray || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertree-hover-background || @foldertreeHoverBackground || rgba(0, 0, 0, 0.05) ||<br />
|-<br />
| @foldertree-selected-background || @foldertreeSelectedBackground || rgba(0, 0, 0, 0.10) ||<br />
|-<br />
| @foldertree-badge-background || @foldertreeBadgeBackground || @bagde-bg || see [[#Colors]] for definition of @badge-bg<br />
|-<br />
| @foldertree-badge-color || @foldertreeBadgeColor ||@badge-color || see [[#Colors]] for definition of @badge-color<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @appointment-reserved || @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointment-temporary || @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointment-absent || @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointment-free || @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointment-private || @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointment-declined-font || @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointment-unconfirmed-alpha || @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointment-declined-alpha || @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointment-hover-pct || @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @weekview-appointment-lasso || @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekview-day-in || @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekview-day-out || @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekview-timeline || @weekviewTimeline || rgba(243, 15, 170, 0.4) || Color of the Line indicating the current time<br />
|-<br />
| @weekview-time-width || @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendar-toolbar-height || @calendarToolbarHeight || 47px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable (7.6.x) || Variable (7.4.x) || Default (7.6.x) || Description<br />
|-<br />
| @monthview-appointment-out || @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthview-today || @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| || @monthview@calendarToolbarHeight || ||<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(path/to/mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. Reference the entire path to the file, relative to the folder containing your ui, but without the leading slash. For example, the Core reference would be <code>apps/themes/default/logo-small.png</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
=== Mobile and retina screens ===<br />
<br />
Almost any mobile device and some newer desktop devices use retina screens. These screens do have a very high pixel density which offer very sharp text rendering. To offer sharp and correctly sized images on retina screens there is and additional CSS directive encapsulated in a media query which must be set in your custom theme.<br />
<br />
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),<br />
only screen and (-moz-min-device-pixel-ratio: 1.5),<br />
only screen and (min-device-pixel-ratio: 1.5),<br />
only screen and (min-resolution: 240dppx) {<br />
#io-ox-top-logo-small {<br />
// tell the browser to scale the image down, this will result<br />
// in a sharp image on retina screens<br />
background-size: 60px 22px;<br />
// important: "logo-large.png" is 120x44px<br />
background-image: url('apps/themes/default/logo-large.png');<br />
}<br />
}<br />
<br />
'''It is important that you provide your brand logo in two sizes''', the standard size of 60x22px and a large version with doubled pixel sizes of 120x44px. All retina devices will use the large logo and scale it down the CSS pixel size of 60x22px. This will result in a sharp image as the retina screen can make use of the additional available pixels in the source image.<br />
<br />
'''Important note''': Your logo must not be wider than 70px for mobile devices. Otherwise the toolbar will be broken on mobile devices as the large logo will cause a line wrap in the toolbar. If you need a larger logo use a custom, smaller one for mobiles. <br />
<br />
Always test your theme on mobiles, too. You can emulate popular screen sizes with the Google Chrome Dev-Tools.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
'''This documentation applies for AppSuite v.7.4.2'''<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers as long as you don't deliver your own icons with your theme. To provide your own icons, put them into your theme's directory, e.g. <tt>apps/themes/<var>theme-name</var>/favicon.ico</tt>.<br />
<br />
=== Favicon ===<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
You should provide your custom favicon within your custom theme. If you do not add a custom favicon to your theme the global OX default will be used. The default icon is located under <tt>apps/themes/icons/default</tt> on the web server.<br />
<br />
'''Attention:''' Safari and Internet Explorer do not support dynamic changes to the favicon for a webpage. This means, the default icon will be shown even if a custom favicon is provided within a custom theme. To enable the right favicon for a theme on Safari and IE, the overall standard <tt>favicon.ico</tt> located under <tt>apps/themes/icons/default</tt> on the web server must be replaced with a custom version.<br />
<br />
=== Apple touch icons ===<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. AppSuite offers full support for Webclips by providing all needed App icons, splashscreens and full screen support. If a user uses the "Add to homescreen" button on his iOS device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format.<br />
<br />
* iPhone 3: 57 x 57 px<br />
* iPhone 4 retina: 114x114 px<br />
* iPhone iPhone 5 retina: 120 x 120 px<br />
* iPad: 72 x 72 px<br />
* iPad (iOS 7): 76 x 76px<br />
* iPad retina: 144 x 144 px <br />
* iPad retina (iOS 7): 152 x 152 px <br />
<br />
Furthermore a fullscreen Webclip App will show a splashscreen, a jpg file that is displayed on startup during app load. There are currently three different resolutions as jpg files available. '''Note''': Splashscreens must be JPG files<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change with Apple's iOS updates. We recommend providing all of this resolutions when customizing the Webclip icons and splashscreens, even if some iOS devices use the next best resolution for an icon if a certain file is missing.<br />
<br />
=== Providing custom icons ===<br />
To provide custom Webclip icons locate the following path in the AppSuite installation on your web server:<br />
pathToAppSuite/apps/themes/icons/default<br />
<br />
This folder contains all OX default icons for Webclips icons and splashscreens. Use these as samples for your own versions.<br />
<br />
A clean installation will have all our default icons in the "default" directory. To customize the icons we recommend using our default icons as samples and save your customized version in your theme. '''Note''': The filename has to be the same as in the default folder. Otherwise the fallback will be applied and the default icons will be used. If more advanced rewriting is needed one should edit the contents of the <tt>.htaccess</tt> file located under <tt>apps/themes</tt><br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
=== Providing domain based login themes ===<br />
<br />
This is only needed when using the default login screen shipped with the Core UI and for versions older than the 7.8.0 release. Since 7.8.0, the normal way via as-config.yml will work just fine ([[AppSuite:Theming the login page|Learn how to do this here]]).<br />
<br />
If you have a multibrand installation and you want to deliver not only custom themes but also custom login-themes this can be done via Apache mod_rewrite. You can do so by a domain-based rewrite rule to deliver custom themes to a user based on the URI he's using. The needed config file <tt>.htaccess</tt> is located under <tt>apps/themes</tt><br />
<br />
<pre><br />
# Sample config for domain based login theme<br />
RewriteCond %{HTTP_HOST} ^www\.domain\.com$<br />
RewriteCond %{REQUEST_FILENAME} -f<br />
RewriteRule ^login/(.*)$ domain_com_logintheme/$1 [L]<br />
</pre><br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]<br />
[[Category:Custom development]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:OX_Mail&diff=21836AppSuite:OX Mail2016-04-18T13:56:08Z<p>Alexander.quast: /* Installation of the Clients */</p>
<hr />
<div>= OX Mail =<br />
<br />
OX Mail is a native mobile phone app built specifically for smartphone users who already have a valid OX App Suite account. The app is designed to let users access their OX App Suite email environment directly from a smartphone native client.<br />
<br />
OX Mail enables users to synchronize mails between a variety of smartphone devices and OX App Suite. OX Mail consists of two elements: The OX Mail component that is built into OX App Suite and the native OX Mail app.<br />
<br />
The OX Mail app has been designed specifically for ease-of-use and is available for both iOS and Android.<br />
<br />
'''Please Note: With this app Open-Xchange has also created a new branding concept for the customers and partners. More information can be found in the chapter [http://oxpedia.org/wiki/index.php?title=AppSuite:OX_Mail#Integrated_Branding.2FCustomization_Concept_for_Partners_and_Customers Branding/Customization Concept for Partners and Customers]'''<br />
<br />
== Requirements ==<br />
<br />
=== Server-side Installation and Configuration ===<br />
<br />
With OX Mail, OX App Suite supports server based PUSH functionality.<br />
<br />
Dovecot customers can use the special PUSH plugin without any additional costs. The plugin will be provided via the Dovecot software repository for Dovecot Pro and community edition. '''Please Note, the installation of the latest Dovecot v2.2.19 release is required'''<br />
<br />
'''Please Note: The Open-Xchange package 'open-xchange-push-imapidle' which provides mail push functionality by using the IMAP IDLE command to generate push events when new mail arrives, is not officially supported with OX Mail (app).'''<br />
<br />
If you are not using the Dovecot Push Plugin your mail backend has to actively notify the Open-Xchange middleware servers of new emails. This might require the creation of an additional OX middleware plugin to receive those notifications. For further details please contact your assigned pre-sales / prof. services contact.<br />
<br />
'''Please Note, the installation of the latest OX App Suite version is required.'''<br />
<br />
You will finde the client requirements under [[AppSuite:OX_System_Requirements#OX_Mail_for_Clients|OX Mail requirements]]<br />
<br />
== Key Benefits ==<br />
<br />
* Supports email PUSH notification for personal Inbox – emails show up immediately on the device<br />
* Quick and easy to set up with the start-up wizard<br />
* Intuitive, simple to use, design <br />
* Familiar smartphone experience<br />
* Available for both iOS and Android – download app from App Store for free<br />
<br />
A more detailed overview of OX Mail, can be found at: http://software.open-xchange.com/products/mail/doc/OX_Mail_Product_Guide.pdf<br />
<br />
== Pricing & Availability ==<br />
<br />
This email app is available for both iOS and Android and can be downloaded for free from the corresponding App Stores. Availability will be confirmed by Open-Xchange via the usual communication channels. <br />
<br />
'''Please note:''' The exact date when the clients become available depends on the approval process of the respective app stores. <br />
<br />
The Open-Xchange Middleware components can be downloaded from the respective download repositories as normal.<br />
<br />
Please contact your Open-Xchange account manager for further information and pricing details.<br />
<br />
= Enabling OX Mail for Users =<br />
<br />
OX Mail is enabled for all users that have the capability ''com.openexchange.capability.mobile_mail_app'' <br />
<br />
More details about capabilities can be found at [[AppSuite:Capabilities]]. Furthermore, this capability can be defined in a more granular way using the Config Cascade as described at [[ConfigCascade]].<br />
<br />
IMPORTANT: <br />
By default, the capability for the OX Mail app is set to false for all users. It can be changed by editing the corresponding capability in the "permissions.properties" config file, or if you need a more fine grained selection of enabled users, you can use the well known provisioning tools / config cascade.<br />
<br />
= Installation of the Clients =<br />
<br />
The OX Mail is available via the different App Stores for iOS and Android:<br />
<br />
* [https://itunes.apple.com/us/app/ox-mail/id1008644994?l=de&ls=1&mt=8 OX Mail in Apple App Store]<br />
* [https://play.google.com/store/apps/details?id=com.openexchange.mobile.mailapp.enterprise OX Mail in GooglePlay]<br />
<br />
'''Note''': OX Mail was designed to work on Smartphones. In some rare cases devices with very large screens (greater than 5.6") might be recognized as tablets by the Play Store. In this case, OX Mail will not show up and can not be installed on your device.<br />
<br />
= OX Mail Server-side Installation and Configuration on OX App Suite v7.8.x =<br />
<br />
This chapter describes how the backend components of OX Mail are installed and configured on the server.<br />
<br />
== Available packages ==<br />
<br />
OX Mail is available with the following backend packages:<br />
<br />
* ''open-xchange-mobile-push-certificates'' - Certificates for cloud-based push notifications<br />
* ''open-xchange-mailapp-backend'' - The main server components for OX Mail<br />
* ''open-xchange-mobile-push-plugin'' - Provides Push functionality<br />
<br />
Installation on the server varies depending on the underlying distribution, details are available in the following chapters.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ yum install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 7.0 (Wheezy) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 8.0 (Jessie) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianJessie|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=debianname|pc2v=DebianJessie|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|backend/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=susename|pc2v=SLES11|mail|mailapp}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== SUSE Linux Enterprise Server 12 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLE_12|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|backend/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=susename|pc2v=SLE_12|mail|mailapp}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
= OX Mail Server-side Installation and Configuration on OX App Suite v7.6.2 =<br />
<br />
This chapter describes how the backend components of OX Mail are installed and configured on the server.<br />
<br />
== Enforced SSL connection on iOS clients ==<br />
<br />
With iOS 9 Apple introduced ATS (App Transport Security) which by default blocks all unencrypted network connections for Apps using http. To enable OX Mail for iOS on your server you will need to provide a valid SSL certificate for your system, otherwise the iOS client will refuse to connect to your system. Using a unencrypted http connection will not work.<br />
<br />
You can simply test if your certificate is valid by visiting your webserver with iOS Safari. If the browser accepts your https connection without showing any warning, your certificate is trusted by the system and OX Mail will also work.<br />
<br />
== Available packages ==<br />
<br />
OX Mail is available with the following backend packages:<br />
<br />
* ''open-xchange-mobile-push-certificates'' - Certificates for cloud-based push notifications<br />
* ''open-xchange-mailapp-backend'' - The main server components for OX Mail<br />
* ''open-xchange-mobile-push-plugin'' - Provides Push functionality<br />
<br />
Installation on the server varies depending on the underlying distribution, details are available in the following chapters.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ yum install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 6.0 (Squeeze) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=debianname|pc2v=DebianSqueeze|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=debianname|pc2v=DebianSqueeze|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 7.0 (Wheezy) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=debianname|pc2v=DebianWheezy|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|backend/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=susename|pc2v=SLES11|mail|mailapp}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
= Setup Description for Mobile Push =<br />
<br />
== Setup of the Open-Xchange Node==<br />
<br />
The existing push framework of the Open-Xchange Middleware has been extended by the capability to spawn "permanent" listeners for incoming new message deliveries. Up to that point the life cycle for a listener was bound to at least one active session, which is associated with a client that is allowed to receive push notifications.<br />
<br />
With introduction of the previously mentioned capability, listeners can be started without the need for an existent session right on the start of an Open-Xchange Middleware node. In addition those permanent listeners are spread approximately even over capable cluster members as - dependent on the underlying implementation - a listener representation may open/hold resources (socket connections) in order to receive notifications about new message deliveries.<br />
<br />
To prepare a certain Open-Xchange Middleware node to spawn permanent push listeners the following properties need to be configured in file '/opt/open-xchange/etc/mail-push.properties':<br />
<br />
* com.openexchange.push.allowPermanentPush<br>This is the general switch to enable/disable support for permanent listeners on a node. Thus needs to be set to "true"<br />
* com.openexchange.push.allowedClient<br>Specify the comma-separated list of clients which are allowed to receive notifications about new mails, “open-xchange-mailapp” should be added here if you plan to use it in combination with the new mobile-push feature.<br />
* com.openexchange.push.credstorage.enabled<br>As permanent listeners are required to run without an active session, the credential storage can be used to store user credentials in installations that do not support a master authentication to the mail storage Hence, if the property "com.openexchange.mail.passwordSource" (mail.properties) is not set to "global" this property is required to be set to "true"<br />
* com.openexchange.push.credstorage.passcrypt<br>This property is required if "com.openexchange.push.credstorage.enabled" is set to "true". It does specify the passphrase to use to symmetrically encrypt the stored credentials. The passphrase is required to be equal on each cluster member.<br />
* com.openexchange.push.credstorage.rdb<br>Once the credential storage is enabled, Open-Xchange offers two ways of storing the user-associated login/password combination. In cluster memory (default) or persisted to database. While the first way ensures that no user credentials are persisted nowhere in the Open-Xchange installation, it has the big disadvantage the stored credentials are gone once the last cluster members gets shut-down. Therefore there is also the possibility to store the credentials inside the database. Of course, no matter where the credentials are stored, they are encrypted using the value from com.openexchange.push.credstorage.passcrypt" property<br />
<br />
With setting the properties above the configuration on the Open-Xchange Middleware node is prepared to spawn permanent listeners.<br />
<br />
Now an appropriate push bundle/package needs to be installed that supports spawning permanent listeners. Currently Open-Xchange ships with three implementations:<br />
* open-xchange-push-dovecot (also requires the optional open-xchange-rest package)<br />
* open-xchange-push-imapidle (Not recommended, therefore disabled for IMAP-IDLE by default. com.openexchange.push.imapidle.supportsPermanentListeners=false)<br />
* open-xchange-push-mailnotify<br />
<br />
Putting all together the following execution flow is taken to decide whether permanent listeners are spawned or not:<br />
<br />
[[Image:ox_mail_push_configuration_2.png|500px]]<br />
<br />
To check at any time what listeners are currently running, there is a new command-line tool "/opt/open-xchange/sbin/listpushusers" that outputs the user-id/context-id pair along-side with the information if the listener is of permanent nature or bound to an active session:<br />
<br />
[[Image:ox_mail_push_configuration_3.png|500px]]<br />
<br />
An exemplary out put might look like:<br />
~# /opt/open-xchange/sbin/listpushusers<br />
user=249, context=1, permanent=true<br />
user=402, context=1, permanent=true<br />
<br />
== Setup of the Mobile Push ==<br />
An appropriate registration for a capable client is required to create a permanent listener for a certain user. As of now, only the Open-Xchange Mail App performs such a registration request to mark the user to have a permanent listener using the newly introduced Mobile Push interfaces of the Open-Xchange Middleware.<br />
The Mobile Push feature is installed by the following packages:<br />
* open-xchange-mobile-push-plugin<br />
* open-xchange-mobile-push-certificates (Only certificates and licenses)<br />
<br />
Simply said the main purpose of the Mobile Push functionality is to register an OSGi event handler converting an incoming OSGi event with topic "com/openexchange/push" to an appropriate native push reaching the mobile device using either<br />
* APN or<br />
* GCM<br />
<br />
=== Client subscription ===<br />
To be able to do so, the client has to perform a subscribe request against the Mobile Push interface. Such a subscribe call mainly performs two things<br />
<br />
1. Storing the data into the database that is needed to initiate a APN/GCM push request<br><br />
2. Registering & starting a permanent listener in the push framework<br><br />
<br />
=== Handling of OSGi events ===<br />
<br />
Moreover, the OSGi events with topic "com/openexchange/push" are spread remotely throughout the Open-Xchange cluster. To avoid that each node yields a native push event for the mobile device, the OSGi event handler of the Mobile Push does only consider local events. This fact implies that each node that broadcasts OSGi events with topic "com/openexchange/push" is required to have the open-xchange-mobile-push packages installed; otherwise the OSGi event is not handled.<br />
<br />
=== Mobile Push configuration ===<br />
The setup of the Mobile Push functionality includes proper configuration of the communication with the APN/GCM services, which is performed in file 'mobilepushevent.properties':<br />
* com.openxchange.mobilepush.events.gcm.enabled<br>General switch to enable/disable communication with GCM service<br />
* com.openxchange.mobilepush.events.gcm.key<br>Specifies the GCM key in order to authenticate against the GCM service and to forward push messages to that service. Required if "com.openxchange.mobilenotifier.events.gcm.enabled" is "true" and you want to use a different key than provided by open-xchange-mobile-push-certificates. Otherwise the key from open-xchange-mobile-push-certificates is used.<br />
* com.openxchange.mobilepush.events.apn.ios.enabled<br>General switch to enable/disable communication with APN service<br />
* com.openxchange.mobilepush.events.apn.ios.keystore<br>Specifies the path to the local keystore file (PKCS #12) containing the APNS certificate and keys for the iOS application. Required if "com.openxchange.mobilepush.events.apn.ios.enabled" is "true" and you want to use a different certificate than provided by open-xchange-mobile-push-certificates. Otherwise the certificate from open-xchange-mobile-push-certificates is used.<br />
* com.openxchange.mobilepush.events.apn.ios.password<br>Specifies the password used when creating the referenced keystore containing the certificate of the iOS application. Note that blank or null passwords are in violation of the PKCS #12 specifications. Required if "com.openxchange.mobilepush.events.apn.ios.enabled" is "true" and you want to use a different certificate than provided by open-xchange-mobile-push-certificates.<br />
<br />
= Setup of the Dovecot Push =<br />
<br />
== IMAP METADATA ==<br />
<br />
Dovecot Push plug-in requires METADATA support on Dovecot side, but it should only be enabled for OX IMAP sessions and not for any other IMAP clients directly. Enabling can be done with e.g. the remote directive "remote 1.2.3.0/24 { imap_metadata = yes }" and specifying the IP ranges of OX.<br />
<br />
Dovecot supports the [[https://tools.ietf.org/html/rfc5464|IMAP METADATA extension (RFC 5464)]], which allows per-mailbox, per-user data to be stored and accessed via IMAP commands.<br />
<br />
To activate metadata storage, a [[Dictionary|dictionary]] needs to be configured in the Dovecot configuration using the {{{mail_attribute_dict}}} option.<br />
<br />
To activate the IMAP METADATA commands, the imap_metadata and mail_attribute_dict options need to be activated.<br />
<br />
Example:<br />
<br />
<br />
# Store METADATA information within user's Maildir directory<br />
mail_attribute_dict = file:%h/Maildir/dovecot-attributes<br />
<br />
protocol imap {<br />
imap_metadata = yes<br />
}<br />
<br />
The following picture should demonstrate how the overall communication flow between Mail App, Open-Xchange Middleware, and the Dovecot Push plug-in takes place. That communication flow requires the "open-xchange-push-dovecot" and "open-xchange-rest" packages to be installed on the Open-Xchange Middleware nodes and the Dovecot "http-notify" plug-in.<br />
<br />
[[Image:ox_mail_push_configuration_4.png|500px]]<br />
<br />
Once the Open-Xchange Mail App is installed on the user’s mobile device and it is allowed to show notifications about a new message delivery, the Mail App performs a subscription call to the Open-Xchange Middleware Servers using a fully authenticated session.<br />
<br />
When the "open-xchange-push-dovecot" package is installed, the previous subscribe call requests it to spawn a permanent listener. Such a listener simply tells the Dovecot server to notify about new message delivery events for the associated user by executing a special SETMETADATA command. Hence, it does not open or use any resources other than firing a single IMAP command to the Dovecot IMAP Server.<br />
<br />
Whenever a "new message delivery" event occurs, the Dovecot Server performs a HTTP callback against a configurable HTTP end-point of the Open-Xchange Middleware providing crucial information about the newly delivered message with a simple JSON body. That incoming HTTP callback is then turned into an appropriate OSGi event with topic "com/openexchange/push".<br />
<br />
That event is in turn handled by the Mobile Push event handler, which uses the event’s information to request an APN/GCM push to the mobile device.<br />
<br />
== Configuration of Dovecot "http-notify" plug-in ==<br />
<br />
To use push notifications, both the "notify" and the "push_notification" plugins need to be activated. For LMTP delivery, this is required:<br />
<br />
protocol lmtp {<br />
mail_plugins = $mail_plugins notify push_notification<br />
}<br />
<br />
If you also want push notifications to work for LDA-based delivery, you would need additional configuration:<br />
<br />
protocol lda {<br />
mail_plugins = $mail_plugins notify push_notification<br />
}<br />
<br />
The HTTP end-point (URL + authentication information) to use is configured in the Dovecot configuration file. The appropriate configuration options will contain the HTTP URL denoting the end-point to connect to as well as the authentication information for Basic Authentication as configured by properties "com.openexchange.rest.services.basic-auth.login" and "com.openexchange.rest.services.basic-auth.password".<br />
The URL to configure in Dovecot configuration follows this pattern.<br />
<http|https> + "://" + <login> + ":" + <password> + "@" + <host> + ":" + <port> + "/preliminary/http-notify/v1/notify"<br />
<br />
E.g.<br />
plugin {<br />
push_notification_driver = ox:url=http://login:pass@node1.domain.tld:8009/preliminary/http-notify/v1/notify<br />
}<br />
<br />
Furthermore, it is also possible to specify more than one HTTP end-point to connect to if a new message delivery occurs. Thus the configuration section mentioned above may be extended by additional "push_notification_driver" entries; e.g. push_notification_driver2, push_notification_driver3, etc.<br />
<br />
Please note that the path "/preliminary/http-notify/v1/notify" denotes the internal REST API of the Open-Xchange Middleware, which is not publicly accessible. The administrator can decide whether to add that path to the Apache configuration (see also [[AppSuite:Apache_Configuration]] and [[AppSuite:Grizzly]]) through a Location/ProxyPass directive:<br />
<br />
<Location /preliminary><br />
Order Deny,Allow<br />
Deny from all<br />
# Only allow access from servers within the network. Do not expose this<br />
# location outside of your network. In case you use a load balancing service in front<br />
# of your Apache infrastructure you should make sure that access to /preliminary will<br />
# be blocked from the internet / outside clients. Examples:<br />
# Allow from 192.168.0.1<br />
# Allow from 192.168.1.1 192.168.1.2<br />
# Allow from 192.168.0.<br />
ProxyPass /preliminary balancer://oxcluster/preliminary<br />
</Location><br />
<br />
In case the "user=" sent by OX in the push_notification_driver url data does not match the IMAP login of a user, Dovecot ignores it. This can be overridden by defining "user_from_metadata" in the push_notification_driver url, e.g. <br />
<br />
push_notification_driver = ox:url=http://example.com/ user_from_metadata<br />
<br />
= Integrated Branding/Customization Concept for Partners and Customers =<br />
<br />
With OX Mail it is also possible for customers and partners to add branding elements to the app. During the installation of the app a user is presented with a list of preconfigured providers. When a provider is selected the app is automatically setup and branded for that provider.<br />
<br />
For both design reasons, as well as app store restrictions, branding in this context means:<br />
* The app design is “Super Flat”. This means there are not many elements that can be, or need to be, styled in order to match a particular brand.<br />
* The app does not contain or use any logos of any sort. <br />
* At install time the app uses a startup wizard in combination with a hosted configuration service. The wizard gives the end user the option to select a provider from a list. When this is done the app will retrieve the branding information from the configuration service and changes its theme accordingly. <br />
<br />
== Branding / Customization Process ==<br />
<br />
In order to participate you will need to provide specific information such as:<br />
<br />
* Confirmation that you are running OX App Suite 7.6.2 including the latest patch.<br />
* A full URL where your OX App Suite service can be reached by a web client.<br />
* Two test accounts on your OX App Suite service, where we can verify that the OX App Suite system works as expected.<br />
* A “logo” and “name” of your service. This information will be used in the app itself.<br />
* Optional: A preferred color (CI color) that Open-Xchange will use for the app if a user chooses their service from the provider list.<br />
<br />
=== Steps ===<br />
<br />
# Please download the Questionnaire from [http://knowledgebase.open-xchange.com/fileadmin/user_upload/open-xchange/document/misc/Questionnaire_OX_Mail_Branding.pdf Open-Xchange Download Server]<br />
# Please fill out the Questionnaire and send it to your Open-Xchange account manager.<br />
# Open-Xchange will check the data. If all information are available, Open-Xchange will add your personal brand to the live OX Mail app. Please Note: The exact date when your brand becomes available depends on the approval process and could take 5 to 10 days. Open-Xchange won't communicate an exact date. Please check by your self.<br />
<br />
[[Category: OX7]]<br />
[[Category: AppSuite]]<br />
[[Category: OXMailapp]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:OX_Mail&diff=21809AppSuite:OX Mail2016-04-08T07:50:16Z<p>Alexander.quast: Added iOS ssl chapter</p>
<hr />
<div>= OX Mail =<br />
<br />
OX Mail is a native mobile phone app built specifically for smartphone users who already have a valid OX App Suite account. The app is designed to let users access their OX App Suite email environment directly from a smartphone native client.<br />
<br />
OX Mail enables users to synchronize mails between a variety of smartphone devices and OX App Suite. OX Mail consists of two elements: The OX Mail component that is built into OX App Suite and the native OX Mail app.<br />
<br />
The OX Mail app has been designed specifically for ease-of-use and is available for both iOS and Android.<br />
<br />
'''Please Note: With this app Open-Xchange has also created a new branding concept for the customers and partners. More information can be found in the chapter [http://oxpedia.org/wiki/index.php?title=AppSuite:OX_Mail#Integrated_Branding.2FCustomization_Concept_for_Partners_and_Customers Branding/Customization Concept for Partners and Customers]'''<br />
<br />
== Requirements ==<br />
<br />
=== Server-side Installation and Configuration ===<br />
<br />
With OX Mail, OX App Suite supports server based PUSH functionality.<br />
<br />
Dovecot customers can use the special PUSH plugin without any additional costs. The plugin will be provided via the Dovecot software repository for Dovecot Pro and community edition. '''Please Note, the installation of the latest Dovecot v2.2.19 release is required'''<br />
<br />
'''Please Note: The Open-Xchange package 'open-xchange-push-imapidle' which provides mail push functionality by using the IMAP IDLE command to generate push events when new mail arrives, is not officially supported with OX Mail (app).'''<br />
<br />
If you are not using the Dovecot Push Plugin your mail backend has to actively notify the Open-Xchange middleware servers of new emails. This might require the creation of an additional OX middleware plugin to receive those notifications. For further details please contact your assigned pre-sales / prof. services contact.<br />
<br />
'''Please Note, the installation of the latest OX App Suite version is required.'''<br />
<br />
You will finde the client requirements under [[AppSuite:OX_System_Requirements#OX_Mail_for_Clients|OX Mail requirements]]<br />
<br />
== Key Benefits ==<br />
<br />
* Supports email PUSH notification for personal Inbox – emails show up immediately on the device<br />
* Quick and easy to set up with the start-up wizard<br />
* Intuitive, simple to use, design <br />
* Familiar smartphone experience<br />
* Available for both iOS and Android – download app from App Store for free<br />
<br />
A more detailed overview of OX Mail, can be found at: http://software.open-xchange.com/products/mail/doc/OX_Mail_Product_Guide.pdf<br />
<br />
== Pricing & Availability ==<br />
<br />
This email app is available for both iOS and Android and can be downloaded for free from the corresponding App Stores. Availability will be confirmed by Open-Xchange via the usual communication channels. <br />
<br />
'''Please note:''' The exact date when the clients become available depends on the approval process of the respective app stores. <br />
<br />
The Open-Xchange Middleware components can be downloaded from the respective download repositories as normal.<br />
<br />
Please contact your Open-Xchange account manager for further information and pricing details.<br />
<br />
= Enabling OX Mail for Users =<br />
<br />
OX Mail is enabled for all users that have the capability ''com.openexchange.capability.mobile_mail_app'' <br />
<br />
More details about capabilities can be found at [[AppSuite:Capabilities]]. Furthermore, this capability can be defined in a more granular way using the Config Cascade as described at [[ConfigCascade]].<br />
<br />
IMPORTANT: <br />
By default, the capability for the OX Mail app is set to false for all users. It can be changed by editing the corresponding capability in the "permissions.properties" config file, or if you need a more fine grained selection of enabled users, you can use the well known provisioning tools / config cascade.<br />
<br />
= Installation of the Clients =<br />
<br />
The OX Mail is available via the different App Stores for iOS and Android:<br />
<br />
* [https://itunes.apple.com/us/app/ox-mail/id1008644994?l=de&ls=1&mt=8 OX Mail in Apple App Store]<br />
* [https://play.google.com/store/apps/details?id=com.openexchange.mobile.mailapp.enterprise OX Mail in GooglePlay]<br />
<br />
= OX Mail Server-side Installation and Configuration on OX App Suite v7.8.x =<br />
<br />
This chapter describes how the backend components of OX Mail are installed and configured on the server.<br />
<br />
== Available packages ==<br />
<br />
OX Mail is available with the following backend packages:<br />
<br />
* ''open-xchange-mobile-push-certificates'' - Certificates for cloud-based push notifications<br />
* ''open-xchange-mailapp-backend'' - The main server components for OX Mail<br />
* ''open-xchange-mobile-push-plugin'' - Provides Push functionality<br />
<br />
Installation on the server varies depending on the underlying distribution, details are available in the following chapters.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ yum install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 7.0 (Wheezy) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 8.0 (Jessie) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianJessie|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=debianname|pc2v=DebianJessie|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|backend/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=susename|pc2v=SLES11|mail|mailapp}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== SUSE Linux Enterprise Server 12 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLE_12|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|backend/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mail/stable|pc2n=susename|pc2v=SLE_12|mail|mailapp}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
= OX Mail Server-side Installation and Configuration on OX App Suite v7.6.2 =<br />
<br />
This chapter describes how the backend components of OX Mail are installed and configured on the server.<br />
<br />
== Enforced SSL connection on iOS clients ==<br />
<br />
With iOS 9 Apple introduced ATS (App Transport Security) which by default blocks all unencrypted network connections for Apps using http. To enable OX Mail for iOS on your server you will need to provide a valid SSL certificate for your system, otherwise the iOS client will refuse to connect to your system. Using a unencrypted http connection will not work.<br />
<br />
You can simply test if your certificate is valid by visiting your webserver with iOS Safari. If the browser accepts your https connection without showing any warning, your certificate is trusted by the system and OX Mail will also work.<br />
<br />
== Available packages ==<br />
<br />
OX Mail is available with the following backend packages:<br />
<br />
* ''open-xchange-mobile-push-certificates'' - Certificates for cloud-based push notifications<br />
* ''open-xchange-mailapp-backend'' - The main server components for OX Mail<br />
* ''open-xchange-mobile-push-plugin'' - Provides Push functionality<br />
<br />
Installation on the server varies depending on the underlying distribution, details are available in the following chapters.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ yum install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 6.0 (Squeeze) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=debianname|pc2v=DebianSqueeze|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=debianname|pc2v=DebianSqueeze|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== Debian GNU/Linux 7.0 (Wheezy) ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=debianname|pc2v=DebianWheezy|pc3v=[CUSTOMERID:PASSWORD]|backend/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=[CUSTOMERID:PASSWORD]|mail|mailapp}}<br />
<br />
and run<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/7.6.2|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|backend/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/mail/1.0.0|pc2n=susename|pc2v=SLES11|mail|mailapp}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-mobile-push-certificates open-xchange-mailapp-backend open-xchange-mobile-push-plugin<br />
<br />
= Setup Description for Mobile Push =<br />
<br />
== Setup of the Open-Xchange Node==<br />
<br />
The existing push framework of the Open-Xchange Middleware has been extended by the capability to spawn "permanent" listeners for incoming new message deliveries. Up to that point the life cycle for a listener was bound to at least one active session, which is associated with a client that is allowed to receive push notifications.<br />
<br />
With introduction of the previously mentioned capability, listeners can be started without the need for an existent session right on the start of an Open-Xchange Middleware node. In addition those permanent listeners are spread approximately even over capable cluster members as - dependent on the underlying implementation - a listener representation may open/hold resources (socket connections) in order to receive notifications about new message deliveries.<br />
<br />
To prepare a certain Open-Xchange Middleware node to spawn permanent push listeners the following properties need to be configured in file '/opt/open-xchange/etc/mail-push.properties':<br />
<br />
* com.openexchange.push.allowPermanentPush<br>This is the general switch to enable/disable support for permanent listeners on a node. Thus needs to be set to "true"<br />
* com.openexchange.push.allowedClient<br>Specify the comma-separated list of clients which are allowed to receive notifications about new mails, “open-xchange-mailapp” should be added here if you plan to use it in combination with the new mobile-push feature.<br />
* com.openexchange.push.credstorage.enabled<br>As permanent listeners are required to run without an active session, the credential storage can be used to store user credentials in installations that do not support a master authentication to the mail storage Hence, if the property "com.openexchange.mail.passwordSource" (mail.properties) is not set to "global" this property is required to be set to "true"<br />
* com.openexchange.push.credstorage.passcrypt<br>This property is required if "com.openexchange.push.credstorage.enabled" is set to "true". It does specify the passphrase to use to symmetrically encrypt the stored credentials. The passphrase is required to be equal on each cluster member.<br />
* com.openexchange.push.credstorage.rdb<br>Once the credential storage is enabled, Open-Xchange offers two ways of storing the user-associated login/password combination. In cluster memory (default) or persisted to database. While the first way ensures that no user credentials are persisted nowhere in the Open-Xchange installation, it has the big disadvantage the stored credentials are gone once the last cluster members gets shut-down. Therefore there is also the possibility to store the credentials inside the database. Of course, no matter where the credentials are stored, they are encrypted using the value from com.openexchange.push.credstorage.passcrypt" property<br />
<br />
With setting the properties above the configuration on the Open-Xchange Middleware node is prepared to spawn permanent listeners.<br />
<br />
Now an appropriate push bundle/package needs to be installed that supports spawning permanent listeners. Currently Open-Xchange ships with three implementations:<br />
* open-xchange-push-dovecot (also requires the optional open-xchange-rest package)<br />
* open-xchange-push-imapidle (Not recommended, therefore disabled for IMAP-IDLE by default. com.openexchange.push.imapidle.supportsPermanentListeners=false)<br />
* open-xchange-push-mailnotify<br />
<br />
Putting all together the following execution flow is taken to decide whether permanent listeners are spawned or not:<br />
<br />
[[Image:ox_mail_push_configuration_2.png|500px]]<br />
<br />
To check at any time what listeners are currently running, there is a new command-line tool "/opt/open-xchange/sbin/listpushusers" that outputs the user-id/context-id pair along-side with the information if the listener is of permanent nature or bound to an active session:<br />
<br />
[[Image:ox_mail_push_configuration_3.png|500px]]<br />
<br />
An exemplary out put might look like:<br />
~# /opt/open-xchange/sbin/listpushusers<br />
user=249, context=1, permanent=true<br />
user=402, context=1, permanent=true<br />
<br />
== Setup of the Mobile Push ==<br />
An appropriate registration for a capable client is required to create a permanent listener for a certain user. As of now, only the Open-Xchange Mail App performs such a registration request to mark the user to have a permanent listener using the newly introduced Mobile Push interfaces of the Open-Xchange Middleware.<br />
The Mobile Push feature is installed by the following packages:<br />
* open-xchange-mobile-push-plugin<br />
* open-xchange-mobile-push-certificates (Only certificates and licenses)<br />
<br />
Simply said the main purpose of the Mobile Push functionality is to register an OSGi event handler converting an incoming OSGi event with topic "com/openexchange/push" to an appropriate native push reaching the mobile device using either<br />
* APN or<br />
* GCM<br />
<br />
=== Client subscription ===<br />
To be able to do so, the client has to perform a subscribe request against the Mobile Push interface. Such a subscribe call mainly performs two things<br />
<br />
1. Storing the data into the database that is needed to initiate a APN/GCM push request<br><br />
2. Registering & starting a permanent listener in the push framework<br><br />
<br />
=== Handling of OSGi events ===<br />
<br />
Moreover, the OSGi events with topic "com/openexchange/push" are spread remotely throughout the Open-Xchange cluster. To avoid that each node yields a native push event for the mobile device, the OSGi event handler of the Mobile Push does only consider local events. This fact implies that each node that broadcasts OSGi events with topic "com/openexchange/push" is required to have the open-xchange-mobile-push packages installed; otherwise the OSGi event is not handled.<br />
<br />
=== Mobile Push configuration ===<br />
The setup of the Mobile Push functionality includes proper configuration of the communication with the APN/GCM services, which is performed in file 'mobilepushevent.properties':<br />
* com.openxchange.mobilepush.events.gcm.enabled<br>General switch to enable/disable communication with GCM service<br />
* com.openxchange.mobilepush.events.gcm.key<br>Specifies the GCM key in order to authenticate against the GCM service and to forward push messages to that service. Required if "com.openxchange.mobilenotifier.events.gcm.enabled" is "true" and you want to use a different key than provided by open-xchange-mobile-push-certificates. Otherwise the key from open-xchange-mobile-push-certificates is used.<br />
* com.openxchange.mobilepush.events.apn.ios.enabled<br>General switch to enable/disable communication with APN service<br />
* com.openxchange.mobilepush.events.apn.ios.keystore<br>Specifies the path to the local keystore file (PKCS #12) containing the APNS certificate and keys for the iOS application. Required if "com.openxchange.mobilepush.events.apn.ios.enabled" is "true" and you want to use a different certificate than provided by open-xchange-mobile-push-certificates. Otherwise the certificate from open-xchange-mobile-push-certificates is used.<br />
* com.openxchange.mobilepush.events.apn.ios.password<br>Specifies the password used when creating the referenced keystore containing the certificate of the iOS application. Note that blank or null passwords are in violation of the PKCS #12 specifications. Required if "com.openxchange.mobilepush.events.apn.ios.enabled" is "true" and you want to use a different certificate than provided by open-xchange-mobile-push-certificates.<br />
<br />
= Setup of the Dovecot Push =<br />
<br />
== IMAP METADATA ==<br />
<br />
Dovecot Push plug-in requires METADATA support on Dovecot side, but it should only be enabled for OX IMAP sessions and not for any other IMAP clients directly. Enabling can be done with e.g. the remote directive "remote 1.2.3.0/24 { imap_metadata = yes }" and specifying the IP ranges of OX.<br />
<br />
Dovecot supports the [[https://tools.ietf.org/html/rfc5464|IMAP METADATA extension (RFC 5464)]], which allows per-mailbox, per-user data to be stored and accessed via IMAP commands.<br />
<br />
To activate metadata storage, a [[Dictionary|dictionary]] needs to be configured in the Dovecot configuration using the {{{mail_attribute_dict}}} option.<br />
<br />
To activate the IMAP METADATA commands, the imap_metadata and mail_attribute_dict options need to be activated.<br />
<br />
Example:<br />
<br />
<br />
# Store METADATA information within user's Maildir directory<br />
mail_attribute_dict = file:%h/Maildir/dovecot-attributes<br />
<br />
protocol imap {<br />
imap_metadata = yes<br />
}<br />
<br />
The following picture should demonstrate how the overall communication flow between Mail App, Open-Xchange Middleware, and the Dovecot Push plug-in takes place. That communication flow requires the "open-xchange-push-dovecot" and "open-xchange-rest" packages to be installed on the Open-Xchange Middleware nodes and the Dovecot "http-notify" plug-in.<br />
<br />
[[Image:ox_mail_push_configuration_4.png|500px]]<br />
<br />
Once the Open-Xchange Mail App is installed on the user’s mobile device and it is allowed to show notifications about a new message delivery, the Mail App performs a subscription call to the Open-Xchange Middleware Servers using a fully authenticated session.<br />
<br />
When the "open-xchange-push-dovecot" package is installed, the previous subscribe call requests it to spawn a permanent listener. Such a listener simply tells the Dovecot server to notify about new message delivery events for the associated user by executing a special SETMETADATA command. Hence, it does not open or use any resources other than firing a single IMAP command to the Dovecot IMAP Server.<br />
<br />
Whenever a "new message delivery" event occurs, the Dovecot Server performs a HTTP callback against a configurable HTTP end-point of the Open-Xchange Middleware providing crucial information about the newly delivered message with a simple JSON body. That incoming HTTP callback is then turned into an appropriate OSGi event with topic "com/openexchange/push".<br />
<br />
That event is in turn handled by the Mobile Push event handler, which uses the event’s information to request an APN/GCM push to the mobile device.<br />
<br />
== Configuration of Dovecot "http-notify" plug-in ==<br />
<br />
To use push notifications, both the "notify" and the "push_notification" plugins need to be activated. For LMTP delivery, this is required:<br />
<br />
protocol lmtp {<br />
mail_plugins = $mail_plugins notify push_notification<br />
}<br />
<br />
If you also want push notifications to work for LDA-based delivery, you would need additional configuration:<br />
<br />
protocol lda {<br />
mail_plugins = $mail_plugins notify push_notification<br />
}<br />
<br />
The HTTP end-point (URL + authentication information) to use is configured in the Dovecot configuration file. The appropriate configuration options will contain the HTTP URL denoting the end-point to connect to as well as the authentication information for Basic Authentication as configured by properties "com.openexchange.rest.services.basic-auth.login" and "com.openexchange.rest.services.basic-auth.password".<br />
The URL to configure in Dovecot configuration follows this pattern.<br />
<http|https> + "://" + <login> + ":" + <password> + "@" + <host> + ":" + <port> + "/preliminary/http-notify/v1/notify"<br />
<br />
E.g.<br />
plugin {<br />
push_notification_driver = ox:url=http://login:pass@node1.domain.tld:8009/preliminary/http-notify/v1/notify<br />
}<br />
<br />
Furthermore, it is also possible to specify more than one HTTP end-point to connect to if a new message delivery occurs. Thus the configuration section mentioned above may be extended by additional "push_notification_driver" entries; e.g. push_notification_driver2, push_notification_driver3, etc.<br />
<br />
Please note that the path "/preliminary/http-notify/v1/notify" denotes the internal REST API of the Open-Xchange Middleware, which is not publicly accessible. The administrator can decide whether to add that path to the Apache configuration (see also [[AppSuite:Apache_Configuration]] and [[AppSuite:Grizzly]]) through a Location/ProxyPass directive:<br />
<br />
<Location /preliminary><br />
Order Deny,Allow<br />
Deny from all<br />
# Only allow access from servers within the network. Do not expose this<br />
# location outside of your network. In case you use a load balancing service in front<br />
# of your Apache infrastructure you should make sure that access to /preliminary will<br />
# be blocked from the internet / outside clients. Examples:<br />
# Allow from 192.168.0.1<br />
# Allow from 192.168.1.1 192.168.1.2<br />
# Allow from 192.168.0.<br />
ProxyPass /preliminary balancer://oxcluster/preliminary<br />
</Location><br />
<br />
In case the "user=" sent by OX in the push_notification_driver url data does not match the IMAP login of a user, Dovecot ignores it. This can be overridden by defining "user_from_metadata" in the push_notification_driver url, e.g. <br />
<br />
push_notification_driver = ox:url=http://example.com/ user_from_metadata<br />
<br />
= Integrated Branding/Customization Concept for Partners and Customers =<br />
<br />
With OX Mail it is also possible for customers and partners to add branding elements to the app. During the installation of the app a user is presented with a list of preconfigured providers. When a provider is selected the app is automatically setup and branded for that provider.<br />
<br />
For both design reasons, as well as app store restrictions, branding in this context means:<br />
* The app design is “Super Flat”. This means there are not many elements that can be, or need to be, styled in order to match a particular brand.<br />
* The app does not contain or use any logos of any sort. <br />
* At install time the app uses a startup wizard in combination with a hosted configuration service. The wizard gives the end user the option to select a provider from a list. When this is done the app will retrieve the branding information from the configuration service and changes its theme accordingly. <br />
<br />
== Branding / Customization Process ==<br />
<br />
In order to participate you will need to provide specific information such as:<br />
<br />
* Confirmation that you are running OX App Suite 7.6.2 including the latest patch.<br />
* A full URL where your OX App Suite service can be reached by a web client.<br />
* Two test accounts on your OX App Suite service, where we can verify that the OX App Suite system works as expected.<br />
* A “logo” and “name” of your service. This information will be used in the app itself.<br />
* Optional: A preferred color (CI color) that Open-Xchange will use for the app if a user chooses their service from the provider list.<br />
<br />
=== Steps ===<br />
<br />
# Please download the Questionnaire from [http://knowledgebase.open-xchange.com/fileadmin/user_upload/open-xchange/document/misc/Questionnaire_OX_Mail_Branding.pdf Open-Xchange Download Server]<br />
# Please fill out the Questionnaire and send it to your Open-Xchange account manager.<br />
# Open-Xchange will check the data. If all information are available, Open-Xchange will add your personal brand to the live OX Mail app. Please Note: The exact date when your brand becomes available depends on the approval process and could take 5 to 10 days. Open-Xchange won't communicate an exact date. Please check by your self.<br />
<br />
[[Category: OX7]]<br />
[[Category: AppSuite]]<br />
[[Category: OXMailapp]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:OX_Drive&diff=17196AppSuite:OX Drive2014-03-05T08:10:22Z<p>Alexander.quast: /* Obtaining Push keys */</p>
<hr />
<div>= OX Drive =<br />
<br />
== Description ==<br />
<br />
OX Drive provides file and folder synchronization across devices. It does this in the simple way<br />
possible for the end user and is fully optimized for each device type.<br />
<br />
Open-Xchange wants to enable end customers to synchronize data. In OX App Suite, Open-Xchange provides a cloud storage called OX Drive. End customers should be able to synchronize Windows, Mac OS, Android, and iOS devices.<br />
<br />
This article explains how to set up the server-side components for OX Drive, as well as details about the client setup.<br />
<br />
== Availability ==<br />
OX Drive is a combination of two components:<br />
* OX Drive in OX App Suite<br />
* OX Drive Clients (optional native client components for synchronization)<br />
<br />
OX Drive is available for the following native clients:<br />
* OX Drive for Windows<br />
* OX Drive for Mac OS<br />
* OX Drive for iOS<br />
* OX Drive for Android<br />
<br />
== Requirements ==<br />
<br />
{|border="2" rules="all" align="left"><br />
|'''Requirement'''<br />
|'''System / Platform'''<br />
|'''Tested Devices'''<br />
|- <br />
|&nbsp;<br />
|&nbsp;<br />
|&nbsp;<br />
|-<br />
|OX App Suite<br />
|OX App Suite v7.4.2<br />
|&nbsp;<br />
|-<br />
|OX Drive for Windows<br />
|Latest Versions of Windows 7, Windows 8 (no support of Mac OS X clients with emulators and Windows RT)<br />
|&nbsp;<br />
|-<br />
|OX Drive for Mac OS<br />
|Mac OS X 10.8 (Mountain Lion), Mac OS X 10.9 (Mavericks)<br />
|&nbsp;<br />
|-<br />
|OX Drive for iOS<br />
|Apple iOS 6, Apple iOS 7<br />
|Apple iPhone 5, Apple iPhone 5s<br />
|-<br />
|OX Drive for Android<br />
|Smartphone on Android Jelly Bean (4.1 - 4.2), Tablets on Android Jelly Bean (4.1 - 4.2)<br />
|Samsung Galaxy S3 mini, Samsung Galaxy S4, Nexus 4<br />
|-<br />
|}<br />
<br />
== The key features of OX Drive ==<br />
* Native Apps for Windows, Mac OS, iOS and Android<br />
* Easy and attractive upsell properties (e.g. Upsell based on Quota limitations)<br />
* Clients are specially designed for the devices they run on taking into account limitations such as battery life, screen limitations, bandwidth etc.<br />
* Controlled synchronization of files across devices<br />
* Storage management (e.g. quota control, upload limits)<br />
* Connection type recognition and adaptation (e.g. Wi-Fi, cell network)<br />
<br />
= Server-side Installation and Configuration =<br />
<br />
This chapter describes how the backend components of OX Drive are installed and configured on the server.<br />
<br />
== Prerequisites ==<br />
<br />
* Open-Xchange Server v7.4.2 and above (''open-xchange-core'')<br />
* Grizzly HTTP connector (''open-xchange-grizzly''), see [[AppSuite:Grizzly]] for details, with ''Comet'' support enabled in ''grizzly.properties''<br />
* Valid Push-Certificates / API keys for cloud-based notifications, see configuration below<br />
* Enabled Hazelcast for inter-OX-communication, see [[AppSuite:Running_a_cluster]] for details<br />
<br />
== Available packages ==<br />
<br />
Open-Xchange Drive is available with the following backend packages:<br />
<br />
* ''open-xchange-drive'' - The main server components for OX Drive<br />
* ''open-xchange-drive-comet'' - Provides the Push interface via long-polling for the desktop clients<br />
* ''open-xchange-updater-drive'' - Adds the OX Drive application to the Windows desktop auto-updater<br />
* ''open-xchange-appsuite-help-drive-*'' - Online help in various languages for the OX Drive applications<br />
<br />
Install the above packages as usual.<br />
<br />
{{InstallPlugin|pluginname=open-xchange-drive open-xchange-drive-comet|toplevel=products|sopath=appsuite/stable/backend|version=App Suite}}<br />
<br />
== Configuration ==<br />
<br />
The following gives an overview about the most important settings to enable file synchronization via OX Drive, especially when it comes to real-time Push notifications for the client applications.<br />
<br />
<br />
=== General ===<br />
<br />
All settings regarding the OX Drive backend component are located in the configuration file ''drive.properties''. The default configuration should be sufficient for a basic "up-and-running" setup (with the exception of defining the Push certificates and API keys for cloud-based client notifications, see next chapters). Please refer to the inline documentation of the configuration file for more advanced options. <br />
<br />
=== Push via Google Cloud Messaging (GCM) ===<br />
<br />
The OX Drive application for Android devices is able to receive Push notifications from the Open-Xchange Server via [http://developer.android.com/google/gcm/index.html Google Cloud Messaging (GCM)]. To issue those Push messages, the backend needs to be provided with a suitable API key for the corresponding Android client application. This API key (a String) is specified in the ''drive.properties'' file:<br />
<br />
# Specifies the API key of the server application. Required.<br />
com.openexchange.drive.events.gcm.key=<br />
<br />
Doing so, Push via GCM can be enabled via:<br />
<br />
# Enables or disables push event notifications to clients using the Google<br />
# Cloud Messaging (GCM) service. This requires a valid configuration for the <br />
# GCM API key, see options below. Defaults to "false". <br />
com.openexchange.drive.events.gcm.enabled=true<br />
<br />
Depending on the used Android client application ("vanilla" or customized versions), different API keys are needed. Please refer to your Open-Xchange contact for details.<br />
<br />
=== Push via Apple Push Notification service (APNs) ===<br />
<br />
The OX Drive application for iOS and Mac OS devices is able to receive Push notifications from the Open-Xchange Server via [http://developer.apple.com/library/IOS/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html Push via Apple Push Notification service (APNs)]. To issue those Push messages, the backend needs to be provided with a suitable keystore container file (PKCS #12) containing the APNs certificate and keys. Note that the Mac OS desktop client and the iOS mobile client are served with separately with different certificates, so that both needs to be configured independantly in the configuration file. The following only shows the setup for iOS. First, the path to the PKCS #12 container file needs to be specified at:<br />
<br />
# Specifies the path to the local keystore file (PKCS #12) containing the APNS <br />
# certificate and keys for the iOS application, e.g. <br />
# "/opt/open-xchange/etc/drive-apns.p12". Required if <br />
# "com.openexchange.drive.events.apn.enabled" is "true".<br />
com.openexchange.drive.events.apn.ios.keystore=<br />
<br />
This file is opened by the backend using the password as supplied via: <br />
<br />
# Specifies the password used when creating the referenced keystore containing<br />
# the certificate of the iOS application. Note that blank or null passwords <br />
# are in violation of the PKCS #12 specifications. Required if <br />
# "com.openexchange.drive.events.apn.enabled" is "true".<br />
com.openexchange.drive.events.apn.ios.password=<br />
<br />
Configuration also allows to swith between development and production environments, however, this setting should be ''true'' normally:<br />
<br />
# Indicates which APNS service is used when sending push notifications to iOS<br />
# devices. A value of "true" will use the production service, a value of <br />
# "false" the sandbox service. Defaults to "true".<br />
com.openexchange.drive.events.apn.ios.production=true<br />
<br />
The OX backend contacts the APNs servers from time to time to get informed about clients no longer reachable clients where the applications was uninstalled. The interval can be defined with the following setting: <br />
<br />
# Configures the interval between queries to the APN feedback service for the<br />
# subscribed iOS devices. The value can be defined using units of measurement: <br />
# "D" (=days), "W" (=weeks) and "H" (=hours). Defaults to "1D" (one day). <br />
# Leaving this parameter empty disables the feedback queries on this node. <br />
# Since each received feedback is processed cluster-wide, only one node in the <br />
# cluster should be enabled here. <br />
com.openexchange.drive.events.apn.ios.feedbackQueryInterval=1D<br />
<br />
Please note that if you have multiple backend nodes in the cluster, it's recommended that only one node is configured to contact the feedback query service. Finally, Push notifications via APN for iOS can be enabled via:<br />
<br />
# Enables or disables push event notifications to clients using the Apple Push<br />
# Notification service (APNS) for iOS devices. This requires a valid <br />
# configuration for the APNS certificate and keys, see options below. <br />
# Defaults to "false". <br />
com.openexchange.drive.events.apn.ios.enabled=false<br />
<br />
As stated above, configuration for Push notifications via APN for the Mac OS desktop application is configured similarly, the relevant options are prefixed with ''com.openexchange.drive.events.apn.macos''. Depending on the used iOS and Mac OS client applications for your Server ("vanilla" or customized versions), different PKCS #12 container files and passwords are needed. Please refer to your Open-Xchange contact for details.<br />
<br />
=== Further Configuration ===<br />
<br />
* The backend component of OX Drive supplies the clients with various hyperlinks, e.g. deep-links to files and folders in the groupware webinterface or an URL to the online help. In order to point to the suitable web interface, please ensure that the correct UI web path is configured via ''com.openexchange.UIWebPath'' located in ''server.properties''.<br />
* As already mentioned above, the backend relies on the [https://grizzly.java.net/comet.html Comet] component of the Grizzly http connector for sending push notifications to the desktop clients. Therefore, ''com.openexchange.http.grizzly.hasCometEnabled'' needs to be set to ''true'' in ''grizzly.properties''.<br />
<br />
== Enabling OX Drive for Users ==<br />
<br />
OX Drive is enabled for all users that have the capability ''com.openexchange.capability.drive''. You can enable or disable this cabaility globally with the following setting in the ''drive.properties'' configuration file:<br />
<br />
# Enables or disables the "drive" module capability globally.<br />
com.openexchange.capability.drive=true<br />
<br />
More details about capabilities can be found at [[AppSuite:Capabilities]]. Furthermore, this capability can be defined in a more granular way using the Config Cascade as described at [[ConfigCascade]].<br />
<br />
= Installation of the Clients =<br />
<br />
== Installation of Mac OS X Desktop Client ==<br />
<br />
The OX Drive for Mac OS X will be provided via the Apple App Store.<br />
<br />
== Installation of Windows Desktop Client ==<br />
<br />
The OX Drive for Windows will be provided direct at the OX App Suite via the OX Updater.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|usm}}<br />
<br />
<br />
$ yum install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== Debian GNU/Linux 6.0 ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianSqueeze|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianSqueeze|usm}}<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== Debian GNU/Linux 7.0 ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|usm}}<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|usm}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
== Installation on Mobile Clients ==<br />
<br />
The OX Drive App is available via the different App Stores.<br />
<br />
== Client Configuration and Deployment ==<br />
<br />
The user defines a folder on the client that should be used for the future synchronization. Within this folder, the application creates a subfolder (e.g. per device) to prevent a heavy amount of data being transferred during <br />
the initial synchronization if e.g., a “wrong” directory (like C:\) has been selected. This folder is called Client Sync Folder. We might consider to relax this rule for the power user and allow to manually select<br />
the Client Sync Folder.<br />
<br />
Optionally, the user can select a private (user must be Admin of the folder) Server Sync Folder as source/target folder. If there is no folder selected a client specific folder can automatically be created and configured. If the Server Sync Folder is not selected, a device specific subfolder is created and configured as Server Sync Folder which of course is also created if not already existing.<br />
<br />
Assumption: The Client Sync Folder as well as the Server Sync Folder can not be changed after the configuration.<br />
* If the Client Sync Folder is not available, the synchronization will not be started.<br />
* If the Server Sync Folder is not available, the sync process will be aborted.<br />
<br />
As a default procedure, new sync folders should be created on the server as well as on the client. This ensures that objects are only synchronized as soon as this is done and the user has full control.<br />
<br />
== Sync Procedure ==<br />
<br />
* The client creates a list of the Client Sync Folder and - together with extended attributes (e.g. md5sums, file name, and path) - sends it to the server. Also, the last sync state (if existing) is sent to the server.<br />
* The server creates a list of the Server Sync Folder together with the extended attributes, compares them and creates an action list <br />
* The client saves the last sync state (either calculated by the server or created by the client)</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:OX_Drive&diff=17152AppSuite:OX Drive2014-02-25T11:21:48Z<p>Alexander.quast: /* Generating a CSR for APN */</p>
<hr />
<div>= OX Drive =<br />
<br />
== Description ==<br />
<br />
OX Drive provides file and folder synchronization across devices. It does this in the simple way<br />
possible for the end user and is fully optimized for each device type.<br />
<br />
Open-Xchange wants to enable end customers to synchronize data. In OX App Suite, Open-Xchange provides a cloud storage called OX Drive. End customers should be able to synchronize Windows, Mac OS, Android, and iOS devices.<br />
<br />
This article explains how to set up the server-side components for OX Drive, as well as details about the client setup.<br />
<br />
== Availability ==<br />
OX Drive is a combination of two components:<br />
* OX Drive in OX App Suite<br />
* OX Drive Clients (optional native client components for synchronization)<br />
<br />
OX Drive is available for the following native clients:<br />
* OX Drive for Windows<br />
* OX Drive for Mac OS<br />
* OX Drive for iOS<br />
* OX Drive for Android<br />
<br />
== Requirements ==<br />
<br />
{|border="2" rules="all" align="left"><br />
|'''Requirement'''<br />
|'''System / Platform'''<br />
|'''Tested Devices'''<br />
|- <br />
|&nbsp;<br />
|&nbsp;<br />
|&nbsp;<br />
|-<br />
|OX App Suite<br />
|OX App Suite v7.4.2<br />
|&nbsp;<br />
|-<br />
|OX Drive for Windows<br />
|Latest Versions of Windows 7, Windows 8 (no support of Mac OS X clients with emulators and Windows RT)<br />
|&nbsp;<br />
|-<br />
|OX Drive for Mac OS<br />
|Mac OS X 10.8 (Mountain Lion), Mac OS X 10.9 (Mavericks)<br />
|&nbsp;<br />
|-<br />
|OX Drive for iOS<br />
|Apple iOS 6, Apple iOS 7<br />
|Apple iPhone 5, Apple iPhone 5s<br />
|-<br />
|OX Drive for Android<br />
|Smartphone on Android Jelly Bean (4.1 - 4.2), Tablets on Android Jelly Bean (4.1 - 4.2)<br />
|Samsung Galaxy S3 mini, Samsung Galaxy S4, Nexus 4<br />
|-<br />
|}<br />
<br />
== The key features of OX Drive ==<br />
* Native Apps for Windows, Mac OS, iOS and Android<br />
* Easy and attractive upsell properties (e.g. Upsell based on Quota limitations)<br />
* Clients are specially designed for the devices they run on taking into account limitations such as battery life, screen limitations, bandwidth etc.<br />
* Controlled synchronization of files across devices<br />
* Storage management (e.g. quota control, upload limits)<br />
* Connection type recognition and adaptation (e.g. Wi-Fi, cell network)<br />
<br />
= Server-side Installation and Configuration =<br />
<br />
This chapter describes how the backend components of OX Drive are installed and configured on the server.<br />
<br />
== Prerequisites ==<br />
<br />
* Open-Xchange Server v7.4.2 and above (''open-xchange-core'')<br />
* Grizzly HTTP connector (''open-xchange-grizzly''), see [[AppSuite:Grizzly]] for details, with ''Comet'' support enabled in ''grizzly.properties''<br />
* Valid Push-Certificates / API keys for cloud-based notifications, see configuration below<br />
* Enabled Hazelcast for inter-OX-communication, see [[AppSuite:Running_a_cluster]] for details<br />
<br />
== Available packages ==<br />
<br />
Open-Xchange Drive is available with the following backend packages:<br />
<br />
* ''open-xchange-drive'' - The main server components for OX Drive<br />
* ''open-xchange-drive-comet'' - Provides the Push interface via long-polling for the desktop clients<br />
* ''open-xchange-updater-drive'' - Adds the OX Drive application to the Windows desktop auto-updater<br />
* ''open-xchange-appsuite-help-drive-*'' - Online help in various languages for the OX Drive applications<br />
<br />
Install the above packages as usual.<br />
<br />
{{InstallPlugin|pluginname=open-xchange-drive open-xchange-drive-comet|toplevel=products|sopath=appsuite/stable/backend|version=App Suite}}<br />
<br />
== Configuration ==<br />
<br />
The following gives an overview about the most important settings to enable file synchronization via OX Drive, especially when it comes to real-time Push notifications for the client applications.<br />
<br />
<br />
=== General ===<br />
<br />
All settings regarding the OX Drive backend component are located in the configuration file ''drive.properties''. The default configuration should be sufficient for a basic "up-and-running" setup (with the exception of defining the Push certificates and API keys for cloud-based client notifications, see next chapters). Please refer to the inline documentation of the configuration file for more advanced options. <br />
<br />
=== Push via Google Cloud Messaging (GCM) ===<br />
<br />
The OX Drive application for Android devices is able to receive Push notifications from the Open-Xchange Server via [http://developer.android.com/google/gcm/index.html Google Cloud Messaging (GCM)]. To issue those Push messages, the backend needs to be provided with a suitable API key for the corresponding Android client application. This API key (a String) is specified in the ''drive.properties'' file:<br />
<br />
# Specifies the API key of the server application. Required.<br />
com.openexchange.drive.events.gcm.key=<br />
<br />
Doing so, Push via GCM can be enabled via:<br />
<br />
# Enables or disables push event notifications to clients using the Google<br />
# Cloud Messaging (GCM) service. This requires a valid configuration for the <br />
# GCM API key, see options below. Defaults to "false". <br />
com.openexchange.drive.events.gcm.enabled=true<br />
<br />
Depending on the used Android client application ("vanilla" or customized versions), different API keys are needed. Please refer to your Open-Xchange contact for details.<br />
<br />
=== Push via Apple Push Notification service (APNs) ===<br />
<br />
The OX Drive application for iOS and Mac OS devices is able to receive Push notifications from the Open-Xchange Server via [http://developer.apple.com/library/IOS/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html Push via Apple Push Notification service (APNs)]. To issue those Push messages, the backend needs to be provided with a suitable keystore container file (PKCS #12) containing the APNs certificate and keys. Note that the Mac OS desktop client and the iOS mobile client are served with separately with different certificates, so that both needs to be configured independantly in the configuration file. The following only shows the setup for iOS. First, the path to the PKCS #12 container file needs to be specified at:<br />
<br />
# Specifies the path to the local keystore file (PKCS #12) containing the APNS <br />
# certificate and keys for the iOS application, e.g. <br />
# "/opt/open-xchange/etc/drive-apns.p12". Required if <br />
# "com.openexchange.drive.events.apn.enabled" is "true".<br />
com.openexchange.drive.events.apn.ios.keystore=<br />
<br />
This file is opened by the backend using the password as supplied via: <br />
<br />
# Specifies the password used when creating the referenced keystore containing<br />
# the certificate of the iOS application. Note that blank or null passwords <br />
# are in violation of the PKCS #12 specifications. Required if <br />
# "com.openexchange.drive.events.apn.enabled" is "true".<br />
com.openexchange.drive.events.apn.ios.password=<br />
<br />
Configuration also allows to swith between development and production environments, however, this setting should be ''true'' normally:<br />
<br />
# Indicates which APNS service is used when sending push notifications to iOS<br />
# devices. A value of "true" will use the production service, a value of <br />
# "false" the sandbox service. Defaults to "true".<br />
com.openexchange.drive.events.apn.ios.production=true<br />
<br />
The OX backend contacts the APNs servers from time to time to get informed about clients no longer reachable clients where the applications was uninstalled. The interval can be defined with the following setting: <br />
<br />
# Configures the interval between queries to the APN feedback service for the<br />
# subscribed iOS devices. The value can be defined using units of measurement: <br />
# "D" (=days), "W" (=weeks) and "H" (=hours). Defaults to "1D" (one day). <br />
# Leaving this parameter empty disables the feedback queries on this node. <br />
# Since each received feedback is processed cluster-wide, only one node in the <br />
# cluster should be enabled here. <br />
com.openexchange.drive.events.apn.ios.feedbackQueryInterval=1D<br />
<br />
Please note that if you have multiple backend nodes in the cluster, it's recommended that only one node is configured to contact the feedback query service. Finally, Push notifications via APN for iOS can be enabled via:<br />
<br />
# Enables or disables push event notifications to clients using the Apple Push<br />
# Notification service (APNS) for iOS devices. This requires a valid <br />
# configuration for the APNS certificate and keys, see options below. <br />
# Defaults to "false". <br />
com.openexchange.drive.events.apn.ios.enabled=false<br />
<br />
As stated above, configuration for Push notifications via APN for the Mac OS desktop application is configured similarly, the relevant options are prefixed with ''com.openexchange.drive.events.apn.macos''. Depending on the used iOS and Mac OS client applications for your Server ("vanilla" or customized versions), different PKCS #12 container files and passwords are needed. Please refer to your Open-Xchange contact for details.<br />
<br />
=== Further Configuration ===<br />
<br />
* The backend component of OX Drive supplies the clients with various hyperlinks, e.g. deep-links to files and folders in the groupware webinterface or an URL to the online help. In order to point to the suitable web interface, please ensure that the correct UI web path is configured via ''com.openexchange.UIWebPath'' located in ''server.properties''.<br />
* As already mentioned above, the backend relies on the [https://grizzly.java.net/comet.html Comet] component of the Grizzly http connector for sending push notifications to the desktop clients. Therefore, ''com.openexchange.http.grizzly.hasCometEnabled'' needs to be set to ''true'' in ''grizzly.properties''.<br />
<br />
=== Obtaining Push keys ===<br />
<br />
If you do have a valid contract for using OX Drive and are going to use the OX labeled clients you can retrieve a GCM and APN push key from OX.<br />
<br />
OX will need the following informations to create a GCM push key and a APN push certificate:<br />
<br />
==== GCM (Android) ====<br />
* The IP(s) or subnet of the server(s) which will send push notifications to the GCM server<br />
<br />
==== APN (iOS and Mac) ====<br />
* One valid certificate signing request (CSR) for each client, iOS and Mac OS. A single CSR can not be used for both.<br />
<br />
====Generating a CSR for APN====<br />
<br />
To manually generate a Certificate, you need a Certificate Signing Request (CSR) file from your Mac.<br />
To create a CSR file, follow the instructions below to create one using Keychain Access.<br />
<br />
Create a CSR file.<br />
# In the Applications folder on your Mac, open the Utilities folder and launch Keychain Access.<br />
# Within the Keychain Access drop down menu, select Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority.<br />
# In the Certificate Information window, enter the following information:<br />
##In the User Email Address field, enter your email address.<br />
##In the Common Name field, create a name for your private key (e.g., Company Foo Key).<br />
##The CA Email Address field should be left empty.<br />
##In the "Request is" group, select the "Saved to disk" option.<br />
#Click Continue within Keychain Access to complete the CSR generating process.<br />
<br />
The CSR file should then be sent to your Prof. Services contact. You will then receive a certificate file from OX. The certificate must then be exported<br />
with your private key that was used to create the CSR to a P12 container.<br />
<br />
Generate a P12<br />
# Import the certificate to your Keychain<br />
# Select the certificate and your private key > export both as P12 container to disk<br />
<br />
The P12 should be kept securely on your server.<br />
<br />
== Enabling OX Drive for Users ==<br />
<br />
OX Drive is enabled for all users that have the capability ''com.openexchange.capability.drive''. You can enable or disable this cabaility globally with the following setting in the ''drive.properties'' configuration file:<br />
<br />
# Enables or disables the "drive" module capability globally.<br />
com.openexchange.capability.drive=true<br />
<br />
More details about capabilities can be found at [[AppSuite:Capabilities]]. Furthermore, this capability can be defined in a more granular way using the Config Cascade as described at [[ConfigCascade]].<br />
<br />
= Installation of the Clients =<br />
<br />
== Installation of Mac OS X Desktop Client ==<br />
<br />
The OX Drive for Mac OS X will be provided via the Apple App Store.<br />
<br />
== Installation of Windows Desktop Client ==<br />
<br />
The OX Drive for Windows will be provided direct at the OX App Suite via the OX Updater.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|usm}}<br />
<br />
<br />
$ yum install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== Debian GNU/Linux 6.0 ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianSqueeze|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianSqueeze|usm}}<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== Debian GNU/Linux 7.0 ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|usm}}<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|usm}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
== Installation on Mobile Clients ==<br />
<br />
The OX Drive App is available via the different App Stores.<br />
<br />
== Client Configuration and Deployment ==<br />
<br />
The user defines a folder on the client that should be used for the future synchronization. Within this folder, the application creates a subfolder (e.g. per device) to prevent a heavy amount of data being transferred during <br />
the initial synchronization if e.g., a “wrong” directory (like C:\) has been selected. This folder is called Client Sync Folder. We might consider to relax this rule for the power user and allow to manually select<br />
the Client Sync Folder.<br />
<br />
Optionally, the user can select a private (user must be Admin of the folder) Server Sync Folder as source/target folder. If there is no folder selected a client specific folder can automatically be created and configured. If the Server Sync Folder is not selected, a device specific subfolder is created and configured as Server Sync Folder which of course is also created if not already existing.<br />
<br />
Assumption: The Client Sync Folder as well as the Server Sync Folder can not be changed after the configuration.<br />
* If the Client Sync Folder is not available, the synchronization will not be started.<br />
* If the Server Sync Folder is not available, the sync process will be aborted.<br />
<br />
As a default procedure, new sync folders should be created on the server as well as on the client. This ensures that objects are only synchronized as soon as this is done and the user has full control.<br />
<br />
== Sync Procedure ==<br />
<br />
* The client creates a list of the Client Sync Folder and - together with extended attributes (e.g. md5sums, file name, and path) - sends it to the server. Also, the last sync state (if existing) is sent to the server.<br />
* The server creates a list of the Server Sync Folder together with the extended attributes, compares them and creates an action list <br />
* The client saves the last sync state (either calculated by the server or created by the client)</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:OX_Drive&diff=17151AppSuite:OX Drive2014-02-25T11:02:44Z<p>Alexander.quast: /* APN (iOS and Mac) */</p>
<hr />
<div>= OX Drive =<br />
<br />
== Description ==<br />
<br />
OX Drive provides file and folder synchronization across devices. It does this in the simple way<br />
possible for the end user and is fully optimized for each device type.<br />
<br />
Open-Xchange wants to enable end customers to synchronize data. In OX App Suite, Open-Xchange provides a cloud storage called OX Drive. End customers should be able to synchronize Windows, Mac OS, Android, and iOS devices.<br />
<br />
This article explains how to set up the server-side components for OX Drive, as well as details about the client setup.<br />
<br />
== Availability ==<br />
OX Drive is a combination of two components:<br />
* OX Drive in OX App Suite<br />
* OX Drive Clients (optional native client components for synchronization)<br />
<br />
OX Drive is available for the following native clients:<br />
* OX Drive for Windows<br />
* OX Drive for Mac OS<br />
* OX Drive for iOS<br />
* OX Drive for Android<br />
<br />
== Requirements ==<br />
<br />
{|border="2" rules="all" align="left"><br />
|'''Requirement'''<br />
|'''System / Platform'''<br />
|'''Tested Devices'''<br />
|- <br />
|&nbsp;<br />
|&nbsp;<br />
|&nbsp;<br />
|-<br />
|OX App Suite<br />
|OX App Suite v7.4.2<br />
|&nbsp;<br />
|-<br />
|OX Drive for Windows<br />
|Latest Versions of Windows 7, Windows 8 (no support of Mac OS X clients with emulators and Windows RT)<br />
|&nbsp;<br />
|-<br />
|OX Drive for Mac OS<br />
|Mac OS X 10.8 (Mountain Lion), Mac OS X 10.9 (Mavericks)<br />
|&nbsp;<br />
|-<br />
|OX Drive for iOS<br />
|Apple iOS 6, Apple iOS 7<br />
|Apple iPhone 5, Apple iPhone 5s<br />
|-<br />
|OX Drive for Android<br />
|Smartphone on Android Jelly Bean (4.1 - 4.2), Tablets on Android Jelly Bean (4.1 - 4.2)<br />
|Samsung Galaxy S3 mini, Samsung Galaxy S4, Nexus 4<br />
|-<br />
|}<br />
<br />
== The key features of OX Drive ==<br />
* Native Apps for Windows, Mac OS, iOS and Android<br />
* Easy and attractive upsell properties (e.g. Upsell based on Quota limitations)<br />
* Clients are specially designed for the devices they run on taking into account limitations such as battery life, screen limitations, bandwidth etc.<br />
* Controlled synchronization of files across devices<br />
* Storage management (e.g. quota control, upload limits)<br />
* Connection type recognition and adaptation (e.g. Wi-Fi, cell network)<br />
<br />
= Server-side Installation and Configuration =<br />
<br />
This chapter describes how the backend components of OX Drive are installed and configured on the server.<br />
<br />
== Prerequisites ==<br />
<br />
* Open-Xchange Server v7.4.2 and above (''open-xchange-core'')<br />
* Grizzly HTTP connector (''open-xchange-grizzly''), see [[AppSuite:Grizzly]] for details, with ''Comet'' support enabled in ''grizzly.properties''<br />
* Valid Push-Certificates / API keys for cloud-based notifications, see configuration below<br />
* Enabled Hazelcast for inter-OX-communication, see [[AppSuite:Running_a_cluster]] for details<br />
<br />
== Available packages ==<br />
<br />
Open-Xchange Drive is available with the following backend packages:<br />
<br />
* ''open-xchange-drive'' - The main server components for OX Drive<br />
* ''open-xchange-drive-comet'' - Provides the Push interface via long-polling for the desktop clients<br />
* ''open-xchange-updater-drive'' - Adds the OX Drive application to the Windows desktop auto-updater<br />
* ''open-xchange-appsuite-help-drive-*'' - Online help in various languages for the OX Drive applications<br />
<br />
Install the above packages as usual.<br />
<br />
{{InstallPlugin|pluginname=open-xchange-drive open-xchange-drive-comet|toplevel=products|sopath=appsuite/stable/backend|version=App Suite}}<br />
<br />
== Configuration ==<br />
<br />
The following gives an overview about the most important settings to enable file synchronization via OX Drive, especially when it comes to real-time Push notifications for the client applications.<br />
<br />
<br />
=== General ===<br />
<br />
All settings regarding the OX Drive backend component are located in the configuration file ''drive.properties''. The default configuration should be sufficient for a basic "up-and-running" setup (with the exception of defining the Push certificates and API keys for cloud-based client notifications, see next chapters). Please refer to the inline documentation of the configuration file for more advanced options. <br />
<br />
=== Push via Google Cloud Messaging (GCM) ===<br />
<br />
The OX Drive application for Android devices is able to receive Push notifications from the Open-Xchange Server via [http://developer.android.com/google/gcm/index.html Google Cloud Messaging (GCM)]. To issue those Push messages, the backend needs to be provided with a suitable API key for the corresponding Android client application. This API key (a String) is specified in the ''drive.properties'' file:<br />
<br />
# Specifies the API key of the server application. Required.<br />
com.openexchange.drive.events.gcm.key=<br />
<br />
Doing so, Push via GCM can be enabled via:<br />
<br />
# Enables or disables push event notifications to clients using the Google<br />
# Cloud Messaging (GCM) service. This requires a valid configuration for the <br />
# GCM API key, see options below. Defaults to "false". <br />
com.openexchange.drive.events.gcm.enabled=true<br />
<br />
Depending on the used Android client application ("vanilla" or customized versions), different API keys are needed. Please refer to your Open-Xchange contact for details.<br />
<br />
=== Push via Apple Push Notification service (APNs) ===<br />
<br />
The OX Drive application for iOS and Mac OS devices is able to receive Push notifications from the Open-Xchange Server via [http://developer.apple.com/library/IOS/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html Push via Apple Push Notification service (APNs)]. To issue those Push messages, the backend needs to be provided with a suitable keystore container file (PKCS #12) containing the APNs certificate and keys. Note that the Mac OS desktop client and the iOS mobile client are served with separately with different certificates, so that both needs to be configured independantly in the configuration file. The following only shows the setup for iOS. First, the path to the PKCS #12 container file needs to be specified at:<br />
<br />
# Specifies the path to the local keystore file (PKCS #12) containing the APNS <br />
# certificate and keys for the iOS application, e.g. <br />
# "/opt/open-xchange/etc/drive-apns.p12". Required if <br />
# "com.openexchange.drive.events.apn.enabled" is "true".<br />
com.openexchange.drive.events.apn.ios.keystore=<br />
<br />
This file is opened by the backend using the password as supplied via: <br />
<br />
# Specifies the password used when creating the referenced keystore containing<br />
# the certificate of the iOS application. Note that blank or null passwords <br />
# are in violation of the PKCS #12 specifications. Required if <br />
# "com.openexchange.drive.events.apn.enabled" is "true".<br />
com.openexchange.drive.events.apn.ios.password=<br />
<br />
Configuration also allows to swith between development and production environments, however, this setting should be ''true'' normally:<br />
<br />
# Indicates which APNS service is used when sending push notifications to iOS<br />
# devices. A value of "true" will use the production service, a value of <br />
# "false" the sandbox service. Defaults to "true".<br />
com.openexchange.drive.events.apn.ios.production=true<br />
<br />
The OX backend contacts the APNs servers from time to time to get informed about clients no longer reachable clients where the applications was uninstalled. The interval can be defined with the following setting: <br />
<br />
# Configures the interval between queries to the APN feedback service for the<br />
# subscribed iOS devices. The value can be defined using units of measurement: <br />
# "D" (=days), "W" (=weeks) and "H" (=hours). Defaults to "1D" (one day). <br />
# Leaving this parameter empty disables the feedback queries on this node. <br />
# Since each received feedback is processed cluster-wide, only one node in the <br />
# cluster should be enabled here. <br />
com.openexchange.drive.events.apn.ios.feedbackQueryInterval=1D<br />
<br />
Please note that if you have multiple backend nodes in the cluster, it's recommended that only one node is configured to contact the feedback query service. Finally, Push notifications via APN for iOS can be enabled via:<br />
<br />
# Enables or disables push event notifications to clients using the Apple Push<br />
# Notification service (APNS) for iOS devices. This requires a valid <br />
# configuration for the APNS certificate and keys, see options below. <br />
# Defaults to "false". <br />
com.openexchange.drive.events.apn.ios.enabled=false<br />
<br />
As stated above, configuration for Push notifications via APN for the Mac OS desktop application is configured similarly, the relevant options are prefixed with ''com.openexchange.drive.events.apn.macos''. Depending on the used iOS and Mac OS client applications for your Server ("vanilla" or customized versions), different PKCS #12 container files and passwords are needed. Please refer to your Open-Xchange contact for details.<br />
<br />
=== Further Configuration ===<br />
<br />
* The backend component of OX Drive supplies the clients with various hyperlinks, e.g. deep-links to files and folders in the groupware webinterface or an URL to the online help. In order to point to the suitable web interface, please ensure that the correct UI web path is configured via ''com.openexchange.UIWebPath'' located in ''server.properties''.<br />
* As already mentioned above, the backend relies on the [https://grizzly.java.net/comet.html Comet] component of the Grizzly http connector for sending push notifications to the desktop clients. Therefore, ''com.openexchange.http.grizzly.hasCometEnabled'' needs to be set to ''true'' in ''grizzly.properties''.<br />
<br />
=== Obtaining Push keys ===<br />
<br />
If you do have a valid contract for using OX Drive and are going to use the OX labeled clients you can retrieve a GCM and APN push key from OX.<br />
<br />
OX will need the following informations to create a GCM push key and a APN push certificate:<br />
<br />
==== GCM (Android) ====<br />
* The IP(s) or subnet of the server(s) which will send push notifications to the GCM server<br />
<br />
==== APN (iOS and Mac) ====<br />
* One valid certificate signing request (CSR) for each client, iOS and Mac OS. A single CSR can not be used for both.<br />
<br />
====Generating a CSR for APN====<br />
<br />
To manually generate a Certificate, you need a Certificate Signing Request (CSR) file from your Mac.<br />
To create a CSR file, follow the instructions below to create one using Keychain Access.<br />
<br />
Create a CSR file.<br />
# In the Applications folder on your Mac, open the Utilities folder and launch Keychain Access.<br />
# Within the Keychain Access drop down menu, select Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority.<br />
# In the Certificate Information window, enter the following information:<br />
##In the User Email Address field, enter your email address.<br />
##In the Common Name field, create a name for your private key (e.g., Company Foo Key).<br />
##The CA Email Address field should be left empty.<br />
##In the "Request is" group, select the "Saved to disk" option.<br />
#Click Continue within Keychain Access to complete the CSR generating process.<br />
<br />
== Enabling OX Drive for Users ==<br />
<br />
OX Drive is enabled for all users that have the capability ''com.openexchange.capability.drive''. You can enable or disable this cabaility globally with the following setting in the ''drive.properties'' configuration file:<br />
<br />
# Enables or disables the "drive" module capability globally.<br />
com.openexchange.capability.drive=true<br />
<br />
More details about capabilities can be found at [[AppSuite:Capabilities]]. Furthermore, this capability can be defined in a more granular way using the Config Cascade as described at [[ConfigCascade]].<br />
<br />
= Installation of the Clients =<br />
<br />
== Installation of Mac OS X Desktop Client ==<br />
<br />
The OX Drive for Mac OS X will be provided via the Apple App Store.<br />
<br />
== Installation of Windows Desktop Client ==<br />
<br />
The OX Drive for Windows will be provided direct at the OX App Suite via the OX Updater.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|usm}}<br />
<br />
<br />
$ yum install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== Debian GNU/Linux 6.0 ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianSqueeze|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianSqueeze|usm}}<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== Debian GNU/Linux 7.0 ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|usm}}<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|usm}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
== Installation on Mobile Clients ==<br />
<br />
The OX Drive App is available via the different App Stores.<br />
<br />
== Client Configuration and Deployment ==<br />
<br />
The user defines a folder on the client that should be used for the future synchronization. Within this folder, the application creates a subfolder (e.g. per device) to prevent a heavy amount of data being transferred during <br />
the initial synchronization if e.g., a “wrong” directory (like C:\) has been selected. This folder is called Client Sync Folder. We might consider to relax this rule for the power user and allow to manually select<br />
the Client Sync Folder.<br />
<br />
Optionally, the user can select a private (user must be Admin of the folder) Server Sync Folder as source/target folder. If there is no folder selected a client specific folder can automatically be created and configured. If the Server Sync Folder is not selected, a device specific subfolder is created and configured as Server Sync Folder which of course is also created if not already existing.<br />
<br />
Assumption: The Client Sync Folder as well as the Server Sync Folder can not be changed after the configuration.<br />
* If the Client Sync Folder is not available, the synchronization will not be started.<br />
* If the Server Sync Folder is not available, the sync process will be aborted.<br />
<br />
As a default procedure, new sync folders should be created on the server as well as on the client. This ensures that objects are only synchronized as soon as this is done and the user has full control.<br />
<br />
== Sync Procedure ==<br />
<br />
* The client creates a list of the Client Sync Folder and - together with extended attributes (e.g. md5sums, file name, and path) - sends it to the server. Also, the last sync state (if existing) is sent to the server.<br />
* The server creates a list of the Server Sync Folder together with the extended attributes, compares them and creates an action list <br />
* The client saves the last sync state (either calculated by the server or created by the client)</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:OX_Drive&diff=17150AppSuite:OX Drive2014-02-25T11:00:54Z<p>Alexander.quast: /* Obtaining Push keys */</p>
<hr />
<div>= OX Drive =<br />
<br />
== Description ==<br />
<br />
OX Drive provides file and folder synchronization across devices. It does this in the simple way<br />
possible for the end user and is fully optimized for each device type.<br />
<br />
Open-Xchange wants to enable end customers to synchronize data. In OX App Suite, Open-Xchange provides a cloud storage called OX Drive. End customers should be able to synchronize Windows, Mac OS, Android, and iOS devices.<br />
<br />
This article explains how to set up the server-side components for OX Drive, as well as details about the client setup.<br />
<br />
== Availability ==<br />
OX Drive is a combination of two components:<br />
* OX Drive in OX App Suite<br />
* OX Drive Clients (optional native client components for synchronization)<br />
<br />
OX Drive is available for the following native clients:<br />
* OX Drive for Windows<br />
* OX Drive for Mac OS<br />
* OX Drive for iOS<br />
* OX Drive for Android<br />
<br />
== Requirements ==<br />
<br />
{|border="2" rules="all" align="left"><br />
|'''Requirement'''<br />
|'''System / Platform'''<br />
|'''Tested Devices'''<br />
|- <br />
|&nbsp;<br />
|&nbsp;<br />
|&nbsp;<br />
|-<br />
|OX App Suite<br />
|OX App Suite v7.4.2<br />
|&nbsp;<br />
|-<br />
|OX Drive for Windows<br />
|Latest Versions of Windows 7, Windows 8 (no support of Mac OS X clients with emulators and Windows RT)<br />
|&nbsp;<br />
|-<br />
|OX Drive for Mac OS<br />
|Mac OS X 10.8 (Mountain Lion), Mac OS X 10.9 (Mavericks)<br />
|&nbsp;<br />
|-<br />
|OX Drive for iOS<br />
|Apple iOS 6, Apple iOS 7<br />
|Apple iPhone 5, Apple iPhone 5s<br />
|-<br />
|OX Drive for Android<br />
|Smartphone on Android Jelly Bean (4.1 - 4.2), Tablets on Android Jelly Bean (4.1 - 4.2)<br />
|Samsung Galaxy S3 mini, Samsung Galaxy S4, Nexus 4<br />
|-<br />
|}<br />
<br />
== The key features of OX Drive ==<br />
* Native Apps for Windows, Mac OS, iOS and Android<br />
* Easy and attractive upsell properties (e.g. Upsell based on Quota limitations)<br />
* Clients are specially designed for the devices they run on taking into account limitations such as battery life, screen limitations, bandwidth etc.<br />
* Controlled synchronization of files across devices<br />
* Storage management (e.g. quota control, upload limits)<br />
* Connection type recognition and adaptation (e.g. Wi-Fi, cell network)<br />
<br />
= Server-side Installation and Configuration =<br />
<br />
This chapter describes how the backend components of OX Drive are installed and configured on the server.<br />
<br />
== Prerequisites ==<br />
<br />
* Open-Xchange Server v7.4.2 and above (''open-xchange-core'')<br />
* Grizzly HTTP connector (''open-xchange-grizzly''), see [[AppSuite:Grizzly]] for details, with ''Comet'' support enabled in ''grizzly.properties''<br />
* Valid Push-Certificates / API keys for cloud-based notifications, see configuration below<br />
* Enabled Hazelcast for inter-OX-communication, see [[AppSuite:Running_a_cluster]] for details<br />
<br />
== Available packages ==<br />
<br />
Open-Xchange Drive is available with the following backend packages:<br />
<br />
* ''open-xchange-drive'' - The main server components for OX Drive<br />
* ''open-xchange-drive-comet'' - Provides the Push interface via long-polling for the desktop clients<br />
* ''open-xchange-updater-drive'' - Adds the OX Drive application to the Windows desktop auto-updater<br />
* ''open-xchange-appsuite-help-drive-*'' - Online help in various languages for the OX Drive applications<br />
<br />
Install the above packages as usual.<br />
<br />
{{InstallPlugin|pluginname=open-xchange-drive open-xchange-drive-comet|toplevel=products|sopath=appsuite/stable/backend|version=App Suite}}<br />
<br />
== Configuration ==<br />
<br />
The following gives an overview about the most important settings to enable file synchronization via OX Drive, especially when it comes to real-time Push notifications for the client applications.<br />
<br />
<br />
=== General ===<br />
<br />
All settings regarding the OX Drive backend component are located in the configuration file ''drive.properties''. The default configuration should be sufficient for a basic "up-and-running" setup (with the exception of defining the Push certificates and API keys for cloud-based client notifications, see next chapters). Please refer to the inline documentation of the configuration file for more advanced options. <br />
<br />
=== Push via Google Cloud Messaging (GCM) ===<br />
<br />
The OX Drive application for Android devices is able to receive Push notifications from the Open-Xchange Server via [http://developer.android.com/google/gcm/index.html Google Cloud Messaging (GCM)]. To issue those Push messages, the backend needs to be provided with a suitable API key for the corresponding Android client application. This API key (a String) is specified in the ''drive.properties'' file:<br />
<br />
# Specifies the API key of the server application. Required.<br />
com.openexchange.drive.events.gcm.key=<br />
<br />
Doing so, Push via GCM can be enabled via:<br />
<br />
# Enables or disables push event notifications to clients using the Google<br />
# Cloud Messaging (GCM) service. This requires a valid configuration for the <br />
# GCM API key, see options below. Defaults to "false". <br />
com.openexchange.drive.events.gcm.enabled=true<br />
<br />
Depending on the used Android client application ("vanilla" or customized versions), different API keys are needed. Please refer to your Open-Xchange contact for details.<br />
<br />
=== Push via Apple Push Notification service (APNs) ===<br />
<br />
The OX Drive application for iOS and Mac OS devices is able to receive Push notifications from the Open-Xchange Server via [http://developer.apple.com/library/IOS/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html Push via Apple Push Notification service (APNs)]. To issue those Push messages, the backend needs to be provided with a suitable keystore container file (PKCS #12) containing the APNs certificate and keys. Note that the Mac OS desktop client and the iOS mobile client are served with separately with different certificates, so that both needs to be configured independantly in the configuration file. The following only shows the setup for iOS. First, the path to the PKCS #12 container file needs to be specified at:<br />
<br />
# Specifies the path to the local keystore file (PKCS #12) containing the APNS <br />
# certificate and keys for the iOS application, e.g. <br />
# "/opt/open-xchange/etc/drive-apns.p12". Required if <br />
# "com.openexchange.drive.events.apn.enabled" is "true".<br />
com.openexchange.drive.events.apn.ios.keystore=<br />
<br />
This file is opened by the backend using the password as supplied via: <br />
<br />
# Specifies the password used when creating the referenced keystore containing<br />
# the certificate of the iOS application. Note that blank or null passwords <br />
# are in violation of the PKCS #12 specifications. Required if <br />
# "com.openexchange.drive.events.apn.enabled" is "true".<br />
com.openexchange.drive.events.apn.ios.password=<br />
<br />
Configuration also allows to swith between development and production environments, however, this setting should be ''true'' normally:<br />
<br />
# Indicates which APNS service is used when sending push notifications to iOS<br />
# devices. A value of "true" will use the production service, a value of <br />
# "false" the sandbox service. Defaults to "true".<br />
com.openexchange.drive.events.apn.ios.production=true<br />
<br />
The OX backend contacts the APNs servers from time to time to get informed about clients no longer reachable clients where the applications was uninstalled. The interval can be defined with the following setting: <br />
<br />
# Configures the interval between queries to the APN feedback service for the<br />
# subscribed iOS devices. The value can be defined using units of measurement: <br />
# "D" (=days), "W" (=weeks) and "H" (=hours). Defaults to "1D" (one day). <br />
# Leaving this parameter empty disables the feedback queries on this node. <br />
# Since each received feedback is processed cluster-wide, only one node in the <br />
# cluster should be enabled here. <br />
com.openexchange.drive.events.apn.ios.feedbackQueryInterval=1D<br />
<br />
Please note that if you have multiple backend nodes in the cluster, it's recommended that only one node is configured to contact the feedback query service. Finally, Push notifications via APN for iOS can be enabled via:<br />
<br />
# Enables or disables push event notifications to clients using the Apple Push<br />
# Notification service (APNS) for iOS devices. This requires a valid <br />
# configuration for the APNS certificate and keys, see options below. <br />
# Defaults to "false". <br />
com.openexchange.drive.events.apn.ios.enabled=false<br />
<br />
As stated above, configuration for Push notifications via APN for the Mac OS desktop application is configured similarly, the relevant options are prefixed with ''com.openexchange.drive.events.apn.macos''. Depending on the used iOS and Mac OS client applications for your Server ("vanilla" or customized versions), different PKCS #12 container files and passwords are needed. Please refer to your Open-Xchange contact for details.<br />
<br />
=== Further Configuration ===<br />
<br />
* The backend component of OX Drive supplies the clients with various hyperlinks, e.g. deep-links to files and folders in the groupware webinterface or an URL to the online help. In order to point to the suitable web interface, please ensure that the correct UI web path is configured via ''com.openexchange.UIWebPath'' located in ''server.properties''.<br />
* As already mentioned above, the backend relies on the [https://grizzly.java.net/comet.html Comet] component of the Grizzly http connector for sending push notifications to the desktop clients. Therefore, ''com.openexchange.http.grizzly.hasCometEnabled'' needs to be set to ''true'' in ''grizzly.properties''.<br />
<br />
=== Obtaining Push keys ===<br />
<br />
If you do have a valid contract for using OX Drive and are going to use the OX labeled clients you can retrieve a GCM and APN push key from OX.<br />
<br />
OX will need the following informations to create a GCM push key and a APN push certificate:<br />
<br />
==== GCM (Android) ====<br />
* The IP(s) or subnet of the server(s) which will send push notifications to the GCM server<br />
<br />
==== APN (iOS and Mac) ====<br />
* A valid certificate signing request (CSR)<br />
<br />
====Generating a CSR for APN====<br />
<br />
To manually generate a Certificate, you need a Certificate Signing Request (CSR) file from your Mac.<br />
To create a CSR file, follow the instructions below to create one using Keychain Access.<br />
<br />
Create a CSR file.<br />
# In the Applications folder on your Mac, open the Utilities folder and launch Keychain Access.<br />
# Within the Keychain Access drop down menu, select Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority.<br />
# In the Certificate Information window, enter the following information:<br />
##In the User Email Address field, enter your email address.<br />
##In the Common Name field, create a name for your private key (e.g., Company Foo Key).<br />
##The CA Email Address field should be left empty.<br />
##In the "Request is" group, select the "Saved to disk" option.<br />
#Click Continue within Keychain Access to complete the CSR generating process.<br />
<br />
== Enabling OX Drive for Users ==<br />
<br />
OX Drive is enabled for all users that have the capability ''com.openexchange.capability.drive''. You can enable or disable this cabaility globally with the following setting in the ''drive.properties'' configuration file:<br />
<br />
# Enables or disables the "drive" module capability globally.<br />
com.openexchange.capability.drive=true<br />
<br />
More details about capabilities can be found at [[AppSuite:Capabilities]]. Furthermore, this capability can be defined in a more granular way using the Config Cascade as described at [[ConfigCascade]].<br />
<br />
= Installation of the Clients =<br />
<br />
== Installation of Mac OS X Desktop Client ==<br />
<br />
The OX Drive for Mac OS X will be provided via the Apple App Store.<br />
<br />
== Installation of Windows Desktop Client ==<br />
<br />
The OX Drive for Windows will be provided direct at the OX App Suite via the OX Updater.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|usm}}<br />
<br />
<br />
$ yum install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== Debian GNU/Linux 6.0 ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianSqueeze|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianSqueeze|usm}}<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== Debian GNU/Linux 7.0 ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|usm}}<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|usm}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
== Installation on Mobile Clients ==<br />
<br />
The OX Drive App is available via the different App Stores.<br />
<br />
== Client Configuration and Deployment ==<br />
<br />
The user defines a folder on the client that should be used for the future synchronization. Within this folder, the application creates a subfolder (e.g. per device) to prevent a heavy amount of data being transferred during <br />
the initial synchronization if e.g., a “wrong” directory (like C:\) has been selected. This folder is called Client Sync Folder. We might consider to relax this rule for the power user and allow to manually select<br />
the Client Sync Folder.<br />
<br />
Optionally, the user can select a private (user must be Admin of the folder) Server Sync Folder as source/target folder. If there is no folder selected a client specific folder can automatically be created and configured. If the Server Sync Folder is not selected, a device specific subfolder is created and configured as Server Sync Folder which of course is also created if not already existing.<br />
<br />
Assumption: The Client Sync Folder as well as the Server Sync Folder can not be changed after the configuration.<br />
* If the Client Sync Folder is not available, the synchronization will not be started.<br />
* If the Server Sync Folder is not available, the sync process will be aborted.<br />
<br />
As a default procedure, new sync folders should be created on the server as well as on the client. This ensures that objects are only synchronized as soon as this is done and the user has full control.<br />
<br />
== Sync Procedure ==<br />
<br />
* The client creates a list of the Client Sync Folder and - together with extended attributes (e.g. md5sums, file name, and path) - sends it to the server. Also, the last sync state (if existing) is sent to the server.<br />
* The server creates a list of the Server Sync Folder together with the extended attributes, compares them and creates an action list <br />
* The client saves the last sync state (either calculated by the server or created by the client)</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:OX_Drive&diff=17149AppSuite:OX Drive2014-02-25T10:59:32Z<p>Alexander.quast: /* Obtaining Push keys */</p>
<hr />
<div>= OX Drive =<br />
<br />
== Description ==<br />
<br />
OX Drive provides file and folder synchronization across devices. It does this in the simple way<br />
possible for the end user and is fully optimized for each device type.<br />
<br />
Open-Xchange wants to enable end customers to synchronize data. In OX App Suite, Open-Xchange provides a cloud storage called OX Drive. End customers should be able to synchronize Windows, Mac OS, Android, and iOS devices.<br />
<br />
This article explains how to set up the server-side components for OX Drive, as well as details about the client setup.<br />
<br />
== Availability ==<br />
OX Drive is a combination of two components:<br />
* OX Drive in OX App Suite<br />
* OX Drive Clients (optional native client components for synchronization)<br />
<br />
OX Drive is available for the following native clients:<br />
* OX Drive for Windows<br />
* OX Drive for Mac OS<br />
* OX Drive for iOS<br />
* OX Drive for Android<br />
<br />
== Requirements ==<br />
<br />
{|border="2" rules="all" align="left"><br />
|'''Requirement'''<br />
|'''System / Platform'''<br />
|'''Tested Devices'''<br />
|- <br />
|&nbsp;<br />
|&nbsp;<br />
|&nbsp;<br />
|-<br />
|OX App Suite<br />
|OX App Suite v7.4.2<br />
|&nbsp;<br />
|-<br />
|OX Drive for Windows<br />
|Latest Versions of Windows 7, Windows 8 (no support of Mac OS X clients with emulators and Windows RT)<br />
|&nbsp;<br />
|-<br />
|OX Drive for Mac OS<br />
|Mac OS X 10.8 (Mountain Lion), Mac OS X 10.9 (Mavericks)<br />
|&nbsp;<br />
|-<br />
|OX Drive for iOS<br />
|Apple iOS 6, Apple iOS 7<br />
|Apple iPhone 5, Apple iPhone 5s<br />
|-<br />
|OX Drive for Android<br />
|Smartphone on Android Jelly Bean (4.1 - 4.2), Tablets on Android Jelly Bean (4.1 - 4.2)<br />
|Samsung Galaxy S3 mini, Samsung Galaxy S4, Nexus 4<br />
|-<br />
|}<br />
<br />
== The key features of OX Drive ==<br />
* Native Apps for Windows, Mac OS, iOS and Android<br />
* Easy and attractive upsell properties (e.g. Upsell based on Quota limitations)<br />
* Clients are specially designed for the devices they run on taking into account limitations such as battery life, screen limitations, bandwidth etc.<br />
* Controlled synchronization of files across devices<br />
* Storage management (e.g. quota control, upload limits)<br />
* Connection type recognition and adaptation (e.g. Wi-Fi, cell network)<br />
<br />
= Server-side Installation and Configuration =<br />
<br />
This chapter describes how the backend components of OX Drive are installed and configured on the server.<br />
<br />
== Prerequisites ==<br />
<br />
* Open-Xchange Server v7.4.2 and above (''open-xchange-core'')<br />
* Grizzly HTTP connector (''open-xchange-grizzly''), see [[AppSuite:Grizzly]] for details, with ''Comet'' support enabled in ''grizzly.properties''<br />
* Valid Push-Certificates / API keys for cloud-based notifications, see configuration below<br />
* Enabled Hazelcast for inter-OX-communication, see [[AppSuite:Running_a_cluster]] for details<br />
<br />
== Available packages ==<br />
<br />
Open-Xchange Drive is available with the following backend packages:<br />
<br />
* ''open-xchange-drive'' - The main server components for OX Drive<br />
* ''open-xchange-drive-comet'' - Provides the Push interface via long-polling for the desktop clients<br />
* ''open-xchange-updater-drive'' - Adds the OX Drive application to the Windows desktop auto-updater<br />
* ''open-xchange-appsuite-help-drive-*'' - Online help in various languages for the OX Drive applications<br />
<br />
Install the above packages as usual.<br />
<br />
{{InstallPlugin|pluginname=open-xchange-drive open-xchange-drive-comet|toplevel=products|sopath=appsuite/stable/backend|version=App Suite}}<br />
<br />
== Configuration ==<br />
<br />
The following gives an overview about the most important settings to enable file synchronization via OX Drive, especially when it comes to real-time Push notifications for the client applications.<br />
<br />
<br />
=== General ===<br />
<br />
All settings regarding the OX Drive backend component are located in the configuration file ''drive.properties''. The default configuration should be sufficient for a basic "up-and-running" setup (with the exception of defining the Push certificates and API keys for cloud-based client notifications, see next chapters). Please refer to the inline documentation of the configuration file for more advanced options. <br />
<br />
=== Push via Google Cloud Messaging (GCM) ===<br />
<br />
The OX Drive application for Android devices is able to receive Push notifications from the Open-Xchange Server via [http://developer.android.com/google/gcm/index.html Google Cloud Messaging (GCM)]. To issue those Push messages, the backend needs to be provided with a suitable API key for the corresponding Android client application. This API key (a String) is specified in the ''drive.properties'' file:<br />
<br />
# Specifies the API key of the server application. Required.<br />
com.openexchange.drive.events.gcm.key=<br />
<br />
Doing so, Push via GCM can be enabled via:<br />
<br />
# Enables or disables push event notifications to clients using the Google<br />
# Cloud Messaging (GCM) service. This requires a valid configuration for the <br />
# GCM API key, see options below. Defaults to "false". <br />
com.openexchange.drive.events.gcm.enabled=true<br />
<br />
Depending on the used Android client application ("vanilla" or customized versions), different API keys are needed. Please refer to your Open-Xchange contact for details.<br />
<br />
=== Push via Apple Push Notification service (APNs) ===<br />
<br />
The OX Drive application for iOS and Mac OS devices is able to receive Push notifications from the Open-Xchange Server via [http://developer.apple.com/library/IOS/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html Push via Apple Push Notification service (APNs)]. To issue those Push messages, the backend needs to be provided with a suitable keystore container file (PKCS #12) containing the APNs certificate and keys. Note that the Mac OS desktop client and the iOS mobile client are served with separately with different certificates, so that both needs to be configured independantly in the configuration file. The following only shows the setup for iOS. First, the path to the PKCS #12 container file needs to be specified at:<br />
<br />
# Specifies the path to the local keystore file (PKCS #12) containing the APNS <br />
# certificate and keys for the iOS application, e.g. <br />
# "/opt/open-xchange/etc/drive-apns.p12". Required if <br />
# "com.openexchange.drive.events.apn.enabled" is "true".<br />
com.openexchange.drive.events.apn.ios.keystore=<br />
<br />
This file is opened by the backend using the password as supplied via: <br />
<br />
# Specifies the password used when creating the referenced keystore containing<br />
# the certificate of the iOS application. Note that blank or null passwords <br />
# are in violation of the PKCS #12 specifications. Required if <br />
# "com.openexchange.drive.events.apn.enabled" is "true".<br />
com.openexchange.drive.events.apn.ios.password=<br />
<br />
Configuration also allows to swith between development and production environments, however, this setting should be ''true'' normally:<br />
<br />
# Indicates which APNS service is used when sending push notifications to iOS<br />
# devices. A value of "true" will use the production service, a value of <br />
# "false" the sandbox service. Defaults to "true".<br />
com.openexchange.drive.events.apn.ios.production=true<br />
<br />
The OX backend contacts the APNs servers from time to time to get informed about clients no longer reachable clients where the applications was uninstalled. The interval can be defined with the following setting: <br />
<br />
# Configures the interval between queries to the APN feedback service for the<br />
# subscribed iOS devices. The value can be defined using units of measurement: <br />
# "D" (=days), "W" (=weeks) and "H" (=hours). Defaults to "1D" (one day). <br />
# Leaving this parameter empty disables the feedback queries on this node. <br />
# Since each received feedback is processed cluster-wide, only one node in the <br />
# cluster should be enabled here. <br />
com.openexchange.drive.events.apn.ios.feedbackQueryInterval=1D<br />
<br />
Please note that if you have multiple backend nodes in the cluster, it's recommended that only one node is configured to contact the feedback query service. Finally, Push notifications via APN for iOS can be enabled via:<br />
<br />
# Enables or disables push event notifications to clients using the Apple Push<br />
# Notification service (APNS) for iOS devices. This requires a valid <br />
# configuration for the APNS certificate and keys, see options below. <br />
# Defaults to "false". <br />
com.openexchange.drive.events.apn.ios.enabled=false<br />
<br />
As stated above, configuration for Push notifications via APN for the Mac OS desktop application is configured similarly, the relevant options are prefixed with ''com.openexchange.drive.events.apn.macos''. Depending on the used iOS and Mac OS client applications for your Server ("vanilla" or customized versions), different PKCS #12 container files and passwords are needed. Please refer to your Open-Xchange contact for details.<br />
<br />
=== Further Configuration ===<br />
<br />
* The backend component of OX Drive supplies the clients with various hyperlinks, e.g. deep-links to files and folders in the groupware webinterface or an URL to the online help. In order to point to the suitable web interface, please ensure that the correct UI web path is configured via ''com.openexchange.UIWebPath'' located in ''server.properties''.<br />
* As already mentioned above, the backend relies on the [https://grizzly.java.net/comet.html Comet] component of the Grizzly http connector for sending push notifications to the desktop clients. Therefore, ''com.openexchange.http.grizzly.hasCometEnabled'' needs to be set to ''true'' in ''grizzly.properties''.<br />
<br />
=== Obtaining Push keys ===<br />
<br />
If you do have a valid contract for using OX Drive and are going to use the OX labeled clients you can retrieve a GCM and APN push key via your support contact.<br />
<br />
Your supporter will need the following informations to create a GCM push key and a APN push certificate:<br />
<br />
==== GCM (Android) ====<br />
* The IP(s) or subnet of the server(s) which will send push notifications to the GCM server<br />
<br />
==== APN (iOS and Mac) ====<br />
* A valid certificate signing request (CSR)<br />
<br />
====Generating a CSR for APN====<br />
<br />
To manually generate a Certificate, you need a Certificate Signing Request (CSR) file from your Mac.<br />
To create a CSR file, follow the instructions below to create one using Keychain Access.<br />
<br />
Create a CSR file.<br />
# In the Applications folder on your Mac, open the Utilities folder and launch Keychain Access.<br />
# Within the Keychain Access drop down menu, select Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority.<br />
# In the Certificate Information window, enter the following information:<br />
##In the User Email Address field, enter your email address.<br />
##In the Common Name field, create a name for your private key (e.g., Company Foo Key).<br />
##The CA Email Address field should be left empty.<br />
##In the "Request is" group, select the "Saved to disk" option.<br />
#Click Continue within Keychain Access to complete the CSR generating process.<br />
<br />
== Enabling OX Drive for Users ==<br />
<br />
OX Drive is enabled for all users that have the capability ''com.openexchange.capability.drive''. You can enable or disable this cabaility globally with the following setting in the ''drive.properties'' configuration file:<br />
<br />
# Enables or disables the "drive" module capability globally.<br />
com.openexchange.capability.drive=true<br />
<br />
More details about capabilities can be found at [[AppSuite:Capabilities]]. Furthermore, this capability can be defined in a more granular way using the Config Cascade as described at [[ConfigCascade]].<br />
<br />
= Installation of the Clients =<br />
<br />
== Installation of Mac OS X Desktop Client ==<br />
<br />
The OX Drive for Mac OS X will be provided via the Apple App Store.<br />
<br />
== Installation of Windows Desktop Client ==<br />
<br />
The OX Drive for Windows will be provided direct at the OX App Suite via the OX Updater.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|usm}}<br />
<br />
<br />
$ yum install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== Debian GNU/Linux 6.0 ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianSqueeze|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianSqueeze|usm}}<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== Debian GNU/Linux 7.0 ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|usm}}<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|usm}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
== Installation on Mobile Clients ==<br />
<br />
The OX Drive App is available via the different App Stores.<br />
<br />
== Client Configuration and Deployment ==<br />
<br />
The user defines a folder on the client that should be used for the future synchronization. Within this folder, the application creates a subfolder (e.g. per device) to prevent a heavy amount of data being transferred during <br />
the initial synchronization if e.g., a “wrong” directory (like C:\) has been selected. This folder is called Client Sync Folder. We might consider to relax this rule for the power user and allow to manually select<br />
the Client Sync Folder.<br />
<br />
Optionally, the user can select a private (user must be Admin of the folder) Server Sync Folder as source/target folder. If there is no folder selected a client specific folder can automatically be created and configured. If the Server Sync Folder is not selected, a device specific subfolder is created and configured as Server Sync Folder which of course is also created if not already existing.<br />
<br />
Assumption: The Client Sync Folder as well as the Server Sync Folder can not be changed after the configuration.<br />
* If the Client Sync Folder is not available, the synchronization will not be started.<br />
* If the Server Sync Folder is not available, the sync process will be aborted.<br />
<br />
As a default procedure, new sync folders should be created on the server as well as on the client. This ensures that objects are only synchronized as soon as this is done and the user has full control.<br />
<br />
== Sync Procedure ==<br />
<br />
* The client creates a list of the Client Sync Folder and - together with extended attributes (e.g. md5sums, file name, and path) - sends it to the server. Also, the last sync state (if existing) is sent to the server.<br />
* The server creates a list of the Server Sync Folder together with the extended attributes, compares them and creates an action list <br />
* The client saves the last sync state (either calculated by the server or created by the client)</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:OX_Drive&diff=17148AppSuite:OX Drive2014-02-25T10:25:01Z<p>Alexander.quast: /* Further Configuration */</p>
<hr />
<div>= OX Drive =<br />
<br />
== Description ==<br />
<br />
OX Drive provides file and folder synchronization across devices. It does this in the simple way<br />
possible for the end user and is fully optimized for each device type.<br />
<br />
Open-Xchange wants to enable end customers to synchronize data. In OX App Suite, Open-Xchange provides a cloud storage called OX Drive. End customers should be able to synchronize Windows, Mac OS, Android, and iOS devices.<br />
<br />
This article explains how to set up the server-side components for OX Drive, as well as details about the client setup.<br />
<br />
== Availability ==<br />
OX Drive is a combination of two components:<br />
* OX Drive in OX App Suite<br />
* OX Drive Clients (optional native client components for synchronization)<br />
<br />
OX Drive is available for the following native clients:<br />
* OX Drive for Windows<br />
* OX Drive for Mac OS<br />
* OX Drive for iOS<br />
* OX Drive for Android<br />
<br />
== Requirements ==<br />
<br />
{|border="2" rules="all" align="left"><br />
|'''Requirement'''<br />
|'''System / Platform'''<br />
|'''Tested Devices'''<br />
|- <br />
|&nbsp;<br />
|&nbsp;<br />
|&nbsp;<br />
|-<br />
|OX App Suite<br />
|OX App Suite v7.4.2<br />
|&nbsp;<br />
|-<br />
|OX Drive for Windows<br />
|Latest Versions of Windows 7, Windows 8 (no support of Mac OS X clients with emulators and Windows RT)<br />
|&nbsp;<br />
|-<br />
|OX Drive for Mac OS<br />
|Mac OS X 10.8 (Mountain Lion), Mac OS X 10.9 (Mavericks)<br />
|&nbsp;<br />
|-<br />
|OX Drive for iOS<br />
|Apple iOS 6, Apple iOS 7<br />
|Apple iPhone 5, Apple iPhone 5s<br />
|-<br />
|OX Drive for Android<br />
|Smartphone on Android Jelly Bean (4.1 - 4.2), Tablets on Android Jelly Bean (4.1 - 4.2)<br />
|Samsung Galaxy S3 mini, Samsung Galaxy S4, Nexus 4<br />
|-<br />
|}<br />
<br />
== The key features of OX Drive ==<br />
* Native Apps for Windows, Mac OS, iOS and Android<br />
* Easy and attractive upsell properties (e.g. Upsell based on Quota limitations)<br />
* Clients are specially designed for the devices they run on taking into account limitations such as battery life, screen limitations, bandwidth etc.<br />
* Controlled synchronization of files across devices<br />
* Storage management (e.g. quota control, upload limits)<br />
* Connection type recognition and adaptation (e.g. Wi-Fi, cell network)<br />
<br />
= Server-side Installation and Configuration =<br />
<br />
This chapter describes how the backend components of OX Drive are installed and configured on the server.<br />
<br />
== Prerequisites ==<br />
<br />
* Open-Xchange Server v7.4.2 and above (''open-xchange-core'')<br />
* Grizzly HTTP connector (''open-xchange-grizzly''), see [[AppSuite:Grizzly]] for details, with ''Comet'' support enabled in ''grizzly.properties''<br />
* Valid Push-Certificates / API keys for cloud-based notifications, see configuration below<br />
* Enabled Hazelcast for inter-OX-communication, see [[AppSuite:Running_a_cluster]] for details<br />
<br />
== Available packages ==<br />
<br />
Open-Xchange Drive is available with the following backend packages:<br />
<br />
* ''open-xchange-drive'' - The main server components for OX Drive<br />
* ''open-xchange-drive-comet'' - Provides the Push interface via long-polling for the desktop clients<br />
* ''open-xchange-updater-drive'' - Adds the OX Drive application to the Windows desktop auto-updater<br />
* ''open-xchange-appsuite-help-drive-*'' - Online help in various languages for the OX Drive applications<br />
<br />
Install the above packages as usual.<br />
<br />
{{InstallPlugin|pluginname=open-xchange-drive open-xchange-drive-comet|toplevel=products|sopath=appsuite/stable/backend|version=App Suite}}<br />
<br />
== Configuration ==<br />
<br />
The following gives an overview about the most important settings to enable file synchronization via OX Drive, especially when it comes to real-time Push notifications for the client applications.<br />
<br />
<br />
=== General ===<br />
<br />
All settings regarding the OX Drive backend component are located in the configuration file ''drive.properties''. The default configuration should be sufficient for a basic "up-and-running" setup (with the exception of defining the Push certificates and API keys for cloud-based client notifications, see next chapters). Please refer to the inline documentation of the configuration file for more advanced options. <br />
<br />
=== Push via Google Cloud Messaging (GCM) ===<br />
<br />
The OX Drive application for Android devices is able to receive Push notifications from the Open-Xchange Server via [http://developer.android.com/google/gcm/index.html Google Cloud Messaging (GCM)]. To issue those Push messages, the backend needs to be provided with a suitable API key for the corresponding Android client application. This API key (a String) is specified in the ''drive.properties'' file:<br />
<br />
# Specifies the API key of the server application. Required.<br />
com.openexchange.drive.events.gcm.key=<br />
<br />
Doing so, Push via GCM can be enabled via:<br />
<br />
# Enables or disables push event notifications to clients using the Google<br />
# Cloud Messaging (GCM) service. This requires a valid configuration for the <br />
# GCM API key, see options below. Defaults to "false". <br />
com.openexchange.drive.events.gcm.enabled=true<br />
<br />
Depending on the used Android client application ("vanilla" or customized versions), different API keys are needed. Please refer to your Open-Xchange contact for details.<br />
<br />
=== Push via Apple Push Notification service (APNs) ===<br />
<br />
The OX Drive application for iOS and Mac OS devices is able to receive Push notifications from the Open-Xchange Server via [http://developer.apple.com/library/IOS/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html Push via Apple Push Notification service (APNs)]. To issue those Push messages, the backend needs to be provided with a suitable keystore container file (PKCS #12) containing the APNs certificate and keys. Note that the Mac OS desktop client and the iOS mobile client are served with separately with different certificates, so that both needs to be configured independantly in the configuration file. The following only shows the setup for iOS. First, the path to the PKCS #12 container file needs to be specified at:<br />
<br />
# Specifies the path to the local keystore file (PKCS #12) containing the APNS <br />
# certificate and keys for the iOS application, e.g. <br />
# "/opt/open-xchange/etc/drive-apns.p12". Required if <br />
# "com.openexchange.drive.events.apn.enabled" is "true".<br />
com.openexchange.drive.events.apn.ios.keystore=<br />
<br />
This file is opened by the backend using the password as supplied via: <br />
<br />
# Specifies the password used when creating the referenced keystore containing<br />
# the certificate of the iOS application. Note that blank or null passwords <br />
# are in violation of the PKCS #12 specifications. Required if <br />
# "com.openexchange.drive.events.apn.enabled" is "true".<br />
com.openexchange.drive.events.apn.ios.password=<br />
<br />
Configuration also allows to swith between development and production environments, however, this setting should be ''true'' normally:<br />
<br />
# Indicates which APNS service is used when sending push notifications to iOS<br />
# devices. A value of "true" will use the production service, a value of <br />
# "false" the sandbox service. Defaults to "true".<br />
com.openexchange.drive.events.apn.ios.production=true<br />
<br />
The OX backend contacts the APNs servers from time to time to get informed about clients no longer reachable clients where the applications was uninstalled. The interval can be defined with the following setting: <br />
<br />
# Configures the interval between queries to the APN feedback service for the<br />
# subscribed iOS devices. The value can be defined using units of measurement: <br />
# "D" (=days), "W" (=weeks) and "H" (=hours). Defaults to "1D" (one day). <br />
# Leaving this parameter empty disables the feedback queries on this node. <br />
# Since each received feedback is processed cluster-wide, only one node in the <br />
# cluster should be enabled here. <br />
com.openexchange.drive.events.apn.ios.feedbackQueryInterval=1D<br />
<br />
Please note that if you have multiple backend nodes in the cluster, it's recommended that only one node is configured to contact the feedback query service. Finally, Push notifications via APN for iOS can be enabled via:<br />
<br />
# Enables or disables push event notifications to clients using the Apple Push<br />
# Notification service (APNS) for iOS devices. This requires a valid <br />
# configuration for the APNS certificate and keys, see options below. <br />
# Defaults to "false". <br />
com.openexchange.drive.events.apn.ios.enabled=false<br />
<br />
As stated above, configuration for Push notifications via APN for the Mac OS desktop application is configured similarly, the relevant options are prefixed with ''com.openexchange.drive.events.apn.macos''. Depending on the used iOS and Mac OS client applications for your Server ("vanilla" or customized versions), different PKCS #12 container files and passwords are needed. Please refer to your Open-Xchange contact for details.<br />
<br />
=== Further Configuration ===<br />
<br />
* The backend component of OX Drive supplies the clients with various hyperlinks, e.g. deep-links to files and folders in the groupware webinterface or an URL to the online help. In order to point to the suitable web interface, please ensure that the correct UI web path is configured via ''com.openexchange.UIWebPath'' located in ''server.properties''.<br />
* As already mentioned above, the backend relies on the [https://grizzly.java.net/comet.html Comet] component of the Grizzly http connector for sending push notifications to the desktop clients. Therefore, ''com.openexchange.http.grizzly.hasCometEnabled'' needs to be set to ''true'' in ''grizzly.properties''.<br />
<br />
=== Obtaining Push keys ===<br />
<br />
== Enabling OX Drive for Users ==<br />
<br />
OX Drive is enabled for all users that have the capability ''com.openexchange.capability.drive''. You can enable or disable this cabaility globally with the following setting in the ''drive.properties'' configuration file:<br />
<br />
# Enables or disables the "drive" module capability globally.<br />
com.openexchange.capability.drive=true<br />
<br />
More details about capabilities can be found at [[AppSuite:Capabilities]]. Furthermore, this capability can be defined in a more granular way using the Config Cascade as described at [[ConfigCascade]].<br />
<br />
= Installation of the Clients =<br />
<br />
== Installation of Mac OS X Desktop Client ==<br />
<br />
The OX Drive for Mac OS X will be provided via the Apple App Store.<br />
<br />
== Installation of Windows Desktop Client ==<br />
<br />
The OX Drive for Windows will be provided direct at the OX App Suite via the OX Updater.<br />
<br />
=== Redhat Enterprise Linux 6 or CentOS 6 ===<br />
<br />
Add the following repositories to your Open-Xchange yum configuration:<br />
<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=YUMRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=rhelname|pc2v=RHEL6|usm}}<br />
<br />
<br />
$ yum install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== Debian GNU/Linux 6.0 ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianSqueeze|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianSqueeze|usm}}<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== Debian GNU/Linux 7.0 ===<br />
<br />
Add the following repositories to your Open-Xchange apt configuration:<br />
<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=APTRepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=debianname|pc2v=DebianWheezy|usm}}<br />
<br />
$ apt-get update<br />
$ apt-get install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
=== SUSE Linux Enterprise Server 11 ===<br />
<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|pc3n=ldbaccount|pc3v=LDBUSER:LDBPASSWORD|updater|usm/updates}}<br />
{{for loop||call=SUSERepo|pv=reponame|pc1n=path|pc1v=products/appsuite/stable|pc2n=susename|pc2v=SLES11|usm}}<br />
<br />
$ zypper ref<br />
$ zypper install open-xchange-updater-drive open-xchange-drive open-xchange-drive-comet<br />
<br />
== Installation on Mobile Clients ==<br />
<br />
The OX Drive App is available via the different App Stores.<br />
<br />
== Client Configuration and Deployment ==<br />
<br />
The user defines a folder on the client that should be used for the future synchronization. Within this folder, the application creates a subfolder (e.g. per device) to prevent a heavy amount of data being transferred during <br />
the initial synchronization if e.g., a “wrong” directory (like C:\) has been selected. This folder is called Client Sync Folder. We might consider to relax this rule for the power user and allow to manually select<br />
the Client Sync Folder.<br />
<br />
Optionally, the user can select a private (user must be Admin of the folder) Server Sync Folder as source/target folder. If there is no folder selected a client specific folder can automatically be created and configured. If the Server Sync Folder is not selected, a device specific subfolder is created and configured as Server Sync Folder which of course is also created if not already existing.<br />
<br />
Assumption: The Client Sync Folder as well as the Server Sync Folder can not be changed after the configuration.<br />
* If the Client Sync Folder is not available, the synchronization will not be started.<br />
* If the Server Sync Folder is not available, the sync process will be aborted.<br />
<br />
As a default procedure, new sync folders should be created on the server as well as on the client. This ensures that objects are only synchronized as soon as this is done and the user has full control.<br />
<br />
== Sync Procedure ==<br />
<br />
* The client creates a list of the Client Sync Folder and - together with extended attributes (e.g. md5sums, file name, and path) - sends it to the server. Also, the last sync state (if existing) is sent to the server.<br />
* The server creates a list of the Server Sync Folder together with the extended attributes, compares them and creates an action list <br />
* The client saves the last sync state (either calculated by the server or created by the client)</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=16892AppSuite:Theming2014-01-24T16:02:07Z<p>Alexander.quast: /* Favicon */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
=== Basic ===<br />
<br />
==== Font ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @baseFontSize || 14px<br />
|-<br />
| @baseFontFamily || @sansFontFamily<br />
|-<br />
| @baseLineHeight || 20px<br />
|-<br />
| @altFontFamily || @serifFontFamily<br />
|-<br />
| @touchFontSize || 15px<br />
|-<br />
| @headingsFontFamily || inherit<br />
|-<br />
| @headingsFontWeight || bold<br />
|-<br />
| @fontSizeLarge || @baseFontSize * 1.25<br />
|-<br />
| @fontSizeSmall || @baseFontSize * 0.85<br />
|-<br />
| @fontSizeMini || @baseFontSize * 0.75<br />
|-<br />
| @vgridFontSize || 13px<br />
|}<br />
<br />
==== Colors ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @bodyBackground || @white<br />
|-<br />
| @textColor || @grayDark<br />
|-<br />
| @linkColor || #08c<br />
|-<br />
| @linkColorHover || darken(@linkColor, 15%)<br />
|-<br />
| @linkAccentColor || #ffad00<br />
|-<br />
| @linkAccentColorHover || darken(@linkAccentColor, 15%)<br />
|-<br />
| @badgeColor || @white<br />
|-<br />
| @badgeBackground || #555<br />
|-<br />
| @headingsColor || inherit<br />
|-<br />
| @black || #000<br />
|-<br />
| @grayDarker || #222<br />
|-<br />
| @grayDark || #333<br />
|-<br />
| @gray || #555<br />
|-<br />
| @grayLight || #aaa<br />
|-<br />
| @grayLighter || #eee<br />
|-<br />
| @white || #fff<br />
|-<br />
| @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blueDark || #0064cd<br />
|-<br />
| @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || #1A8D1A<br />
|-<br />
| @greenLight || #92D050<br />
|-<br />
| @red || #cc0000<br />
|-<br />
| @yellow || #F8E400<br />
|-<br />
| @orange || #f89406<br />
|-<br />
| @pink || #E01CD9<br />
|-<br />
| @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
==== Space ====<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paddingLarge || 11px 19px<br />
|-<br />
| @paddingSmall || 2px 10px<br />
|-<br />
| @paddingMini || 0 6px<br />
|-<br />
| @baseBorderRadius || 4px<br />
|-<br />
| @borderRadiusLarge || 6px<br />
|-<br />
| @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paginationBackground || #fff<br />
|-<br />
| @paginationBorder || #ddd<br />
|-<br />
| @paginationActiveBackground || #f5f5f5<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @btnBackground || @white<br />
|-<br />
| @btnBackgroundHighlight || darken(@white, 10%)<br />
|-<br />
| @btnBorder || #bbb<br />
|-<br />
| @btnPrimaryBackground || @linkColor<br />
|-<br />
| @btnPrimaryBackgroundHighlight || spin(@btnPrimaryBackground, 20%)<br />
|-<br />
| @btnInfoBackground || #5bc0de<br />
|-<br />
| @btnInfoBackgroundHighlight || #2f96b4<br />
|-<br />
| @btnSuccessBackground || #62c462<br />
|-<br />
| @btnSuccessBackgroundHighlight || #51a351<br />
|-<br />
| @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| @btnWarningBackgroundHighlight || @orange<br />
|-<br />
| @btnDangerBackground || #ee5f5b<br />
|-<br />
| @btnDangerBackgroundHighlight || #bd362f<br />
|-<br />
| @btnInverseBackground || #444<br />
|-<br />
| @btnInverseBackgroundHighlight || @grayDarker<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @dropdownBackground || @white<br />
|-<br />
| @dropdownBorder || rgba(0,0,0,.2)<br />
|-<br />
| @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdownDividerBottom || @white<br />
|-<br />
| @dropdownLinkColor || @grayDark<br />
|-<br />
| @dropdownLinkColorHover || @white<br />
|-<br />
| @dropdownLinkColorActive || @white<br />
|-<br />
| @dropdownLinkBackgroundActive || @linkColor<br />
|-<br />
| @dropdownLinkBackgroundHover || @dropdownLinkBackgroundActive<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @foldertreeSidepanelBackground || #333 ||<br />
|-<br />
| @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertreeActiveLabelColor || #ccc || ''Active'' means, user can perform an action on this item<br />
|-<br />
| @foldertreePassiveLabelColor || #ccc || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertreeHoverBackground || #888 ||<br />
|-<br />
| @foldertreeSelectedBackground || #222 ||<br />
|-<br />
| @foldertreeBadgeBackground || @bagdeBackground || see [[#Colors]] for definition of @badgeBackground<br />
|-<br />
| @foldertreeBadgeColor ||@badgeColor || see [[#Colors]] for definition of @badgeBackground<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekviewTimeline || #f00 /* red */ || Color of the Line indicating the current time<br />
|-<br />
| @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre&lt;noinclude&gt;&lt;/noinclude&gt;>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre&lt;noinclude&gt;&lt;/noinclude&gt;> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
'''This documentation applies for AppSuite v.7.4.2'''<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers as long as you don't deliver your own icons with your theme. <br />
<br />
=== Favicon ===<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
You should provide your custom favicon within your custom theme. If you do not add a custom favicon to your theme the global OX default will be used. The default icon is located under <tt>apps/themes/icons/default</tt> on the web server.<br />
<br />
'''Attention:''' Safari and Internet Explorer do not support dynamic changes to the favicon for a webpage. This means, the default icon will be shown even if a custom favicon is provided within a custom theme. To enable the right favicon for a theme on Safari and IE, the overall standard <tt>favicon.ico</tt> located under <tt>apps/themes/icons/default</tt> on the web server must be replaced with a custom version.<br />
<br />
=== Apple touch icons ===<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. AppSuite offers full support for Webclips by providing all needed App icons, splashscreens and full screen support. If a user uses the "Add to homescreen" button on his iOS device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format.<br />
<br />
* iPhone 3: 57 x 57 px<br />
* iPhone 4 retina: 114x114 px<br />
* iPhone iPhone 5 retina: 120 x 120 px<br />
* iPad: 72 x 72 px<br />
* iPad (iOS 7): 76 x 76px<br />
* iPad retina: 144 x 144 px <br />
* iPad retina (iOS 7): 152 x 152 px <br />
<br />
Furthermore a fullscreen Webclip App will show a splashscreen, a jpg file that is displayed on startup during app load. There are currently three different resolutions as jpg files available. '''Note''': Splashscreens must be JPG files<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change with Apple's iOS updates. We recommend providing all of this resolutions when customizing the Webclip icons and splashscreens, even if some iOS devices use the next best resolution for an icon if a certain file is missing.<br />
<br />
=== Providing custom icons ===<br />
To provide custom Webclip icons locate the following path in the AppSuite installation on your web server:<br />
pathToAppSuite/apps/themes/icons/default<br />
<br />
This folder contains all OX default icons for Webclips icons and splashscreens. Use these as samples for your own versions.<br />
<br />
A clean installation will have all our default icons in the "default" directory. To customize the icons we recommend using our default icons as samples and save your customized version in your theme. '''Note''': The filename has to be the same as in the default folder. Otherwise the fallback will be applied and the default icons will be used. If more advanced rewriting is needed one should edit the contents of the <tt>.htaccess</tt> file located under <tt>apps/themes</tt><br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
=== Providing domain based login themes ===<br />
<br />
If you have a multibrand installation and you want to deliver not only custom themes but also custom login-themes this can be done via Apache mod_rewrite. You can do so by a domain-based rewrite rule to deliver custom themes to a user based on the URI he's using. The needed config file <tt>.htaccess</tt> is located under <tt>apps/themes</tt><br />
<br />
<pre><br />
# Sample config for domain based login theme<br />
RewriteCond %{HTTP_HOST} ^www\.domain\.com$<br />
RewriteCond %{REQUEST_FILENAME} -f<br />
RewriteRule ^login/(.*)$ domain_com_logintheme/$1 [L]<br />
</pre><br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Browserdetection&diff=16807AppSuite:Browserdetection2014-01-08T08:46:59Z<p>Alexander.quast: </p>
<hr />
<div>== Browser detection outside AppSuite ==<br />
[[File:loginpage.png|thumb|250px|This warning is not shown to a user if you use the form-login]]<br />
<br />
AppSuite detects the client browser and collects some information about the current device the visitor is using. These informations are used to serve the best UI and enable/disable certain features for his device. The browser detection is done by a standalone and dependency free lib that can be included via script-tag to other sites.<br />
<br />
This is usefull if you do not use the original AppSuite login page which performs this browser detection. If you use a form-login and jump directly into AppSuite, the user might not see the typical warning AppSuite states on the login page if an unsupported browser is used.<br />
<br />
To show the same warning to a user without using the original AppSuite login page you should include the browser detection lib in your own login page and show a warning to the user if he does not use a supported browser.<br />
<br />
=== Including the browser.js lib ===<br />
<br />
You can easily include the browser detection via script-tag to your own login page. It's small, dependency free peace of Javascript code which adds a function to the global scope called <pre>isBrowserSuppported()</pre><br />
<br />
The lib is located in the AppSuite UI under <pre>http://somedomain.com/appsuite/src/browser.js</pre>. Add this script tag to your page head <pre><script src="http://somedomain.com/appsuite/src/browser.js" type="text/javascript" charset="UTF-8"></script></pre><br />
<br />
In your page <tt>onLoad</tt> you can then call the the global function <tt>isBrowserSupported</tt> which returns a boolean. If <tt>false</tt> is returned by the function you should show a warning to the user that his browser is not supported.</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Browserdetection&diff=16806AppSuite:Browserdetection2014-01-08T08:45:00Z<p>Alexander.quast: </p>
<hr />
<div>== Browser detection outside AppSuite ==<br />
[[File:loginpage.png|thumb|250px|This warning is not shown to a user if you use the form-login]]<br />
<br />
AppSuite detects the client browser and collects some information about the current device the visitor is using. These informations are used to serve the best UI and enable/disable certain features for his device. The browser detection is done by a standalone and dependency free lib that can be included via script-tag to other sites.<br />
<br />
This is usefull if you do not use the original AppSuite login page which performs this browser detection. If you use a form-login and jump directly into AppSuite, the user might not see the typical warning AppSuite states on the login page if an unsupported browser is used.<br />
<br />
To show the same warning to a user without using the original AppSuite login page you should include the browser detection lib in your own login page and show a warning to the user if he does not use a supported browser.<br />
<br />
=== Including the browser.js lib ===<br />
<br />
You can easily include the browser detection via script-tag to your own login page. It's small, dependency free peace of Javascript code which adds a function to the global scope called <pre>isBrowserSuppported()</pre><br />
<br />
The lib is located in the AppSuite UI under <pre>http://somedomain.com/appsuite/src/browser.js</pre>. Add this script tag to your page head <pre><script src="http://somedomain.com/appsuite/src/browser.js" type="text/javascript" charset="UTF-8"></script></pre><br />
<br />
In your page <code>onLoad</code> you can then call the the global function <pre>isBrowserSupported</pre> which returns a boolean. If <pre>false</pre> is returned by the function you should show a warning to the user that his browser is not supported.</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Browserdetection&diff=16805AppSuite:Browserdetection2014-01-08T08:43:37Z<p>Alexander.quast: </p>
<hr />
<div>== Browser detection outside AppSuite ==<br />
[[File:loginpage.png|thumb|250px|This warning is not shown to a user if you use the form-login]]<br />
<br />
AppSuite detects the client browser and collects some information about the current device the visitor is using. These informations are used to serve the best UI and enable/disable certain features for his device. The browser detection is done by a standalone and dependency free lib that can be included via script-tag to other sites.<br />
<br />
This is usefull if you do not use the original AppSuite login page which performs this browser detection. If you use a form-login and jump directly into AppSuite, the user might not see the typical warning AppSuite states on the login page if an unsupported browser is used.<br />
<br />
To show the same warning to a user without using the original AppSuite login page you should include the browser detection lib in your own login page and show a warning to the user if he does not use a supported browser.<br />
<br />
=== Including the browser.js lib ===<br />
<br />
You can easily include the browser detection via script-tag to your own login page. It's small, dependency free peace of Javascript code which adds a function to the global scope called <pre>isBrowserSuppported()</pre><br />
<br />
The lib is located in the AppSuite UI under <pre>http://somedomain.com/appsuite/src/browser.js</pre>. Add this script tag to your page <pre><script src="http://somedomain.com/appsuite/src/browser.js" type="text/javascript" charset="UTF-8"></script></pre><br />
<br />
In your page <pre>onLoad</pre> you can then call the the global function <pre>isBrowserSupported</pre> which returns a boolean. If <pre>false</pre> is returned by the function you should show a warning to the user that his browser is not supported.</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=File:Loginpage.png&diff=16804File:Loginpage.png2014-01-08T08:22:01Z<p>Alexander.quast: </p>
<hr />
<div></div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:UI_remote_debugging_android_mac&diff=16803AppSuite:UI remote debugging android mac2014-01-08T08:19:19Z<p>Alexander.quast: </p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">How to setup remote debugging for chrome on android devices with a mac</div><br />
<br />
==Prerequisites==<br />
<br />
You need the latest X-Code and a working setup of the latest Homebrew. Check with <tt>brew doctor</tt>.<br />
<br />
==Setup==<br />
<pre><br />
$ brew install android-sdk<br />
</pre><br />
Add this to your shells rc (e.g. .bashrc or .zshrc)<br />
<pre><br />
export ANDROID_HOME=/usr/local/opt/android-sdk<br />
</pre><br />
<br />
Launch the "Android SDK Manager".<br />
<pre><br />
$ android<br />
</pre><br />
Check <tt>Android SDK Platform-tools</tt> and <tt>Android Support Library</tt> uncheck everything else, except if you plan on using other components of the SDK.<br />
<br />
Add this to your shells rc (e.g. .bashrc or .zshrc) for convenience:<br />
<br />
<pre><br />
alias chrome-android="adb forward tcp:9222 localabstract:chrome_devtools_remote"<br />
</pre><br />
<br />
==Usage==<br />
<br />
Connect an Android Device via USB.<br />
<br />
Open a terminal and enter "chrome-android".<br />
<br />
Open Chrome on your device.<br />
<br />
Visit <tt>localhost:9222</tt> on your desktop machine for remote debugging.<br />
<br />
==Chrome Plugin==<br />
<br />
A simpler way to perform remote debugging directly with Chrome is to install the "ADB Plugin". It's a Chrome Plugin/App and can be installed from the Chrome Webstore. All you need is a running Android SDK, nothing else. The ADB Plugin adds a icon to the Chrome toolbar which shows all inspectable targets on connected devices/emulators.</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Browserdetection&diff=16802AppSuite:Browserdetection2014-01-08T08:12:24Z<p>Alexander.quast: Created page with "== Browser detection outside AppSuite == AppSuite detects the client browser and collects some information about the current device the visitor is using. These informations a..."</p>
<hr />
<div>== Browser detection outside AppSuite ==<br />
<br />
AppSuite detects the client browser and collects some information about the current device the visitor is using. These informations are used to serve the best UI and enable/disable certain features for his device. The browser detection is done by a standalone and dependency free lib that can be included via script-tag to other sites.<br />
<br />
This is usefull if you do not use the original AppSuite login page which performs this browser detection. If you use a form-login and jump directly into AppSuite, the user might not see the typical warning AppSuite states on the login page if an unsupported browser is used.<br />
<br />
To show the same warning to a user without using the original AppSuite login page you should include the browser detection lib in your own login page and show a warning to the user if he does not use a supported browser.</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=Portal:AppSuite_UI/Topics&diff=16801Portal:AppSuite UI/Topics2014-01-08T08:05:46Z<p>Alexander.quast: Added new article</p>
<hr />
<div>== Getting started ==<br />
* [[AppSuite:UI developer primer| Skills needed to develop the UI]]<br />
* [[AppSuite:Getting started developing the UI | Getting started developing the UI]]<br />
* [[AppSuite:UI_Development_Style_Guide | UI Development Style Guide]]<br />
* [[AppSuite:Appserver | Appserver]]<br />
* [[AppSuite:Apache Configuration | Apache Configuration]]<br />
* [[AppSuite:Definition of done|Definition of done]]<br />
* [[Appsuite:UI_FAQ | Frequently asked questions]]<br />
<br />
== Testing ==<br />
* [[AppSuite:Test basics | Lessons learned while testing]]<br />
* [[AppSuite:RunTests | Running ui tests]]<br />
<br />
== How-to articles ==<br />
* [[AppSuite:Action links|Understanding action links]]<br />
** [[AppSuite:Files App Actions|Adding actions to the files app]]<br />
* [[AppSuite:Date_and_time|Date and time]]<br />
* [[AppSuite:i18n | Internationalization (i18n)]]<br />
* [[AppSuite:a11y | Accessibility (a11y)]]<br />
* [[AppSuite:Mediaplayer | Mediaplayer]]<br />
* [[AppSuite:Theming | Theming]]<br />
* [[AppSuite:UI manifests explained | UI manifests explained]]<br />
* [[AppSuite:Upsell | Upsell]]<br />
* [[AppSuite:VGrid | VGrid]]<br />
* [[AppSuite:Mobile | Mobile development]]<br />
* [[AppSuite:Upsell tools| Upsell tools]]<br />
* [[AppSuite:Guided tours| Guided tours]]<br />
* [[AppSuite:Browserdetection | Browser detection with form-login]]<br />
<br />
=== Server communication ===<br />
* [[AppSuite:APIs | APIs]]<br />
* [[AppSuite:API_Factory | API Factory]]<br />
* [[AppSuite:http.js | http.js]]<br />
<br />
=== Extension points ===<br />
* [[AppSuite:Extending_the_UI_(Hands-on_introduction)| Hands-on introduction]]<br />
* [[AppSuite:Extending_the_UI | General information on extension points]]<br />
* [[AppSuite:Modifying forms by using extension points | Modifying forms]]<br />
* [[AppSuite:Extension points for calendar |extension points: Calendar]]<br />
* [[AppSuite:Extension points for contact |extension points: Contact]]<br />
* [[AppSuite:Extension points for core | extension points: Core]]<br />
* [[AppSuite:Extension points for email | extension points: E-Mail]]<br />
* [[AppSuite:Extension points for files |extension points: Files]]<br />
* [[AppSuite:Extension points for tasks |extension points: Tasks]]<br />
* [[AppSuite:Extension points for miscellaneous |extension points: Miscellaneous]]<br />
<br />
=== Writing components ===<br />
* [[AppSuite:Writing a portal plugin | Writing a portal plugin]]<br />
** [[AppSuite:Configuring portal plugins|Configuring a portal plugin]]<br />
** [[AppSuite:Using the Upsell widget|Using the Upsell widget]]<br />
* [[AppSuite:Writing a simple application | Writing a simple application]]<br />
* [[AppSuite:Writing a notification area plugin | Writing a plugin for the notification area]]<br />
* [[AppSuite:Writing a wizard | Writing a wizard]]<br />
<br />
== Miscellaneous articles ==<br />
* [[AppSuite:External libraries for the UI | External libraries used by the UI]]<br />
* [[AppSuite:Configuration| Configuration]]<br />
* [[AppSuite:Custom configurations| Custom configurations]]<br />
* [[AppSuite:UI build system| The UI build system]]<br />
* [[AppSuite:Embedding your settings into AppSuite settings|How to embed your own settings into the Appsuite settings page]]<br />
* [[AppSuite:Debugging the UI|Debugging the UI]]<br />
* All articles regarding the UI are filed in the category [[:Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=16746AppSuite:Theming2013-12-16T16:18:16Z<p>Alexander.quast: /* Favicons and mobile homescreen icons */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
=== Basic ===<br />
<br />
==== Font ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @baseFontSize || 14px<br />
|-<br />
| @baseFontFamily || @sansFontFamily<br />
|-<br />
| @baseLineHeight || 20px<br />
|-<br />
| @altFontFamily || @serifFontFamily<br />
|-<br />
| @touchFontSize || 15px<br />
|-<br />
| @headingsFontFamily || inherit<br />
|-<br />
| @headingsFontWeight || bold<br />
|-<br />
| @fontSizeLarge || @baseFontSize * 1.25<br />
|-<br />
| @fontSizeSmall || @baseFontSize * 0.85<br />
|-<br />
| @fontSizeMini || @baseFontSize * 0.75<br />
|-<br />
| @vgridFontSize || 13px<br />
|}<br />
<br />
==== Colors ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @bodyBackground || @white<br />
|-<br />
| @textColor || @grayDark<br />
|-<br />
| @linkColor || #08c<br />
|-<br />
| @linkColorHover || darken(@linkColor, 15%)<br />
|-<br />
| @linkAccentColor || #ffad00<br />
|-<br />
| @linkAccentColorHover || darken(@linkAccentColor, 15%)<br />
|-<br />
| @badgeColor || @white<br />
|-<br />
| @badgeBackground || #555<br />
|-<br />
| @headingsColor || inherit<br />
|-<br />
| @black || #000<br />
|-<br />
| @grayDarker || #222<br />
|-<br />
| @grayDark || #333<br />
|-<br />
| @gray || #555<br />
|-<br />
| @grayLight || #aaa<br />
|-<br />
| @grayLighter || #eee<br />
|-<br />
| @white || #fff<br />
|-<br />
| @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blueDark || #0064cd<br />
|-<br />
| @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || #1A8D1A<br />
|-<br />
| @greenLight || #92D050<br />
|-<br />
| @red || #cc0000<br />
|-<br />
| @yellow || #F8E400<br />
|-<br />
| @orange || #f89406<br />
|-<br />
| @pink || #E01CD9<br />
|-<br />
| @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
==== Space ====<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paddingLarge || 11px 19px<br />
|-<br />
| @paddingSmall || 2px 10px<br />
|-<br />
| @paddingMini || 0 6px<br />
|-<br />
| @baseBorderRadius || 4px<br />
|-<br />
| @borderRadiusLarge || 6px<br />
|-<br />
| @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paginationBackground || #fff<br />
|-<br />
| @paginationBorder || #ddd<br />
|-<br />
| @paginationActiveBackground || #f5f5f5<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @btnBackground || @white<br />
|-<br />
| @btnBackgroundHighlight || darken(@white, 10%)<br />
|-<br />
| @btnBorder || #bbb<br />
|-<br />
| @btnPrimaryBackground || @linkColor<br />
|-<br />
| @btnPrimaryBackgroundHighlight || spin(@btnPrimaryBackground, 20%)<br />
|-<br />
| @btnInfoBackground || #5bc0de<br />
|-<br />
| @btnInfoBackgroundHighlight || #2f96b4<br />
|-<br />
| @btnSuccessBackground || #62c462<br />
|-<br />
| @btnSuccessBackgroundHighlight || #51a351<br />
|-<br />
| @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| @btnWarningBackgroundHighlight || @orange<br />
|-<br />
| @btnDangerBackground || #ee5f5b<br />
|-<br />
| @btnDangerBackgroundHighlight || #bd362f<br />
|-<br />
| @btnInverseBackground || #444<br />
|-<br />
| @btnInverseBackgroundHighlight || @grayDarker<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @dropdownBackground || @white<br />
|-<br />
| @dropdownBorder || rgba(0,0,0,.2)<br />
|-<br />
| @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdownDividerBottom || @white<br />
|-<br />
| @dropdownLinkColor || @grayDark<br />
|-<br />
| @dropdownLinkColorHover || @white<br />
|-<br />
| @dropdownLinkColorActive || @white<br />
|-<br />
| @dropdownLinkBackgroundActive || @linkColor<br />
|-<br />
| @dropdownLinkBackgroundHover || @dropdownLinkBackgroundActive<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @foldertreeSidepanelBackground || #333 ||<br />
|-<br />
| @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertreeActiveLabelColor || #ccc || ''Active'' means, user can perform an action on this item<br />
|-<br />
| @foldertreePassiveLabelColor || #ccc || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertreeHoverBackground || #888 ||<br />
|-<br />
| @foldertreeSelectedBackground || #222 ||<br />
|-<br />
| @foldertreeBadgeBackground || @bagdeBackground || see [[#Colors]] for definition of @badgeBackground<br />
|-<br />
| @foldertreeBadgeColor ||@badgeColor || see [[#Colors]] for definition of @badgeBackground<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekviewTimeline || #f00 /* red */ || Color of the Line indicating the current time<br />
|-<br />
| @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre&lt;noinclude&gt;&lt;/noinclude&gt;>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre&lt;noinclude&gt;&lt;/noinclude&gt;> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
'''This documentation applies for AppSuite v.7.4.2'''<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers as long as you don't deliver your own icons with your theme. <br />
<br />
=== Favicon ===<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
You should provide your custom favicon within your custom theme. If you do not add a custom favicon to your theme the global OX default will be used. The default icon is located under <tt>apps/themes/icons/default</tt><br />
<br />
=== Apple touch icons ===<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. AppSuite offers full support for Webclips by providing all needed App icons, splashscreens and full screen support. If a user uses the "Add to homescreen" button on his iOS device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format.<br />
<br />
* iPhone 3: 57 x 57 px<br />
* iPhone 4 retina: 114x114 px<br />
* iPhone iPhone 5 retina: 120 x 120 px<br />
* iPad: 72 x 72 px<br />
* iPad (iOS 7): 76 x 76px<br />
* iPad retina: 144 x 144 px <br />
* iPad retina (iOS 7): 152 x 152 px <br />
<br />
Furthermore a fullscreen Webclip App will show a splashscreen, a jpg file that is displayed on startup during app load. There are currently three different resolutions as jpg files available. '''Note''': Splashscreens must be JPG files<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change with Apple's iOS updates. We recommend providing all of this resolutions when customizing the Webclip icons and splashscreens, even if some iOS devices use the next best resolution for an icon if a certain file is missing.<br />
<br />
=== Providing custom icons ===<br />
To provide custom Webclip icons locate the following path in your AppSuite installation:<br />
pathToAppSuite/apps/themes/icons/default<br />
<br />
This folder contains all OX default icons for Webclips icons and splashscreens. Use these as samples for your own versions.<br />
<br />
A clean installation will have all our default icons in the "default" directory. To customize the icons we recommend using our default icons as samples and save your customized version in your theme. '''Note''': The filename has to be the same as in the default folder. Otherwise the fallback will be applied and the default icons will be used. If more advanced rewriting is needed one should edit the contents of the <tt>.htaccess</tt> file located under <tt>apps/themes</tt><br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
=== Providing domain based login themes ===<br />
<br />
If you have a multibrand installation and you want to deliver not only custom themes but also custom login-themes this can be done via Apache mod_rewrite. You can do so by a domain-based rewrite rule to deliver custom themes to a user based on the URI he's using. The needed config file <tt>.htaccess</tt> is located under <tt>apps/themes</tt><br />
<br />
<pre><br />
# Sample config for domain based login theme<br />
RewriteCond %{HTTP_HOST} ^www\.domain\.com$<br />
RewriteCond %{REQUEST_FILENAME} -f<br />
RewriteRule ^login/(.*)$ domain_com_logintheme/$1 [L]<br />
</pre><br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=16735AppSuite:Theming2013-12-16T11:18:23Z<p>Alexander.quast: /* Favicons and mobile homescreen icons */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
=== Basic ===<br />
<br />
==== Font ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @baseFontSize || 14px<br />
|-<br />
| @baseFontFamily || @sansFontFamily<br />
|-<br />
| @baseLineHeight || 20px<br />
|-<br />
| @altFontFamily || @serifFontFamily<br />
|-<br />
| @touchFontSize || 15px<br />
|-<br />
| @headingsFontFamily || inherit<br />
|-<br />
| @headingsFontWeight || bold<br />
|-<br />
| @fontSizeLarge || @baseFontSize * 1.25<br />
|-<br />
| @fontSizeSmall || @baseFontSize * 0.85<br />
|-<br />
| @fontSizeMini || @baseFontSize * 0.75<br />
|-<br />
| @vgridFontSize || 13px<br />
|}<br />
<br />
==== Colors ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @bodyBackground || @white<br />
|-<br />
| @textColor || @grayDark<br />
|-<br />
| @linkColor || #08c<br />
|-<br />
| @linkColorHover || darken(@linkColor, 15%)<br />
|-<br />
| @linkAccentColor || #ffad00<br />
|-<br />
| @linkAccentColorHover || darken(@linkAccentColor, 15%)<br />
|-<br />
| @badgeColor || @white<br />
|-<br />
| @badgeBackground || #555<br />
|-<br />
| @headingsColor || inherit<br />
|-<br />
| @black || #000<br />
|-<br />
| @grayDarker || #222<br />
|-<br />
| @grayDark || #333<br />
|-<br />
| @gray || #555<br />
|-<br />
| @grayLight || #aaa<br />
|-<br />
| @grayLighter || #eee<br />
|-<br />
| @white || #fff<br />
|-<br />
| @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blueDark || #0064cd<br />
|-<br />
| @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || #1A8D1A<br />
|-<br />
| @greenLight || #92D050<br />
|-<br />
| @red || #cc0000<br />
|-<br />
| @yellow || #F8E400<br />
|-<br />
| @orange || #f89406<br />
|-<br />
| @pink || #E01CD9<br />
|-<br />
| @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
==== Space ====<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paddingLarge || 11px 19px<br />
|-<br />
| @paddingSmall || 2px 10px<br />
|-<br />
| @paddingMini || 0 6px<br />
|-<br />
| @baseBorderRadius || 4px<br />
|-<br />
| @borderRadiusLarge || 6px<br />
|-<br />
| @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paginationBackground || #fff<br />
|-<br />
| @paginationBorder || #ddd<br />
|-<br />
| @paginationActiveBackground || #f5f5f5<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @btnBackground || @white<br />
|-<br />
| @btnBackgroundHighlight || darken(@white, 10%)<br />
|-<br />
| @btnBorder || #bbb<br />
|-<br />
| @btnPrimaryBackground || @linkColor<br />
|-<br />
| @btnPrimaryBackgroundHighlight || spin(@btnPrimaryBackground, 20%)<br />
|-<br />
| @btnInfoBackground || #5bc0de<br />
|-<br />
| @btnInfoBackgroundHighlight || #2f96b4<br />
|-<br />
| @btnSuccessBackground || #62c462<br />
|-<br />
| @btnSuccessBackgroundHighlight || #51a351<br />
|-<br />
| @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| @btnWarningBackgroundHighlight || @orange<br />
|-<br />
| @btnDangerBackground || #ee5f5b<br />
|-<br />
| @btnDangerBackgroundHighlight || #bd362f<br />
|-<br />
| @btnInverseBackground || #444<br />
|-<br />
| @btnInverseBackgroundHighlight || @grayDarker<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @dropdownBackground || @white<br />
|-<br />
| @dropdownBorder || rgba(0,0,0,.2)<br />
|-<br />
| @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdownDividerBottom || @white<br />
|-<br />
| @dropdownLinkColor || @grayDark<br />
|-<br />
| @dropdownLinkColorHover || @white<br />
|-<br />
| @dropdownLinkColorActive || @white<br />
|-<br />
| @dropdownLinkBackgroundActive || @linkColor<br />
|-<br />
| @dropdownLinkBackgroundHover || @dropdownLinkBackgroundActive<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @foldertreeSidepanelBackground || #333 ||<br />
|-<br />
| @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertreeActiveLabelColor || #ccc || ''Active'' means, user can perform an action on this item<br />
|-<br />
| @foldertreePassiveLabelColor || #ccc || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertreeHoverBackground || #888 ||<br />
|-<br />
| @foldertreeSelectedBackground || #222 ||<br />
|-<br />
| @foldertreeBadgeBackground || @bagdeBackground || see [[#Colors]] for definition of @badgeBackground<br />
|-<br />
| @foldertreeBadgeColor ||@badgeColor || see [[#Colors]] for definition of @badgeBackground<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekviewTimeline || #f00 /* red */ || Color of the Line indicating the current time<br />
|-<br />
| @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre&lt;noinclude&gt;&lt;/noinclude&gt;>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre&lt;noinclude&gt;&lt;/noinclude&gt;> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
'''This documentation applies for AppSuite v.7.4.2'''<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers as long as you don't deliver your own icons. The favicon can be delivered with a custom theme. It's possible to install and use multiple themes, all providing their own favicon. <br />
<br />
The Apple touch icons (aka. Webclip or Homescreen icons) can not be changed via custom themes. This is a technical restriction of mobile Safari which does not allow runtime changes to these icons. You can provide one set of touchicons which is used no matter what theme is installed or used by the user. To do so, follow the steps described later in this article.<br />
=== Favicon ===<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
You should provide your custom favicon within your custom theme. If you do not add a custom favicon to your theme the global OX default will be used. The default icon is located under <tt>apps/themes/icons/default</tt><br />
<br />
=== Apple touch icons ===<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. AppSuite offers full support for Webclips by providing all needed App icons, splashscreens and full screen support. If a user uses the "Add to homescreen" button on his iOS device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format.<br />
<br />
* iPhone 3: 57 x 57 px<br />
* iPhone 4 retina: 114x114 px<br />
* iPhone iPhone 5 retina: 120 x 120 px<br />
* iPad: 72 x 72 px<br />
* iPad (iOS 7): 76 x 76px<br />
* iPad retina: 144 x 144 px <br />
* iPad retina (iOS 7): 152 x 152 px <br />
<br />
Furthermore a fullscreen Webclip App will show a splashscreen, a jpg file that is displayed on startup during app load. There are currently three different resolutions as jpg files available. '''Note''': Splashscreens must be JPG files<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change with Apple's iOS updates. We recommend providing all of this resolutions when customizing the Webclip icons and splashscreens, even if some iOS devices use the next best resolution for an icon if a certain file is missing.<br />
<br />
=== Providing custom icons ===<br />
To provide custom Webclip icons locate the following path in your AppSuite installation:<br />
pathToAppSuite/apps/themes/icons<br />
<br />
The directory will contain two folders<br />
custom <br />
and<br />
default<br />
A clean installation will have all our default icons in the "default" directory. The "custom" folder should be empty, only containing <tt>README</tt> file. To customize the icons we recommend using our default icons as samples and save your customized version in the "custom" directory. '''Note''': The filename has to be the same as in the default folder. Otherwise the rewrite will not work and the default icons will be used. If more advanced rewriting is needed one should edit the contents of the <tt>.htaccess</tt> file located under <tt>apps/themes</tt><br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
=== Providing domain based login themes ===<br />
<br />
If you have a multibrand installation and you want to deliver not only custom themes but also custom login-themes this can be done via Apache mod_rewrite. You can do so by a domain-based rewrite rule to deliver custom themes to a user based on the URI he's using. The needed config file <tt>.htaccess</tt> is located under <tt>apps/themes</tt><br />
<br />
<pre><br />
# Sample config for domain based login theme<br />
RewriteCond %{HTTP_HOST} ^www\.domain\.com$<br />
RewriteCond %{REQUEST_FILENAME} -f<br />
RewriteRule ^login/(.*)$ domain_com_logintheme/$1 [L]<br />
</pre><br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=16734AppSuite:Theming2013-12-16T11:18:14Z<p>Alexander.quast: /* Favicons and mobile homescreen icons */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
=== Basic ===<br />
<br />
==== Font ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @baseFontSize || 14px<br />
|-<br />
| @baseFontFamily || @sansFontFamily<br />
|-<br />
| @baseLineHeight || 20px<br />
|-<br />
| @altFontFamily || @serifFontFamily<br />
|-<br />
| @touchFontSize || 15px<br />
|-<br />
| @headingsFontFamily || inherit<br />
|-<br />
| @headingsFontWeight || bold<br />
|-<br />
| @fontSizeLarge || @baseFontSize * 1.25<br />
|-<br />
| @fontSizeSmall || @baseFontSize * 0.85<br />
|-<br />
| @fontSizeMini || @baseFontSize * 0.75<br />
|-<br />
| @vgridFontSize || 13px<br />
|}<br />
<br />
==== Colors ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @bodyBackground || @white<br />
|-<br />
| @textColor || @grayDark<br />
|-<br />
| @linkColor || #08c<br />
|-<br />
| @linkColorHover || darken(@linkColor, 15%)<br />
|-<br />
| @linkAccentColor || #ffad00<br />
|-<br />
| @linkAccentColorHover || darken(@linkAccentColor, 15%)<br />
|-<br />
| @badgeColor || @white<br />
|-<br />
| @badgeBackground || #555<br />
|-<br />
| @headingsColor || inherit<br />
|-<br />
| @black || #000<br />
|-<br />
| @grayDarker || #222<br />
|-<br />
| @grayDark || #333<br />
|-<br />
| @gray || #555<br />
|-<br />
| @grayLight || #aaa<br />
|-<br />
| @grayLighter || #eee<br />
|-<br />
| @white || #fff<br />
|-<br />
| @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blueDark || #0064cd<br />
|-<br />
| @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || #1A8D1A<br />
|-<br />
| @greenLight || #92D050<br />
|-<br />
| @red || #cc0000<br />
|-<br />
| @yellow || #F8E400<br />
|-<br />
| @orange || #f89406<br />
|-<br />
| @pink || #E01CD9<br />
|-<br />
| @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
==== Space ====<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paddingLarge || 11px 19px<br />
|-<br />
| @paddingSmall || 2px 10px<br />
|-<br />
| @paddingMini || 0 6px<br />
|-<br />
| @baseBorderRadius || 4px<br />
|-<br />
| @borderRadiusLarge || 6px<br />
|-<br />
| @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paginationBackground || #fff<br />
|-<br />
| @paginationBorder || #ddd<br />
|-<br />
| @paginationActiveBackground || #f5f5f5<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @btnBackground || @white<br />
|-<br />
| @btnBackgroundHighlight || darken(@white, 10%)<br />
|-<br />
| @btnBorder || #bbb<br />
|-<br />
| @btnPrimaryBackground || @linkColor<br />
|-<br />
| @btnPrimaryBackgroundHighlight || spin(@btnPrimaryBackground, 20%)<br />
|-<br />
| @btnInfoBackground || #5bc0de<br />
|-<br />
| @btnInfoBackgroundHighlight || #2f96b4<br />
|-<br />
| @btnSuccessBackground || #62c462<br />
|-<br />
| @btnSuccessBackgroundHighlight || #51a351<br />
|-<br />
| @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| @btnWarningBackgroundHighlight || @orange<br />
|-<br />
| @btnDangerBackground || #ee5f5b<br />
|-<br />
| @btnDangerBackgroundHighlight || #bd362f<br />
|-<br />
| @btnInverseBackground || #444<br />
|-<br />
| @btnInverseBackgroundHighlight || @grayDarker<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @dropdownBackground || @white<br />
|-<br />
| @dropdownBorder || rgba(0,0,0,.2)<br />
|-<br />
| @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdownDividerBottom || @white<br />
|-<br />
| @dropdownLinkColor || @grayDark<br />
|-<br />
| @dropdownLinkColorHover || @white<br />
|-<br />
| @dropdownLinkColorActive || @white<br />
|-<br />
| @dropdownLinkBackgroundActive || @linkColor<br />
|-<br />
| @dropdownLinkBackgroundHover || @dropdownLinkBackgroundActive<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @foldertreeSidepanelBackground || #333 ||<br />
|-<br />
| @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertreeActiveLabelColor || #ccc || ''Active'' means, user can perform an action on this item<br />
|-<br />
| @foldertreePassiveLabelColor || #ccc || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertreeHoverBackground || #888 ||<br />
|-<br />
| @foldertreeSelectedBackground || #222 ||<br />
|-<br />
| @foldertreeBadgeBackground || @bagdeBackground || see [[#Colors]] for definition of @badgeBackground<br />
|-<br />
| @foldertreeBadgeColor ||@badgeColor || see [[#Colors]] for definition of @badgeBackground<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekviewTimeline || #f00 /* red */ || Color of the Line indicating the current time<br />
|-<br />
| @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre&lt;noinclude&gt;&lt;/noinclude&gt;>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre&lt;noinclude&gt;&lt;/noinclude&gt;> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
'''This documentation applies for App Suite v.7.4.2'''<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers as long as you don't deliver your own icons. The favicon can be delivered with a custom theme. It's possible to install and use multiple themes, all providing their own favicon. <br />
<br />
The Apple touch icons (aka. Webclip or Homescreen icons) can not be changed via custom themes. This is a technical restriction of mobile Safari which does not allow runtime changes to these icons. You can provide one set of touchicons which is used no matter what theme is installed or used by the user. To do so, follow the steps described later in this article.<br />
=== Favicon ===<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
You should provide your custom favicon within your custom theme. If you do not add a custom favicon to your theme the global OX default will be used. The default icon is located under <tt>apps/themes/icons/default</tt><br />
<br />
=== Apple touch icons ===<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. AppSuite offers full support for Webclips by providing all needed App icons, splashscreens and full screen support. If a user uses the "Add to homescreen" button on his iOS device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format.<br />
<br />
* iPhone 3: 57 x 57 px<br />
* iPhone 4 retina: 114x114 px<br />
* iPhone iPhone 5 retina: 120 x 120 px<br />
* iPad: 72 x 72 px<br />
* iPad (iOS 7): 76 x 76px<br />
* iPad retina: 144 x 144 px <br />
* iPad retina (iOS 7): 152 x 152 px <br />
<br />
Furthermore a fullscreen Webclip App will show a splashscreen, a jpg file that is displayed on startup during app load. There are currently three different resolutions as jpg files available. '''Note''': Splashscreens must be JPG files<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change with Apple's iOS updates. We recommend providing all of this resolutions when customizing the Webclip icons and splashscreens, even if some iOS devices use the next best resolution for an icon if a certain file is missing.<br />
<br />
=== Providing custom icons ===<br />
To provide custom Webclip icons locate the following path in your AppSuite installation:<br />
pathToAppSuite/apps/themes/icons<br />
<br />
The directory will contain two folders<br />
custom <br />
and<br />
default<br />
A clean installation will have all our default icons in the "default" directory. The "custom" folder should be empty, only containing <tt>README</tt> file. To customize the icons we recommend using our default icons as samples and save your customized version in the "custom" directory. '''Note''': The filename has to be the same as in the default folder. Otherwise the rewrite will not work and the default icons will be used. If more advanced rewriting is needed one should edit the contents of the <tt>.htaccess</tt> file located under <tt>apps/themes</tt><br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
=== Providing domain based login themes ===<br />
<br />
If you have a multibrand installation and you want to deliver not only custom themes but also custom login-themes this can be done via Apache mod_rewrite. You can do so by a domain-based rewrite rule to deliver custom themes to a user based on the URI he's using. The needed config file <tt>.htaccess</tt> is located under <tt>apps/themes</tt><br />
<br />
<pre><br />
# Sample config for domain based login theme<br />
RewriteCond %{HTTP_HOST} ^www\.domain\.com$<br />
RewriteCond %{REQUEST_FILENAME} -f<br />
RewriteRule ^login/(.*)$ domain_com_logintheme/$1 [L]<br />
</pre><br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=16733AppSuite:Theming2013-12-16T11:17:13Z<p>Alexander.quast: /* Providing custom icons */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
=== Basic ===<br />
<br />
==== Font ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @baseFontSize || 14px<br />
|-<br />
| @baseFontFamily || @sansFontFamily<br />
|-<br />
| @baseLineHeight || 20px<br />
|-<br />
| @altFontFamily || @serifFontFamily<br />
|-<br />
| @touchFontSize || 15px<br />
|-<br />
| @headingsFontFamily || inherit<br />
|-<br />
| @headingsFontWeight || bold<br />
|-<br />
| @fontSizeLarge || @baseFontSize * 1.25<br />
|-<br />
| @fontSizeSmall || @baseFontSize * 0.85<br />
|-<br />
| @fontSizeMini || @baseFontSize * 0.75<br />
|-<br />
| @vgridFontSize || 13px<br />
|}<br />
<br />
==== Colors ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @bodyBackground || @white<br />
|-<br />
| @textColor || @grayDark<br />
|-<br />
| @linkColor || #08c<br />
|-<br />
| @linkColorHover || darken(@linkColor, 15%)<br />
|-<br />
| @linkAccentColor || #ffad00<br />
|-<br />
| @linkAccentColorHover || darken(@linkAccentColor, 15%)<br />
|-<br />
| @badgeColor || @white<br />
|-<br />
| @badgeBackground || #555<br />
|-<br />
| @headingsColor || inherit<br />
|-<br />
| @black || #000<br />
|-<br />
| @grayDarker || #222<br />
|-<br />
| @grayDark || #333<br />
|-<br />
| @gray || #555<br />
|-<br />
| @grayLight || #aaa<br />
|-<br />
| @grayLighter || #eee<br />
|-<br />
| @white || #fff<br />
|-<br />
| @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blueDark || #0064cd<br />
|-<br />
| @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || #1A8D1A<br />
|-<br />
| @greenLight || #92D050<br />
|-<br />
| @red || #cc0000<br />
|-<br />
| @yellow || #F8E400<br />
|-<br />
| @orange || #f89406<br />
|-<br />
| @pink || #E01CD9<br />
|-<br />
| @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
==== Space ====<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paddingLarge || 11px 19px<br />
|-<br />
| @paddingSmall || 2px 10px<br />
|-<br />
| @paddingMini || 0 6px<br />
|-<br />
| @baseBorderRadius || 4px<br />
|-<br />
| @borderRadiusLarge || 6px<br />
|-<br />
| @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paginationBackground || #fff<br />
|-<br />
| @paginationBorder || #ddd<br />
|-<br />
| @paginationActiveBackground || #f5f5f5<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @btnBackground || @white<br />
|-<br />
| @btnBackgroundHighlight || darken(@white, 10%)<br />
|-<br />
| @btnBorder || #bbb<br />
|-<br />
| @btnPrimaryBackground || @linkColor<br />
|-<br />
| @btnPrimaryBackgroundHighlight || spin(@btnPrimaryBackground, 20%)<br />
|-<br />
| @btnInfoBackground || #5bc0de<br />
|-<br />
| @btnInfoBackgroundHighlight || #2f96b4<br />
|-<br />
| @btnSuccessBackground || #62c462<br />
|-<br />
| @btnSuccessBackgroundHighlight || #51a351<br />
|-<br />
| @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| @btnWarningBackgroundHighlight || @orange<br />
|-<br />
| @btnDangerBackground || #ee5f5b<br />
|-<br />
| @btnDangerBackgroundHighlight || #bd362f<br />
|-<br />
| @btnInverseBackground || #444<br />
|-<br />
| @btnInverseBackgroundHighlight || @grayDarker<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @dropdownBackground || @white<br />
|-<br />
| @dropdownBorder || rgba(0,0,0,.2)<br />
|-<br />
| @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdownDividerBottom || @white<br />
|-<br />
| @dropdownLinkColor || @grayDark<br />
|-<br />
| @dropdownLinkColorHover || @white<br />
|-<br />
| @dropdownLinkColorActive || @white<br />
|-<br />
| @dropdownLinkBackgroundActive || @linkColor<br />
|-<br />
| @dropdownLinkBackgroundHover || @dropdownLinkBackgroundActive<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @foldertreeSidepanelBackground || #333 ||<br />
|-<br />
| @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertreeActiveLabelColor || #ccc || ''Active'' means, user can perform an action on this item<br />
|-<br />
| @foldertreePassiveLabelColor || #ccc || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertreeHoverBackground || #888 ||<br />
|-<br />
| @foldertreeSelectedBackground || #222 ||<br />
|-<br />
| @foldertreeBadgeBackground || @bagdeBackground || see [[#Colors]] for definition of @badgeBackground<br />
|-<br />
| @foldertreeBadgeColor ||@badgeColor || see [[#Colors]] for definition of @badgeBackground<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekviewTimeline || #f00 /* red */ || Color of the Line indicating the current time<br />
|-<br />
| @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre&lt;noinclude&gt;&lt;/noinclude&gt;>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre&lt;noinclude&gt;&lt;/noinclude&gt;> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers as long as you don't deliver your own icons. The favicon can be delivered with a custom theme. It's possible to install and use multiple themes, all providing their own favicon. <br />
<br />
The Apple touch icons (aka. Webclip or Homescreen icons) can not be changed via custom themes. This is a technical restriction of mobile Safari which does not allow runtime changes to these icons. You can provide one set of touchicons which is used no matter what theme is installed or used by the user. To do so, follow the steps described later in this article.<br />
=== Favicon ===<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
You should provide your custom favicon within your custom theme. If you do not add a custom favicon to your theme the global OX default will be used. The default icon is located under <tt>apps/themes/icons/default</tt><br />
<br />
=== Apple touch icons ===<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. AppSuite offers full support for Webclips by providing all needed App icons, splashscreens and full screen support. If a user uses the "Add to homescreen" button on his iOS device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format.<br />
<br />
* iPhone 3: 57 x 57 px<br />
* iPhone 4 retina: 114x114 px<br />
* iPhone iPhone 5 retina: 120 x 120 px<br />
* iPad: 72 x 72 px<br />
* iPad (iOS 7): 76 x 76px<br />
* iPad retina: 144 x 144 px <br />
* iPad retina (iOS 7): 152 x 152 px <br />
<br />
Furthermore a fullscreen Webclip App will show a splashscreen, a jpg file that is displayed on startup during app load. There are currently three different resolutions as jpg files available. '''Note''': Splashscreens must be JPG files<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change with Apple's iOS updates. We recommend providing all of this resolutions when customizing the Webclip icons and splashscreens, even if some iOS devices use the next best resolution for an icon if a certain file is missing.<br />
<br />
=== Providing custom icons ===<br />
To provide custom Webclip icons locate the following path in your AppSuite installation:<br />
pathToAppSuite/apps/themes/icons<br />
<br />
The directory will contain two folders<br />
custom <br />
and<br />
default<br />
A clean installation will have all our default icons in the "default" directory. The "custom" folder should be empty, only containing <tt>README</tt> file. To customize the icons we recommend using our default icons as samples and save your customized version in the "custom" directory. '''Note''': The filename has to be the same as in the default folder. Otherwise the rewrite will not work and the default icons will be used. If more advanced rewriting is needed one should edit the contents of the <tt>.htaccess</tt> file located under <tt>apps/themes</tt><br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
=== Providing domain based login themes ===<br />
<br />
If you have a multibrand installation and you want to deliver not only custom themes but also custom login-themes this can be done via Apache mod_rewrite. You can do so by a domain-based rewrite rule to deliver custom themes to a user based on the URI he's using. The needed config file <tt>.htaccess</tt> is located under <tt>apps/themes</tt><br />
<br />
<pre><br />
# Sample config for domain based login theme<br />
RewriteCond %{HTTP_HOST} ^www\.domain\.com$<br />
RewriteCond %{REQUEST_FILENAME} -f<br />
RewriteRule ^login/(.*)$ domain_com_logintheme/$1 [L]<br />
</pre><br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=16730AppSuite:Theming2013-12-16T09:42:23Z<p>Alexander.quast: /* Providing domain based login themes */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
=== Basic ===<br />
<br />
==== Font ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @baseFontSize || 14px<br />
|-<br />
| @baseFontFamily || @sansFontFamily<br />
|-<br />
| @baseLineHeight || 20px<br />
|-<br />
| @altFontFamily || @serifFontFamily<br />
|-<br />
| @touchFontSize || 15px<br />
|-<br />
| @headingsFontFamily || inherit<br />
|-<br />
| @headingsFontWeight || bold<br />
|-<br />
| @fontSizeLarge || @baseFontSize * 1.25<br />
|-<br />
| @fontSizeSmall || @baseFontSize * 0.85<br />
|-<br />
| @fontSizeMini || @baseFontSize * 0.75<br />
|-<br />
| @vgridFontSize || 13px<br />
|}<br />
<br />
==== Colors ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @bodyBackground || @white<br />
|-<br />
| @textColor || @grayDark<br />
|-<br />
| @linkColor || #08c<br />
|-<br />
| @linkColorHover || darken(@linkColor, 15%)<br />
|-<br />
| @linkAccentColor || #ffad00<br />
|-<br />
| @linkAccentColorHover || darken(@linkAccentColor, 15%)<br />
|-<br />
| @badgeColor || @white<br />
|-<br />
| @badgeBackground || #555<br />
|-<br />
| @headingsColor || inherit<br />
|-<br />
| @black || #000<br />
|-<br />
| @grayDarker || #222<br />
|-<br />
| @grayDark || #333<br />
|-<br />
| @gray || #555<br />
|-<br />
| @grayLight || #aaa<br />
|-<br />
| @grayLighter || #eee<br />
|-<br />
| @white || #fff<br />
|-<br />
| @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blueDark || #0064cd<br />
|-<br />
| @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || #1A8D1A<br />
|-<br />
| @greenLight || #92D050<br />
|-<br />
| @red || #cc0000<br />
|-<br />
| @yellow || #F8E400<br />
|-<br />
| @orange || #f89406<br />
|-<br />
| @pink || #E01CD9<br />
|-<br />
| @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
==== Space ====<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paddingLarge || 11px 19px<br />
|-<br />
| @paddingSmall || 2px 10px<br />
|-<br />
| @paddingMini || 0 6px<br />
|-<br />
| @baseBorderRadius || 4px<br />
|-<br />
| @borderRadiusLarge || 6px<br />
|-<br />
| @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paginationBackground || #fff<br />
|-<br />
| @paginationBorder || #ddd<br />
|-<br />
| @paginationActiveBackground || #f5f5f5<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @btnBackground || @white<br />
|-<br />
| @btnBackgroundHighlight || darken(@white, 10%)<br />
|-<br />
| @btnBorder || #bbb<br />
|-<br />
| @btnPrimaryBackground || @linkColor<br />
|-<br />
| @btnPrimaryBackgroundHighlight || spin(@btnPrimaryBackground, 20%)<br />
|-<br />
| @btnInfoBackground || #5bc0de<br />
|-<br />
| @btnInfoBackgroundHighlight || #2f96b4<br />
|-<br />
| @btnSuccessBackground || #62c462<br />
|-<br />
| @btnSuccessBackgroundHighlight || #51a351<br />
|-<br />
| @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| @btnWarningBackgroundHighlight || @orange<br />
|-<br />
| @btnDangerBackground || #ee5f5b<br />
|-<br />
| @btnDangerBackgroundHighlight || #bd362f<br />
|-<br />
| @btnInverseBackground || #444<br />
|-<br />
| @btnInverseBackgroundHighlight || @grayDarker<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @dropdownBackground || @white<br />
|-<br />
| @dropdownBorder || rgba(0,0,0,.2)<br />
|-<br />
| @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdownDividerBottom || @white<br />
|-<br />
| @dropdownLinkColor || @grayDark<br />
|-<br />
| @dropdownLinkColorHover || @white<br />
|-<br />
| @dropdownLinkColorActive || @white<br />
|-<br />
| @dropdownLinkBackgroundActive || @linkColor<br />
|-<br />
| @dropdownLinkBackgroundHover || @dropdownLinkBackgroundActive<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @foldertreeSidepanelBackground || #333 ||<br />
|-<br />
| @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertreeActiveLabelColor || #ccc || ''Active'' means, user can perform an action on this item<br />
|-<br />
| @foldertreePassiveLabelColor || #ccc || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertreeHoverBackground || #888 ||<br />
|-<br />
| @foldertreeSelectedBackground || #222 ||<br />
|-<br />
| @foldertreeBadgeBackground || @bagdeBackground || see [[#Colors]] for definition of @badgeBackground<br />
|-<br />
| @foldertreeBadgeColor ||@badgeColor || see [[#Colors]] for definition of @badgeBackground<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekviewTimeline || #f00 /* red */ || Color of the Line indicating the current time<br />
|-<br />
| @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre&lt;noinclude&gt;&lt;/noinclude&gt;>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre&lt;noinclude&gt;&lt;/noinclude&gt;> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers as long as you don't deliver your own icons. The favicon can be delivered with a custom theme. It's possible to install and use multiple themes, all providing their own favicon. <br />
<br />
The Apple touch icons (aka. Webclip or Homescreen icons) can not be changed via custom themes. This is a technical restriction of mobile Safari which does not allow runtime changes to these icons. You can provide one set of touchicons which is used no matter what theme is installed or used by the user. To do so, follow the steps described later in this article.<br />
=== Favicon ===<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
You should provide your custom favicon within your custom theme. If you do not add a custom favicon to your theme the global OX default will be used. The default icon is located under <tt>apps/themes/icons/default</tt><br />
<br />
=== Apple touch icons ===<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. AppSuite offers full support for Webclips by providing all needed App icons, splashscreens and full screen support. If a user uses the "Add to homescreen" button on his iOS device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format.<br />
<br />
* iPhone 3: 57 x 57 px<br />
* iPhone 4 retina: 114x114 px<br />
* iPhone iPhone 5 retina: 120 x 120 px<br />
* iPad: 72 x 72 px<br />
* iPad (iOS 7): 76 x 76px<br />
* iPad retina: 144 x 144 px <br />
* iPad retina (iOS 7): 152 x 152 px <br />
<br />
Furthermore a fullscreen Webclip App will show a splashscreen, a jpg file that is displayed on startup during app load. There are currently three different resolutions as jpg files available. '''Note''': Splashscreens must be JPG files<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change with Apple's iOS updates. We recommend providing all of this resolutions when customizing the Webclip icons and splashscreens, even if some iOS devices use the next best resolution for an icon if a certain file is missing.<br />
<br />
=== Providing custom icons ===<br />
To provide custom Webclip icons locate the following path in your AppSuite installation:<br />
pathToAppSuite/apps/themes/icons<br />
<br />
The directory will contain two folders<br />
custom <br />
and<br />
default<br />
A clean installation will have all our default icons in the "default" directory. The "custom" folder should be empty, only containing <tt>README</tt> file. To customize the icons we recommend using our default icons as samples and save your customized version in the "custom" directory. '''Note''': The filename has to be the same as in the default folder. Otherwise the rewrite will not work and the default icons will be used.<br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
=== Providing domain based login themes ===<br />
<br />
If you have a multibrand installation and you want to deliver not only custom themes but also custom login-themes this can be done via Apache mod_rewrite. You can do so by a domain-based rewrite rule to deliver custom themes to a user based on the URI he's using. The needed config file <tt>.htaccess</tt> is located under <tt>apps/themes</tt><br />
<br />
<pre><br />
# Sample config for domain based login theme<br />
RewriteCond %{HTTP_HOST} ^www\.domain\.com$<br />
RewriteCond %{REQUEST_FILENAME} -f<br />
RewriteRule ^login/(.*)$ domain_com_logintheme/$1 [L]<br />
</pre><br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=16729AppSuite:Theming2013-12-16T09:37:51Z<p>Alexander.quast: /* Theming the login page */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
=== Basic ===<br />
<br />
==== Font ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @baseFontSize || 14px<br />
|-<br />
| @baseFontFamily || @sansFontFamily<br />
|-<br />
| @baseLineHeight || 20px<br />
|-<br />
| @altFontFamily || @serifFontFamily<br />
|-<br />
| @touchFontSize || 15px<br />
|-<br />
| @headingsFontFamily || inherit<br />
|-<br />
| @headingsFontWeight || bold<br />
|-<br />
| @fontSizeLarge || @baseFontSize * 1.25<br />
|-<br />
| @fontSizeSmall || @baseFontSize * 0.85<br />
|-<br />
| @fontSizeMini || @baseFontSize * 0.75<br />
|-<br />
| @vgridFontSize || 13px<br />
|}<br />
<br />
==== Colors ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @bodyBackground || @white<br />
|-<br />
| @textColor || @grayDark<br />
|-<br />
| @linkColor || #08c<br />
|-<br />
| @linkColorHover || darken(@linkColor, 15%)<br />
|-<br />
| @linkAccentColor || #ffad00<br />
|-<br />
| @linkAccentColorHover || darken(@linkAccentColor, 15%)<br />
|-<br />
| @badgeColor || @white<br />
|-<br />
| @badgeBackground || #555<br />
|-<br />
| @headingsColor || inherit<br />
|-<br />
| @black || #000<br />
|-<br />
| @grayDarker || #222<br />
|-<br />
| @grayDark || #333<br />
|-<br />
| @gray || #555<br />
|-<br />
| @grayLight || #aaa<br />
|-<br />
| @grayLighter || #eee<br />
|-<br />
| @white || #fff<br />
|-<br />
| @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blueDark || #0064cd<br />
|-<br />
| @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || #1A8D1A<br />
|-<br />
| @greenLight || #92D050<br />
|-<br />
| @red || #cc0000<br />
|-<br />
| @yellow || #F8E400<br />
|-<br />
| @orange || #f89406<br />
|-<br />
| @pink || #E01CD9<br />
|-<br />
| @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
==== Space ====<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paddingLarge || 11px 19px<br />
|-<br />
| @paddingSmall || 2px 10px<br />
|-<br />
| @paddingMini || 0 6px<br />
|-<br />
| @baseBorderRadius || 4px<br />
|-<br />
| @borderRadiusLarge || 6px<br />
|-<br />
| @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paginationBackground || #fff<br />
|-<br />
| @paginationBorder || #ddd<br />
|-<br />
| @paginationActiveBackground || #f5f5f5<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @btnBackground || @white<br />
|-<br />
| @btnBackgroundHighlight || darken(@white, 10%)<br />
|-<br />
| @btnBorder || #bbb<br />
|-<br />
| @btnPrimaryBackground || @linkColor<br />
|-<br />
| @btnPrimaryBackgroundHighlight || spin(@btnPrimaryBackground, 20%)<br />
|-<br />
| @btnInfoBackground || #5bc0de<br />
|-<br />
| @btnInfoBackgroundHighlight || #2f96b4<br />
|-<br />
| @btnSuccessBackground || #62c462<br />
|-<br />
| @btnSuccessBackgroundHighlight || #51a351<br />
|-<br />
| @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| @btnWarningBackgroundHighlight || @orange<br />
|-<br />
| @btnDangerBackground || #ee5f5b<br />
|-<br />
| @btnDangerBackgroundHighlight || #bd362f<br />
|-<br />
| @btnInverseBackground || #444<br />
|-<br />
| @btnInverseBackgroundHighlight || @grayDarker<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @dropdownBackground || @white<br />
|-<br />
| @dropdownBorder || rgba(0,0,0,.2)<br />
|-<br />
| @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdownDividerBottom || @white<br />
|-<br />
| @dropdownLinkColor || @grayDark<br />
|-<br />
| @dropdownLinkColorHover || @white<br />
|-<br />
| @dropdownLinkColorActive || @white<br />
|-<br />
| @dropdownLinkBackgroundActive || @linkColor<br />
|-<br />
| @dropdownLinkBackgroundHover || @dropdownLinkBackgroundActive<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @foldertreeSidepanelBackground || #333 ||<br />
|-<br />
| @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertreeActiveLabelColor || #ccc || ''Active'' means, user can perform an action on this item<br />
|-<br />
| @foldertreePassiveLabelColor || #ccc || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertreeHoverBackground || #888 ||<br />
|-<br />
| @foldertreeSelectedBackground || #222 ||<br />
|-<br />
| @foldertreeBadgeBackground || @bagdeBackground || see [[#Colors]] for definition of @badgeBackground<br />
|-<br />
| @foldertreeBadgeColor ||@badgeColor || see [[#Colors]] for definition of @badgeBackground<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekviewTimeline || #f00 /* red */ || Color of the Line indicating the current time<br />
|-<br />
| @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre&lt;noinclude&gt;&lt;/noinclude&gt;>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre&lt;noinclude&gt;&lt;/noinclude&gt;> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers as long as you don't deliver your own icons. The favicon can be delivered with a custom theme. It's possible to install and use multiple themes, all providing their own favicon. <br />
<br />
The Apple touch icons (aka. Webclip or Homescreen icons) can not be changed via custom themes. This is a technical restriction of mobile Safari which does not allow runtime changes to these icons. You can provide one set of touchicons which is used no matter what theme is installed or used by the user. To do so, follow the steps described later in this article.<br />
=== Favicon ===<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
You should provide your custom favicon within your custom theme. If you do not add a custom favicon to your theme the global OX default will be used. The default icon is located under <tt>apps/themes/icons/default</tt><br />
<br />
=== Apple touch icons ===<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. AppSuite offers full support for Webclips by providing all needed App icons, splashscreens and full screen support. If a user uses the "Add to homescreen" button on his iOS device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format.<br />
<br />
* iPhone 3: 57 x 57 px<br />
* iPhone 4 retina: 114x114 px<br />
* iPhone iPhone 5 retina: 120 x 120 px<br />
* iPad: 72 x 72 px<br />
* iPad (iOS 7): 76 x 76px<br />
* iPad retina: 144 x 144 px <br />
* iPad retina (iOS 7): 152 x 152 px <br />
<br />
Furthermore a fullscreen Webclip App will show a splashscreen, a jpg file that is displayed on startup during app load. There are currently three different resolutions as jpg files available. '''Note''': Splashscreens must be JPG files<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change with Apple's iOS updates. We recommend providing all of this resolutions when customizing the Webclip icons and splashscreens, even if some iOS devices use the next best resolution for an icon if a certain file is missing.<br />
<br />
=== Providing custom icons ===<br />
To provide custom Webclip icons locate the following path in your AppSuite installation:<br />
pathToAppSuite/apps/themes/icons<br />
<br />
The directory will contain two folders<br />
custom <br />
and<br />
default<br />
A clean installation will have all our default icons in the "default" directory. The "custom" folder should be empty, only containing <tt>README</tt> file. To customize the icons we recommend using our default icons as samples and save your customized version in the "custom" directory. '''Note''': The filename has to be the same as in the default folder. Otherwise the rewrite will not work and the default icons will be used.<br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
=== Providing domain based login themes ===<br />
<br />
Before login you can not retrieve any user-based information from the backend. This is a issue if you have a multibrand installation and you want to deliver not only custom themes but also custom login-themes. You can do so by a domain-based rewrite rule to deliver custom themes to a user based on the URI. The needed config file <tt>.htaccess</tt> is located under <tt>apps/themes</tt><br />
<br />
<pre><br />
# Sample config for domain based login theme<br />
RewriteCond %{HTTP_HOST} ^www\.domain\.com$<br />
RewriteCond %{REQUEST_FILENAME} -f<br />
RewriteRule ^login/(.*)$ mylogintheme/$1 [L]<br />
</pre><br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=16728AppSuite:Theming2013-12-16T09:31:04Z<p>Alexander.quast: /* Favicons and mobile homescreen icons */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
=== Basic ===<br />
<br />
==== Font ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @baseFontSize || 14px<br />
|-<br />
| @baseFontFamily || @sansFontFamily<br />
|-<br />
| @baseLineHeight || 20px<br />
|-<br />
| @altFontFamily || @serifFontFamily<br />
|-<br />
| @touchFontSize || 15px<br />
|-<br />
| @headingsFontFamily || inherit<br />
|-<br />
| @headingsFontWeight || bold<br />
|-<br />
| @fontSizeLarge || @baseFontSize * 1.25<br />
|-<br />
| @fontSizeSmall || @baseFontSize * 0.85<br />
|-<br />
| @fontSizeMini || @baseFontSize * 0.75<br />
|-<br />
| @vgridFontSize || 13px<br />
|}<br />
<br />
==== Colors ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @bodyBackground || @white<br />
|-<br />
| @textColor || @grayDark<br />
|-<br />
| @linkColor || #08c<br />
|-<br />
| @linkColorHover || darken(@linkColor, 15%)<br />
|-<br />
| @linkAccentColor || #ffad00<br />
|-<br />
| @linkAccentColorHover || darken(@linkAccentColor, 15%)<br />
|-<br />
| @badgeColor || @white<br />
|-<br />
| @badgeBackground || #555<br />
|-<br />
| @headingsColor || inherit<br />
|-<br />
| @black || #000<br />
|-<br />
| @grayDarker || #222<br />
|-<br />
| @grayDark || #333<br />
|-<br />
| @gray || #555<br />
|-<br />
| @grayLight || #aaa<br />
|-<br />
| @grayLighter || #eee<br />
|-<br />
| @white || #fff<br />
|-<br />
| @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blueDark || #0064cd<br />
|-<br />
| @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || #1A8D1A<br />
|-<br />
| @greenLight || #92D050<br />
|-<br />
| @red || #cc0000<br />
|-<br />
| @yellow || #F8E400<br />
|-<br />
| @orange || #f89406<br />
|-<br />
| @pink || #E01CD9<br />
|-<br />
| @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
==== Space ====<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paddingLarge || 11px 19px<br />
|-<br />
| @paddingSmall || 2px 10px<br />
|-<br />
| @paddingMini || 0 6px<br />
|-<br />
| @baseBorderRadius || 4px<br />
|-<br />
| @borderRadiusLarge || 6px<br />
|-<br />
| @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paginationBackground || #fff<br />
|-<br />
| @paginationBorder || #ddd<br />
|-<br />
| @paginationActiveBackground || #f5f5f5<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @btnBackground || @white<br />
|-<br />
| @btnBackgroundHighlight || darken(@white, 10%)<br />
|-<br />
| @btnBorder || #bbb<br />
|-<br />
| @btnPrimaryBackground || @linkColor<br />
|-<br />
| @btnPrimaryBackgroundHighlight || spin(@btnPrimaryBackground, 20%)<br />
|-<br />
| @btnInfoBackground || #5bc0de<br />
|-<br />
| @btnInfoBackgroundHighlight || #2f96b4<br />
|-<br />
| @btnSuccessBackground || #62c462<br />
|-<br />
| @btnSuccessBackgroundHighlight || #51a351<br />
|-<br />
| @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| @btnWarningBackgroundHighlight || @orange<br />
|-<br />
| @btnDangerBackground || #ee5f5b<br />
|-<br />
| @btnDangerBackgroundHighlight || #bd362f<br />
|-<br />
| @btnInverseBackground || #444<br />
|-<br />
| @btnInverseBackgroundHighlight || @grayDarker<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @dropdownBackground || @white<br />
|-<br />
| @dropdownBorder || rgba(0,0,0,.2)<br />
|-<br />
| @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdownDividerBottom || @white<br />
|-<br />
| @dropdownLinkColor || @grayDark<br />
|-<br />
| @dropdownLinkColorHover || @white<br />
|-<br />
| @dropdownLinkColorActive || @white<br />
|-<br />
| @dropdownLinkBackgroundActive || @linkColor<br />
|-<br />
| @dropdownLinkBackgroundHover || @dropdownLinkBackgroundActive<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @foldertreeSidepanelBackground || #333 ||<br />
|-<br />
| @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertreeActiveLabelColor || #ccc || ''Active'' means, user can perform an action on this item<br />
|-<br />
| @foldertreePassiveLabelColor || #ccc || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertreeHoverBackground || #888 ||<br />
|-<br />
| @foldertreeSelectedBackground || #222 ||<br />
|-<br />
| @foldertreeBadgeBackground || @bagdeBackground || see [[#Colors]] for definition of @badgeBackground<br />
|-<br />
| @foldertreeBadgeColor ||@badgeColor || see [[#Colors]] for definition of @badgeBackground<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekviewTimeline || #f00 /* red */ || Color of the Line indicating the current time<br />
|-<br />
| @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre&lt;noinclude&gt;&lt;/noinclude&gt;>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre&lt;noinclude&gt;&lt;/noinclude&gt;> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers as long as you don't deliver your own icons. The favicon can be delivered with a custom theme. It's possible to install and use multiple themes, all providing their own favicon. <br />
<br />
The Apple touch icons (aka. Webclip or Homescreen icons) can not be changed via custom themes. This is a technical restriction of mobile Safari which does not allow runtime changes to these icons. You can provide one set of touchicons which is used no matter what theme is installed or used by the user. To do so, follow the steps described later in this article.<br />
=== Favicon ===<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
You should provide your custom favicon within your custom theme. If you do not add a custom favicon to your theme the global OX default will be used. The default icon is located under <tt>apps/themes/icons/default</tt><br />
<br />
=== Apple touch icons ===<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. AppSuite offers full support for Webclips by providing all needed App icons, splashscreens and full screen support. If a user uses the "Add to homescreen" button on his iOS device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format.<br />
<br />
* iPhone 3: 57 x 57 px<br />
* iPhone 4 retina: 114x114 px<br />
* iPhone iPhone 5 retina: 120 x 120 px<br />
* iPad: 72 x 72 px<br />
* iPad (iOS 7): 76 x 76px<br />
* iPad retina: 144 x 144 px <br />
* iPad retina (iOS 7): 152 x 152 px <br />
<br />
Furthermore a fullscreen Webclip App will show a splashscreen, a jpg file that is displayed on startup during app load. There are currently three different resolutions as jpg files available. '''Note''': Splashscreens must be JPG files<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change with Apple's iOS updates. We recommend providing all of this resolutions when customizing the Webclip icons and splashscreens, even if some iOS devices use the next best resolution for an icon if a certain file is missing.<br />
<br />
=== Providing custom icons ===<br />
To provide custom Webclip icons locate the following path in your AppSuite installation:<br />
pathToAppSuite/apps/themes/icons<br />
<br />
The directory will contain two folders<br />
custom <br />
and<br />
default<br />
A clean installation will have all our default icons in the "default" directory. The "custom" folder should be empty, only containing <tt>README</tt> file. To customize the icons we recommend using our default icons as samples and save your customized version in the "custom" directory. '''Note''': The filename has to be the same as in the default folder. Otherwise the rewrite will not work and the default icons will be used.<br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=16717AppSuite:Theming2013-12-12T08:08:48Z<p>Alexander.quast: /* Favicons and mobile homescreen icons */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
=== Basic ===<br />
<br />
==== Font ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @baseFontSize || 14px<br />
|-<br />
| @baseFontFamily || @sansFontFamily<br />
|-<br />
| @baseLineHeight || 20px<br />
|-<br />
| @altFontFamily || @serifFontFamily<br />
|-<br />
| @touchFontSize || 15px<br />
|-<br />
| @headingsFontFamily || inherit<br />
|-<br />
| @headingsFontWeight || bold<br />
|-<br />
| @fontSizeLarge || @baseFontSize * 1.25<br />
|-<br />
| @fontSizeSmall || @baseFontSize * 0.85<br />
|-<br />
| @fontSizeMini || @baseFontSize * 0.75<br />
|-<br />
| @vgridFontSize || 13px<br />
|}<br />
<br />
==== Colors ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @bodyBackground || @white<br />
|-<br />
| @textColor || @grayDark<br />
|-<br />
| @linkColor || #08c<br />
|-<br />
| @linkColorHover || darken(@linkColor, 15%)<br />
|-<br />
| @linkAccentColor || #ffad00<br />
|-<br />
| @linkAccentColorHover || darken(@linkAccentColor, 15%)<br />
|-<br />
| @badgeColor || @white<br />
|-<br />
| @badgeBackground || #555<br />
|-<br />
| @headingsColor || inherit<br />
|-<br />
| @black || #000<br />
|-<br />
| @grayDarker || #222<br />
|-<br />
| @grayDark || #333<br />
|-<br />
| @gray || #555<br />
|-<br />
| @grayLight || #aaa<br />
|-<br />
| @grayLighter || #eee<br />
|-<br />
| @white || #fff<br />
|-<br />
| @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blueDark || #0064cd<br />
|-<br />
| @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || #1A8D1A<br />
|-<br />
| @greenLight || #92D050<br />
|-<br />
| @red || #cc0000<br />
|-<br />
| @yellow || #F8E400<br />
|-<br />
| @orange || #f89406<br />
|-<br />
| @pink || #E01CD9<br />
|-<br />
| @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
==== Space ====<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paddingLarge || 11px 19px<br />
|-<br />
| @paddingSmall || 2px 10px<br />
|-<br />
| @paddingMini || 0 6px<br />
|-<br />
| @baseBorderRadius || 4px<br />
|-<br />
| @borderRadiusLarge || 6px<br />
|-<br />
| @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paginationBackground || #fff<br />
|-<br />
| @paginationBorder || #ddd<br />
|-<br />
| @paginationActiveBackground || #f5f5f5<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @btnBackground || @white<br />
|-<br />
| @btnBackgroundHighlight || darken(@white, 10%)<br />
|-<br />
| @btnBorder || #bbb<br />
|-<br />
| @btnPrimaryBackground || @linkColor<br />
|-<br />
| @btnPrimaryBackgroundHighlight || spin(@btnPrimaryBackground, 20%)<br />
|-<br />
| @btnInfoBackground || #5bc0de<br />
|-<br />
| @btnInfoBackgroundHighlight || #2f96b4<br />
|-<br />
| @btnSuccessBackground || #62c462<br />
|-<br />
| @btnSuccessBackgroundHighlight || #51a351<br />
|-<br />
| @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| @btnWarningBackgroundHighlight || @orange<br />
|-<br />
| @btnDangerBackground || #ee5f5b<br />
|-<br />
| @btnDangerBackgroundHighlight || #bd362f<br />
|-<br />
| @btnInverseBackground || #444<br />
|-<br />
| @btnInverseBackgroundHighlight || @grayDarker<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @dropdownBackground || @white<br />
|-<br />
| @dropdownBorder || rgba(0,0,0,.2)<br />
|-<br />
| @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdownDividerBottom || @white<br />
|-<br />
| @dropdownLinkColor || @grayDark<br />
|-<br />
| @dropdownLinkColorHover || @white<br />
|-<br />
| @dropdownLinkColorActive || @white<br />
|-<br />
| @dropdownLinkBackgroundActive || @linkColor<br />
|-<br />
| @dropdownLinkBackgroundHover || @dropdownLinkBackgroundActive<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @foldertreeSidepanelBackground || #333 ||<br />
|-<br />
| @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertreeActiveLabelColor || #ccc || ''Active'' means, user can perform an action on this item<br />
|-<br />
| @foldertreePassiveLabelColor || #ccc || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertreeHoverBackground || #888 ||<br />
|-<br />
| @foldertreeSelectedBackground || #222 ||<br />
|-<br />
| @foldertreeBadgeBackground || @bagdeBackground || see [[#Colors]] for definition of @badgeBackground<br />
|-<br />
| @foldertreeBadgeColor ||@badgeColor || see [[#Colors]] for definition of @badgeBackground<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekviewTimeline || #f00 /* red */ || Color of the Line indicating the current time<br />
|-<br />
| @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre&lt;noinclude&gt;&lt;/noinclude&gt;>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre&lt;noinclude&gt;&lt;/noinclude&gt;> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing AppSuite icons which are used in the application like the brand on the upper right.<br />
<br />
AppSuite ships with a standard set of icons containing a<br />
# favicon for desktop browsers<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers. If you wish to change these icons, you have to do this manually on your webserver where the UI is installed. The icons can not be delivered via custom themes. You should also note: You can only provide one custom icon for each resolution (more about this later), a multi-brand installation can not offer different favicons and apple-touch icons for each installed theme.<br />
<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. AppSuite offers full support for Webclips by providing all needed App icons, splashscreens and full screen support. If a user uses the "Add to homescreen" button on his iOS device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format.<br />
<br />
* iPhone 3: 57 x 57 px<br />
* iPhone 4 retina: 114x114 px<br />
* iPhone iPhone 5 retina: 120 x 120 px<br />
* iPad: 72 x 72 px<br />
* iPad (iOS 7): 76 x 76px<br />
* iPad retina: 144 x 144 px <br />
* iPad retina (iOS 7): 152 x 152 px <br />
<br />
Furthermore a fullscreen Webclip App will show a splashscreen, a jpg file that is displayed on startup during app load. There are currently three different resolutions as jpg files available. '''Note''': Splashscreens must be JPG files<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change with Apple's iOS updates. We recommend providing all of this resolutions when customizing the Webclip icons and splashscreens, even if some iOS devices use the next best resolution for an icon if a certain file is missing.<br />
<br />
=== Changing icons ===<br />
To provide custom icons locate the following path in your AppSuite installation:<br />
pathToAppSuite/apps/themes/icons<br />
<br />
The directory will contain two folders<br />
custom <br />
and<br />
default<br />
A clean installation will have all our default icons in the "default" directory. The "custom" folder should be empty, only containing a <tt>.htaccess</tt> and a <tt>README</tt> file. Keep the <tt>.htaccess</tt> file unchanged, it will automatically handle rewrite condition to serve the right icon to the user. To customize the icons we recommend using our default icons as samples and save your customized version in the "custom" directory. '''Note''': The filename has to be the same as in the default folder. Otherwise the rewrite will not work and the default icons will be used.<br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=16699AppSuite:Theming2013-12-11T14:29:19Z<p>Alexander.quast: /* Favicons and mobile homescreen icons */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
=== Basic ===<br />
<br />
==== Font ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @baseFontSize || 14px<br />
|-<br />
| @baseFontFamily || @sansFontFamily<br />
|-<br />
| @baseLineHeight || 20px<br />
|-<br />
| @altFontFamily || @serifFontFamily<br />
|-<br />
| @touchFontSize || 15px<br />
|-<br />
| @headingsFontFamily || inherit<br />
|-<br />
| @headingsFontWeight || bold<br />
|-<br />
| @fontSizeLarge || @baseFontSize * 1.25<br />
|-<br />
| @fontSizeSmall || @baseFontSize * 0.85<br />
|-<br />
| @fontSizeMini || @baseFontSize * 0.75<br />
|-<br />
| @vgridFontSize || 13px<br />
|}<br />
<br />
==== Colors ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @bodyBackground || @white<br />
|-<br />
| @textColor || @grayDark<br />
|-<br />
| @linkColor || #08c<br />
|-<br />
| @linkColorHover || darken(@linkColor, 15%)<br />
|-<br />
| @linkAccentColor || #ffad00<br />
|-<br />
| @linkAccentColorHover || darken(@linkAccentColor, 15%)<br />
|-<br />
| @badgeColor || @white<br />
|-<br />
| @badgeBackground || #555<br />
|-<br />
| @headingsColor || inherit<br />
|-<br />
| @black || #000<br />
|-<br />
| @grayDarker || #222<br />
|-<br />
| @grayDark || #333<br />
|-<br />
| @gray || #555<br />
|-<br />
| @grayLight || #aaa<br />
|-<br />
| @grayLighter || #eee<br />
|-<br />
| @white || #fff<br />
|-<br />
| @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blueDark || #0064cd<br />
|-<br />
| @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || #1A8D1A<br />
|-<br />
| @greenLight || #92D050<br />
|-<br />
| @red || #cc0000<br />
|-<br />
| @yellow || #F8E400<br />
|-<br />
| @orange || #f89406<br />
|-<br />
| @pink || #E01CD9<br />
|-<br />
| @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
==== Space ====<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paddingLarge || 11px 19px<br />
|-<br />
| @paddingSmall || 2px 10px<br />
|-<br />
| @paddingMini || 0 6px<br />
|-<br />
| @baseBorderRadius || 4px<br />
|-<br />
| @borderRadiusLarge || 6px<br />
|-<br />
| @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paginationBackground || #fff<br />
|-<br />
| @paginationBorder || #ddd<br />
|-<br />
| @paginationActiveBackground || #f5f5f5<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @btnBackground || @white<br />
|-<br />
| @btnBackgroundHighlight || darken(@white, 10%)<br />
|-<br />
| @btnBorder || #bbb<br />
|-<br />
| @btnPrimaryBackground || @linkColor<br />
|-<br />
| @btnPrimaryBackgroundHighlight || spin(@btnPrimaryBackground, 20%)<br />
|-<br />
| @btnInfoBackground || #5bc0de<br />
|-<br />
| @btnInfoBackgroundHighlight || #2f96b4<br />
|-<br />
| @btnSuccessBackground || #62c462<br />
|-<br />
| @btnSuccessBackgroundHighlight || #51a351<br />
|-<br />
| @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| @btnWarningBackgroundHighlight || @orange<br />
|-<br />
| @btnDangerBackground || #ee5f5b<br />
|-<br />
| @btnDangerBackgroundHighlight || #bd362f<br />
|-<br />
| @btnInverseBackground || #444<br />
|-<br />
| @btnInverseBackgroundHighlight || @grayDarker<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @dropdownBackground || @white<br />
|-<br />
| @dropdownBorder || rgba(0,0,0,.2)<br />
|-<br />
| @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdownDividerBottom || @white<br />
|-<br />
| @dropdownLinkColor || @grayDark<br />
|-<br />
| @dropdownLinkColorHover || @white<br />
|-<br />
| @dropdownLinkColorActive || @white<br />
|-<br />
| @dropdownLinkBackgroundActive || @linkColor<br />
|-<br />
| @dropdownLinkBackgroundHover || @dropdownLinkBackgroundActive<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @foldertreeSidepanelBackground || #333 ||<br />
|-<br />
| @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertreeActiveLabelColor || #ccc || ''Active'' means, user can perform an action on this item<br />
|-<br />
| @foldertreePassiveLabelColor || #ccc || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertreeHoverBackground || #888 ||<br />
|-<br />
| @foldertreeSelectedBackground || #222 ||<br />
|-<br />
| @foldertreeBadgeBackground || @bagdeBackground || see [[#Colors]] for definition of @badgeBackground<br />
|-<br />
| @foldertreeBadgeColor ||@badgeColor || see [[#Colors]] for definition of @badgeBackground<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekviewTimeline || #f00 /* red */ || Color of the Line indicating the current time<br />
|-<br />
| @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre&lt;noinclude&gt;&lt;/noinclude&gt;>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre&lt;noinclude&gt;&lt;/noinclude&gt;> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
'''Note''': This chapter is not about changing <br />
AppSuite ships with a standard set of icons containing a<br />
# favicon for desktop browsers<br />
# set of touch icons which are mainly used by mobile Safari on iOS<br />
<br />
These icons are used as default for all devices and browsers. If you wish to change these icons, you have to do this manually on your webserver where the UI is installed. The icons can not be delivered via custom themes. You should also note: You can only provide one custom icon for each resolution (more about this later), a multi-brand installation can not offer different favicons and apple-touch icons for each installed theme.<br />
<br />
All major browsers support the use of a favicon. The favicon is a pixel image with the size of 16x16 (32x32) and the "ico" file ending. (see [http://en.wikipedia.org/wiki/Favicon Wikipedia Favicon] for details).<br />
<br />
iOS devices (iPhone/iPad/iPod) support so called "Webclips". Webclips are bookmarks to websites or webapps which provide a App Icon that is shown on the iOS homescreen. AppSuite offers full support for Webclips by providing all needed App icons, splashscreens and full screen support. If a user uses the "Add to homescreen" button on his iOS device, a Webclip is created, taking the right icon for his current device. Most devices need custom resolutions of the Webclip icon in the '''png''' format.<br />
<br />
* iPhone 3: 57 x 57 px<br />
* iPhone 4 retina: 114x114 px<br />
* iPhone iPhone 5 retina: 120 x 120 px<br />
* iPad: 72 x 72 px<br />
* iPad (iOS 7): 76 x 76px<br />
* iPad retina: 144 x 144 px <br />
* iPad retina (iOS 7): 152 x 152 px <br />
<br />
Furthermore a fullscreen Webclip App will show a splashscreen, a jpg file that is displayed on startup during app load. There are currently three different resolutions as jpg files available. '''Note''': Splashscreens must be JPG files<br />
<br />
* iPhone: 320 x 460 px<br />
* iPhone 4: 640 x 920 px<br />
* iPhone 5: 640 x 1096 px<br />
<br />
'''Note''': We do not provide splashscreens for iPad<br />
<br />
This list may change with Apple's iOS updates. We recommend providing all of this resolutions when customizing the Webclip icons and splashscreens, even if some iOS devices use the next best resolution for an icon if a certain file is missing.<br />
<br />
=== Changing icons ===<br />
To provide custom icons locate the following path in your AppSuite installation:<br />
pathToAppSuite/apps/themes/icons<br />
<br />
The directory will contain two folders<br />
custom <br />
and<br />
default<br />
A clean installation will have all our default iconset in the "default" directory. The "custom" folder should be empty, only containing a <tt>.htaccess</tt> and a <tt>README</tt> file. Keep the <tt>.htaccess</tt> file unchanged, it will automatically handle rewrite condition to serve the right icon to the user. To customize the icons we recommend using our default icons as samples and save your customized version in the "custom" directory. "Note": The filename has to be the same as in the default folder. Otherwise the rewrite will not work and the default icons will be used.<br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Theming&diff=16696AppSuite:Theming2013-12-11T13:45:42Z<p>Alexander.quast: /* Theming the login page */</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Theming</div><br />
<br />
'''Abstract.''' In this article, you can learn how to create customized themes and use them to change the look of you appsuite installation.<br />
__TOC__<br />
== LESS.JS ==<br />
Appsuite used LESS as dynamic stylesheet language. LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions.<br />
<br />
Please read [http://lesscss.org/#docs LESS.JS] documentation first.<br />
<br />
=== Using less.js ===<br />
If your theme depends on less.js, you will need one more step to make it work. Why? To accelerate the login, compilation of LessCSS files was moved from the login process in the browser to the installation process on the backend. <br />
<br />
Backend packages for themes and any apps which ship .less files require the following changes:<br />
<br />
1. Add "skipLess=1" to the build command in *.spec and in debian/rules:<br />
sh /opt/open-xchange-appsuite-dev/bin/build-appsuite app skipLess=1<br />
2. Add %post and %postun sections to *.spec:<br />
%post<br />
if [ "$1" = 1 ]; then<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
fi<br />
%postun<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the %post and %postun sections should apply only to backend packages <br />
which contain .less files.<br />
<br />
3. Add debian/postinst and debian/postrm containing the same content:<br />
#!/bin/sh<br />
UPDATE=/opt/open-xchange/appsuite/share/update-themes.sh<br />
[ -x $UPDATE ] && $UPDATE<br />
<br />
For multiple binary packages, the postinst and postrm files should apply only to backend packages which contain .less files.<br />
<br />
Note: Since 7.2.1, LessCSS files must have the file extension .less to be usable with the 'less' RequireJS plugin (module dependencies of the form 'less!filename.less'). Previously we were more lenient and dealt with .css, too.<br />
<br />
== File structure ==<br />
A theme basically consists of two files located in <code>apps/themes/<var>THEME_ID</var>/</code>. These files are described in this and the following sections.<br />
<br />
<code><var>THEME_ID</var></code> is a unique identifier for your theme, which is not visible to users. By convention, it is best derived from a domain name you control, e.g. <code>com.example.prettytheme</code>.<br />
<br />
=== definitions.less ===<br />
This file can be used to override variables described in the "Variables" section of this article.<br />
<br />
=== style.less ===<br />
This file can be used to define any CSS you like. Before doing this, check, if there really is no variable that can be used to achieve the same thing.<br />
<br />
=== Referencing paths ===<br />
Since 7.2.1, all URLs are relative to the source .less file in which they are contained. This means that unless a theme changes an image it does not need to include that image anymore. <br />
<br />
Old themes must be updated if they change an image from the default theme: All styles from the default theme which refer to a changed image must be overwritten in the custom theme. This way the URLs resolve to the new image.<br />
<br />
== Variables ==<br />
<br />
Naming of the variables should be straight forward. Variables containing the word ''Background'' will always refer to the background color. Variables containing ''Color'' will refer to the foreground color of an element, like color of a font. ''Hover'' in most cases means "hovered" elements. ''Selected'' relates to the currently selected item. Elements that are supposed to catch the users eye can use the ''Highlight'' class and the variable contains this word.<br />
<br />
=== Basic ===<br />
<br />
==== Font ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @sansFontFamily || "Helvetica Neue", Helvetica, Arial, sans-serif<br />
|-<br />
| @serifFontFamily || Georgia, "Times New Roman", Times, serif<br />
|-<br />
| @monoFontFamily || Monaco, Menlo, Consolas, "Courier New", monospace<br />
|-<br />
| @baseFontSize || 14px<br />
|-<br />
| @baseFontFamily || @sansFontFamily<br />
|-<br />
| @baseLineHeight || 20px<br />
|-<br />
| @altFontFamily || @serifFontFamily<br />
|-<br />
| @touchFontSize || 15px<br />
|-<br />
| @headingsFontFamily || inherit<br />
|-<br />
| @headingsFontWeight || bold<br />
|-<br />
| @fontSizeLarge || @baseFontSize * 1.25<br />
|-<br />
| @fontSizeSmall || @baseFontSize * 0.85<br />
|-<br />
| @fontSizeMini || @baseFontSize * 0.75<br />
|-<br />
| @vgridFontSize || 13px<br />
|}<br />
<br />
==== Colors ====<br />
<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @bodyBackground || @white<br />
|-<br />
| @textColor || @grayDark<br />
|-<br />
| @linkColor || #08c<br />
|-<br />
| @linkColorHover || darken(@linkColor, 15%)<br />
|-<br />
| @linkAccentColor || #ffad00<br />
|-<br />
| @linkAccentColorHover || darken(@linkAccentColor, 15%)<br />
|-<br />
| @badgeColor || @white<br />
|-<br />
| @badgeBackground || #555<br />
|-<br />
| @headingsColor || inherit<br />
|-<br />
| @black || #000<br />
|-<br />
| @grayDarker || #222<br />
|-<br />
| @grayDark || #333<br />
|-<br />
| @gray || #555<br />
|-<br />
| @grayLight || #aaa<br />
|-<br />
| @grayLighter || #eee<br />
|-<br />
| @white || #fff<br />
|-<br />
| @blue || darken(#049cdb, 5%)<br />
|-<br />
| @blueDark || #0064cd<br />
|-<br />
| @blueLight || lighten(#049cdb, 25%)<br />
|-<br />
| @green || #1A8D1A<br />
|-<br />
| @greenLight || #92D050<br />
|-<br />
| @red || #cc0000<br />
|-<br />
| @yellow || #F8E400<br />
|-<br />
| @orange || #f89406<br />
|-<br />
| @pink || #E01CD9<br />
|-<br />
| @purple || #7E16CF<br />
|-<br />
|}<br />
<br />
==== Space ====<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paddingLarge || 11px 19px<br />
|-<br />
| @paddingSmall || 2px 10px<br />
|-<br />
| @paddingMini || 0 6px<br />
|-<br />
| @baseBorderRadius || 4px<br />
|-<br />
| @borderRadiusLarge || 6px<br />
|-<br />
| @borderRadiusSmall || 3px<br />
|}<br />
<br />
=== Pagination ===<br />
<br />
Used where pagination is done, for example in the Calendar weekview, each week is on one "page"; one can switch the week using a pagination widget styled with these variables.<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @paginationBackground || #fff<br />
|-<br />
| @paginationBorder || #ddd<br />
|-<br />
| @paginationActiveBackground || #f5f5f5<br />
|}<br />
<br />
=== Buttons ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @btnBackground || @white<br />
|-<br />
| @btnBackgroundHighlight || darken(@white, 10%)<br />
|-<br />
| @btnBorder || #bbb<br />
|-<br />
| @btnPrimaryBackground || @linkColor<br />
|-<br />
| @btnPrimaryBackgroundHighlight || spin(@btnPrimaryBackground, 20%)<br />
|-<br />
| @btnInfoBackground || #5bc0de<br />
|-<br />
| @btnInfoBackgroundHighlight || #2f96b4<br />
|-<br />
| @btnSuccessBackground || #62c462<br />
|-<br />
| @btnSuccessBackgroundHighlight || #51a351<br />
|-<br />
| @btnWarningBackground || lighten(@orange, 15%)<br />
|-<br />
| @btnWarningBackgroundHighlight || @orange<br />
|-<br />
| @btnDangerBackground || #ee5f5b<br />
|-<br />
| @btnDangerBackgroundHighlight || #bd362f<br />
|-<br />
| @btnInverseBackground || #444<br />
|-<br />
| @btnInverseBackgroundHighlight || @grayDarker<br />
|}<br />
<br />
=== Dropdowns ===<br />
<br />
{|<br />
! Variable || Default || Description<br />
|-<br />
| @dropdownBackground || @white<br />
|-<br />
| @dropdownBorder || rgba(0,0,0,.2)<br />
|-<br />
| @dropdownDividerTop || #e5e5e5<br />
|-<br />
| @dropdownDividerBottom || @white<br />
|-<br />
| @dropdownLinkColor || @grayDark<br />
|-<br />
| @dropdownLinkColorHover || @white<br />
|-<br />
| @dropdownLinkColorActive || @white<br />
|-<br />
| @dropdownLinkBackgroundActive || @linkColor<br />
|-<br />
| @dropdownLinkBackgroundHover || @dropdownLinkBackgroundActive<br />
|}<br />
<br />
=== Foldertree ===<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @foldertreeSidepanelBackground || #333 ||<br />
|-<br />
| @foldertreeSectionTitleColor || #888 || Color for sectiontitles in foldertree (like "Public" folders)<br />
|-<br />
| @foldertreeActiveLabelColor || #ccc || ''Active'' means, user can perform an action on this item<br />
|-<br />
| @foldertreePassiveLabelColor || #ccc || ''Passive'' means, user can '''not''' perform any action with this item <br />
|-<br />
| @foldertreeHoverBackground || #888 ||<br />
|-<br />
| @foldertreeSelectedBackground || #222 ||<br />
|-<br />
| @foldertreeBadgeBackground || @bagdeBackground || see [[#Colors]] for definition of @badgeBackground<br />
|-<br />
| @foldertreeBadgeColor ||@badgeColor || see [[#Colors]] for definition of @badgeBackground<br />
|}<br />
<br />
=== Calendar ===<br />
==== Appointment ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @appointmentReserved || #08c /* blue */ || Appointment status color<br />
|-<br />
| @appointmentTemporary || #ffbb00 /* yellow */ || Appointment status color<br />
|-<br />
| @appointmentAbsent || #913f3f /* red */ || Appointment status color<br />
|-<br />
| @appointmentFree || #8eb360 /* green */ || Appointment status color<br />
|-<br />
| @appointmentPrivate || #555 /* gray */ || Appointment status color<br />
|-<br />
| @appointmentDeclinedFont || #888 /* dark gray */|| Font color for declined Appointments<br />
|-<br />
| @appointmentUnconfirmedAlpha || 0.4 || Transparency value for unconfirmed Appointments<br />
|-<br />
| @appointmentDeclinedAlpha || 0.3 || Transparency value for declined Appointments<br />
|-<br />
| @appointmentHoverPct || 15% || Percentage increase of the dark pigment content on hover effect<br />
|}<br />
<br />
==== Week View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @weekviewAppointmentLasso || #aeaeff || Lasso frame color<br />
|-<br />
| @weekviewDayIn || #fff /* white */ || Default background color in week view<br />
|-<br />
| @weekviewDayOut || #e0e0e0 /* grey */ || Background color outside of the mean working time<br />
|-<br />
| @weekviewTimeline || #f00 /* red */ || Color of the Line indicating the current time<br />
|-<br />
| @weekviewTimeWith || 58px || With of the time labels on the left side<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar <br />
|}<br />
<br />
==== Month View ====<br />
{|<br />
! Variable || Default || Description <br />
|-<br />
| @monthviewAppointmentOut || #aaa /* light gray */ || Color of appointments, which are not in focus<br />
|-<br />
| @monthviewToday || #daefff /* light blue */|| Background color of the current day<br />
|-<br />
| @calendarToolbarHeight || 41px || Height of the control toolbar<br />
|}<br />
<br />
== Area names ==<br />
<br />
The variables sometimes refer to common areas. To identify which area is located where, see the following annotated screenshots.<br />
<br />
[[File:Colors_mail.png|800px||Mail application]]<br />
<br />
[[File:Colors_launchpad.png|800px||Launchpad application]]<br />
<br />
== Replacing the logo ==<br />
<br />
One of the most common theme changes which requires editing <code>style.css</code> is changing the logo in the top right corner. The logo is displayed as the background image for an element with the ID <code>io-ox-top-logo-small</code>. A theme can therefore change the size and URL of the image:<br />
#io-ox-top-logo-small {<br />
width: 60px;<br />
height: 22px;<br />
margin: 8px 13px 0 13px;<br />
background-image: url(mylogo.png);<br />
}<br />
The file <code>mylogo.png</code> is expected to be in the same directory as <code>style.css</code>. If you want to place the image somewhere else, then use a relative path in <code>url()</code>.<br />
<br />
Remember that images in OX App Suite are served by the web server and not by the application server. This means that images need to be packaged separately (for dedicated web servers) and installed in <code>/var/www/appsuite/</code> (or similar, depending on the target platform) instead of <code>/opt/open-xchange/appsuite/</code>. Direct support for multiple packages is coming in version 7.4.1. Until then, use the build system from the <code>develop</code> branch to [[AppSuite:UI_build_system#init-packaging|initialize the packaging]] if your theme contains images.<br />
<br />
== Mixins ==<br />
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:<br />
<br />
=== Sample ===<br />
<pre class="language-css"><br />
.border-radius(@radius: 0px) {<br />
-webkit-border-radius: @radius;<br />
-moz-border-radius: @radius;<br />
-ms-border-radius: @radius;<br />
border-radius: @radius;<br />
}<br />
<br />
#menu a {<br />
color: #111;<br />
.border-radius(5px);<br />
}<br />
</pre><br />
<br />
Read [http://www.lesscss.org/#-mixins LESS Mixins]<br />
<br />
=== global OX Mixins ===<br />
<br />
they can be found at [[#definitions.less | definitions.less]]<br />
<br />
{|<br />
! Mixin || Sample || Description <br />
|-<br />
| .box-sizing(@boxmodel) || .box-sizing(border-box) ||<br />
|-<br />
| .user-select(@select) || .user-select(none) ||<br />
|-<br />
| .border-radius(@radius) || .border-radius(3px) ||<br />
|-<br />
| .box-shadow(@shadow) || .box-shadow(3px) ||<br />
|-<br />
| .vertical-gradient(@startColor, @endColor) || .vertical-gradient(#888, #555) ||<br />
|-<br />
| .radial-gradient(@color1, @color2, @color3) || .radial-gradient(#111, #222, #333) ||<br />
|-<br />
| .transition(@transition) || .transition(background-color 0.2s linear) ||<br />
|-<br />
| .animation(@animation) || .animation(slidein 300ms) ||<br />
|-<br />
| .animation-name(@name) || .animation-name(slideright) ||<br />
|-<br />
| .ellipsis || .ellipsis ||<br />
|-<br />
| .overflow(@type) || .overflow(hidden) ||<br />
|-<br />
| .overflow-x(@type) || .overflow-x(hidden) ||<br />
|-<br />
| .overflow-y(@type) || .overflow-y(hidden) ||<br />
|-<br />
| .backface-visibility(@type) || .backface-visibility(hidden) ||<br />
|}<br />
<br />
== How to activate a theme during development ==<br />
<br />
When creating a new theme, you will want to test changes quickly without building packages reinstalling them. The trick is to use [[Appsuite:Appserver|appserver]].<br />
<br />
# First, you need to add the theme to the list of available themes on the backend. Simply create a new file in <code>/opt/open-xchange/etc/settings/</code> with the extension <code>.properties</code> and add a line for your theme to it: <pre&lt;noinclude&gt;&lt;/noinclude&gt;>io.ox/core/settingOptions//themes/<var>ID</var>=<var>Theme Name</var></pre&lt;noinclude&gt;&lt;/noinclude&gt;> Replace <var>ID</var> by the identifier (directory name) of your theme, and <var>Theme Name</var> by the human-readable name which should appear in the UI.<br />
# The server needs to be restarted to read the new settings.<br />
# Now, you can use <code>appserver</code> ([[AppSuite:appserver#Use_with_Apache|with a local web server]] if your theme includes images) to get your theme in combination with the UI which is already installed on the backend.<br />
# Finally, activate your theme the list in the <code>Settings -> Basic</code> view behind the option <code>Theme</code>.<br />
<br />
In case you also want to access the same backend without <code>appserver</code> while your theme is selected, that theme (or at least some empty <code>.less</code> files) should be also installed on the backend to avoid errors. To just use an empty theme, run the following as root:<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/definitions.less<br />
touch /opt/open-xchange/appsuite/apps/themes/<var>ID</var>/style.less<br />
/opt/open-xchange/appsuite/share/update-themes.sh<br />
The value of <var>ID</var> here must be the same as in your <code>.properties</code> file.<br />
<br />
== Favicons and mobile homescreen icons ==<br />
<br />
== Theming the login page ==<br />
<br />
The login page is a little bit special. If you don’t use the [[Open-Xchange_servlet_for_external_login_masks|form login]] and provide your own login page, you might want to theme the login page, too. [[AppSuite:Theming the login page|Learn how to do this here]].<br />
<br />
== Best practice ==<br />
<br />
To be really safe, it’s best to only define your own values for the variables shown above. If this really breaks anything, we consider this a bug, please report it [https://bugs.open-xchange.com/] in our bugzilla.<br />
<br />
Of course, using CSS in <code>style.less</code> file to define your own styles is also possible. Make sure to test your style in such cases more carefully. It is most likely safe to change minor things using this file, but if you plan to change any positions of larger elements, this might break the complete design. So please be careful when overwriting the default CSS rules.<br />
<br />
== Links ==<br />
[http://bradfrost.github.io/this-is-responsive/resources.html Responsive design]<br />
<br />
[http://lesscss.org/ LESS]<br />
<br />
== Caveats ==<br />
<br />
It is '''not''' recommended to change the size of elements or their position. If you really want to do so, please check on all devices and in all browsers and make sure you didn’t break anything. You even have to be careful when changing the font, because this might have effects on positioning, too.<br />
<br />
As mentioned before, changing colors should be safe.<br />
<br />
[[Category:AppSuite]]<br />
[[Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Test_basics&diff=16623AppSuite:Test basics2013-12-02T14:13:24Z<p>Alexander.quast: </p>
<hr />
<div>Lessons learned painfully while doing testing:<br />
* PhantomJS thinks it is a touch device (Modernizr.touch === true)<br />
* Almost no CSS is loaded. Don't rely on classes like "hidden" (bootstrap class)<br />
* Don't clear <body> (e.g. $(document.body).empty()). UI is not robust against that.<br />
* The browser window is elastic. It has no fixed size. Usually affects scrolling tests.<br />
* If weird things happen, try to check if your app/window/node is really still in the DOM.<br />
* HTML fixtures cannot be loaded (don't know why yet); just rename your files to *.txt<br />
* Please mind that your fake server only works inside "description" (not across specs)<br />
* PhantomJS fails at: Date.parse("2012-01-01"); (see https://code.google.com/p/phantomjs/issues/detail?id=267#c2)<br />
* The fake server is global, if someone has registered your desired api/call already, your response will never get send<br />
<br />
[[Category:UI]]<br />
[[Category:AppSuite]]<br />
[[Category:Developer]]<br />
[[Category:Testing]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=OXSessionFormLogin&diff=15347OXSessionFormLogin2013-08-19T10:11:39Z<p>Alexander.quast: added example for mobile web interface</p>
<hr />
<div>= Form Login =<br />
<br />
The form login is a mechanism, that allows you to create a custom login form, by which way a user may enter the OX frontend. All you need to do, is have the form POST the necessary login information and the location of the OX frontend. The OX server will create a session, set all necessary cookies and forward the browser to the frontend. <br />
<br />
<br />
== Parameters ==<br />
<br />
The parameters that the OX servers login process expects are:<br />
<br />
; login<br />
: The login name. This will usually be a text input.<br />
; password<br />
: The users password. This will usually be a password input field.<br />
; client<br />
: The client parameter used to distinguish between programs using the same cookie store. Since we want the new session to be used by the AJAX frontend, we'll set this to '''com.openexchange.ox.gui.dhtml''' for the OX6 frontend and to '''open-xchange-appsuite''' for App Suite. This is a hidden field. See also [[OXSessionGlossary]] <br />
; version<br />
: A version string. The content is not really relevant, but it will be logged, so we can later find out, where a login request came from. The UI will usually send its version, we'll send '''Form Login''' so we can see in the logfile when our spiffy new form was used to log in. This will also be a hidden field.<br />
; autologin<br />
: This tells the frontend whether to attempt to store the session data for a later autologin. This can only be true if server configuration parameter '''com.openexchange.sessiond.autologin''' is enabled as well, otherwise the UI will attempt to store the session and trigger a server error. See [[OXSessionAutologin]] for more details about the autologin process.<br />
; uiWebPath<br />
: Tells the server where to find the frontend, so it can redirect the browser there. This will usually be a relative URL, since the backend and frontend are usually accessible using the same host (they have to be to allow for the same source policy in javascript). '''Make sure to always send the browser to the index.html and NOT the ox.html'''. The index.html contains some browser checks that have to be done before entering the UI. You'll save yourself headaches by always sending the user to the index.html. Usually this will point to '''/ox6/index.html''' for the OX6 frontend or '''/appsuite/''' (note the trailing slash) for App Suite. This also is a hidden field.<br />
; authId<br />
: A random string used for tracking a login requests way through your apache / OX setup.<br />
<br />
<br />
== Example ==<br />
<br />
So, in essence, what we need is a form for POSTing to the backend with the above parameters. This is pretty basic HTML stuff:<br />
<br />
<syntaxhighlight lang='html4strict'><br />
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><br />
<html><br />
<head><br />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"><br />
<meta http-equiv="cache-control" content="no-cache"><br />
<title>Login</title><br />
<script type="text/javascript"><br />
function uuid() {<br />
function hex(len, x) {<br />
if (x === undefined) x = Math.random();<br />
var s = new Array(len);<br />
for (var i = 0; i < len; i++) {<br />
x *= 16;<br />
var digit = x & 15;<br />
s[i] = digit + (digit < 10 ? 48 : 87); // '0' and 'a' - 10<br />
}<br />
return String.fromCharCode.apply(String, s);<br />
}<br />
return [hex(8), "-", hex(4), "-4", hex(3), "-", hex(4, 0.5 + Math.random() / 4), "-", hex(12)].join("");<br />
}<br />
</script><br />
</head><br />
<body><br />
<form action="/ajax/login?action=formlogin&authId=" method="post" onSubmit="this.action += uuid();"><br />
<p><br />
<label for="login">Username: </label><br />
<input type="text" name="login" id="login"><br><br />
<label for="password">Password: </label><br />
<input type="password" name="password" id="password"><br><br />
<input type="submit" value="Login"><br />
<input type="hidden" name="version" value="Form Login"><br />
<input type="hidden" name="autologin" value="true"><br />
<br />
<!-- When using OX App Suite --><br />
<input type="hidden" name="client" value="open-xchange-appsuite"><br />
<!-- Important: value of uiWebPath MUST be terminated by a trailing slash "/" --><br />
<input type="hidden" name="uiWebPath" value="/appsuite/"><br />
<br />
<!-- When using OX6 --><br />
<!-- <input type="hidden" name="client" value="com.openexchange.ox.gui.dhtml"> --><br />
<!-- <input type="hidden" name="uiWebPath" value="/ox6/index.html"> --><br />
<br />
<!-- When using Mobile Web Interface --><br />
<!-- <input type="hidden" name="client" value="com.openexchange.mobileapp"> --><br />
<!-- <input type="hidden" name="uiWebPath" value="/mobile/index.html"> --><br />
</p><br />
</form><br />
</body><br />
</html><br />
</syntaxhighlight> <br />
<br />
Notice the form sends its entries to '''/ajax/login?action=formlogin'''. This relative URL will only work if the form is accessed using the same host name as the OX server. If you want to send the user to the OX server from a different host, specify the whole address in the forms action attribute, e.g. '''https://ox.mydomain.com/ajax/login?action=formlogin'''. The '''uiWebPath''' though is always considered relative to the OX server (regardless of where the form resides), so you're usually good when using a relative link there. <br />
<br />
Now back to the '''authId'''. In order to generate a unique String we'll define a javascript function in the head of the document.<br />
<br />
We won't worry about the details here, only one thing matters to us at this point: This bit of javascript generates a random UUID that we can use for our authId parameter. Since we want to see that parameter in the apache log files, we have to pass this as part of the URL. This means, when the user submits the form, we'll append a generated authId to the URL.<br />
<br />
If you're uncomfortable using javascript for this, you might opt for having the form page generated by a server side script and just include the random UUID in the form definition. The only thing to remember about this is: You need the '''authId''' parameter, it must be part of the URL, so it shows up in logfiles and it must be unique so that it makes sense when later tracking what happens to a login request. In total our form page looks like this:<br />
<br />
== Login Errors ==<br />
<br />
What happens if an error occurs during the login process? For example, the user might have entered the wrong password? In that case the OX Server uses an error template, you may override, to display an error message. It's basic, but functional:<br />
<br />
<syntaxhighlight lang='html4strict'><br />
<html><br />
<script type="text/javascript"><br />
// Display normal HTML for 5 seconds, then redirect via referrer.<br />
setTimeout(redirect,5000);<br />
function redirect(){<br />
var referrer=document.referrer;<br />
var redirect_url;<br />
// If referrer already contains failed parameter, we don't add a 2nd one.<br />
if(referrer.indexOf("login=failed")>=0){<br />
redirect_url=referrer;<br />
}else{<br />
// Check if referrer contains multiple parameter<br />
if(referrer.indexOf("?")<0){<br />
redirect_url=referrer+"?login=failed";<br />
}else{<br />
redirect_url=referrer+"&login=failed";<br />
}<br />
}<br />
// Redirect to referrer<br />
window.location.href=redirect_url;<br />
}<br />
</script><br />
<body><br />
<h1>ERROR_MESSAGE</h1><br />
</body><br />
</html><br />
</syntaxhighlight><br />
<br />
What does it do? It displays the error message for 5 seconds and the redirects back to the referrer, meaning: Your form. It adds a login=failed parameter to the URL, so your form may react when something went wrong. If you think (like myself) this form lacks the, ah well, je-ne-sais-quoi of a nice error page, then fret not! You can provide your own custom template. To do that, open up the file '''/opt/openexchange/etc/groupware/login.properties''' and set the '''com.openexchange.ajax.login.errorPageTemplate''' to point to a file on the OX system that contains your template. For example:<br />
<br />
com.openexchange.ajax.login.errorPageTemplate=/opt/openexchange/local/loginErrors.html<br />
<br />
<br />
Then write the template. Keep in mind, that ERROR_MESSAGE will be replaced by the actual error message of the login attempt (say "Your password was not valid" or somesuch). The template above might be a good starting point for you to start experimenting.<br />
<br />
<br />
<br />
[[Category: OX6]]<br />
[[Category: v6.20]]<br />
[[Category: HTTP API]]<br />
[[Category: Details]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=Portal:AppSuite_UI/Topics&diff=14540Portal:AppSuite UI/Topics2013-05-13T07:35:54Z<p>Alexander.quast: </p>
<hr />
<div>== Getting started ==<br />
* [[AppSuite:UI developer primer| Skills needed to develop the UI]]<br />
* [[AppSuite:Getting started developing the UI | Getting started developing the UI]]<br />
* [[AppSuite:UI_Development_Style_Guide | UI Development Style Guide]]<br />
* [[AppSuite:Apache Configuration | Apache Configuration]]<br />
* [[AppSuite:Definition of done|Definition of done]]<br />
<br />
== How-to articles ==<br />
* [[AppSuite:Action links|Understanding action links]]<br />
** [[AppSuite:Files App Actions|Adding actions to the files app]]<br />
* [[AppSuite:Date_and_time|Date and time]]<br />
* [[AppSuite:i18n | Internationalization (i18n)]]<br />
* [[AppSuite:Mediaplayer | Mediaplayer]]<br />
* [[AppSuite:Theming | Theming]]<br />
* [[AppSuite:UI manifests explained | UI manifests explained]]<br />
* [[AppSuite:Upsell | Upsell]]<br />
* [[AppSuite:VGrid | VGrid]]<br />
* [[AppSuite:Mobile | Mobile development]]<br />
<br />
=== Server communication ===<br />
* [[AppSuite:APIs | APIs]]<br />
* [[AppSuite:API_Factory | API Factory]]<br />
* [[AppSuite:http.js | http.js]]<br />
<br />
=== Extension points ===<br />
* [[AppSuite:Extending_the_UI_(Hands-on_introduction)| Hands-on introduction]]<br />
* [[AppSuite:Extending_the_UI | General information on extension points]]<br />
* [[AppSuite:Extension points for email | E-Mail extension points]]<br />
* [[AppSuite:Modifying forms by using extension points | Modifying forms]]<br />
<br />
=== Writing components ===<br />
* [[AppSuite:Writing a portal plugin | Writing a portal plugin]]<br />
* [[AppSuite:Writing a simple application | Writing a simple application]]<br />
* [[AppSuite:Writing a notification area plugin | Writing a plugin for the notification area]]<br />
<br />
== Miscellaneous articles ==<br />
* [[AppSuite:External libraries for the UI | External libraries used by the UI]]<br />
* [[AppSuite:Configuration| Configuration]]<br />
* [[AppSuite:UI build system| The UI build system]]<br />
* All articles regarding the UI are filed in the category [[:Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=Portal:AppSuite_UI/Topics&diff=14539Portal:AppSuite UI/Topics2013-05-13T07:21:00Z<p>Alexander.quast: </p>
<hr />
<div>== Getting started ==<br />
* [[AppSuite:UI developer primer| Skills needed to develop the UI]]<br />
* [[AppSuite:Getting started developing the UI | Getting started developing the UI]]<br />
* [[AppSuite:UI_Development_Style_Guide | UI Development Style Guide]]<br />
* [[AppSuite:Apache Configuration | Apache Configuration]]<br />
* [[AppSuite:Definition of done|Definition of done]]<br />
<br />
== How-to articles ==<br />
* [[AppSuite:Action links|Understanding action links]]<br />
** [[AppSuite:Files App Actions|Adding actions to the files app]]<br />
* [[AppSuite:Date_and_time|Date and time]]<br />
* [[AppSuite:i18n | Internationalization (i18n)]]<br />
* [[AppSuite:Mediaplayer | Mediaplayer]]<br />
* [[AppSuite:Theming | Theming]]<br />
* [[AppSuite:UI manifests explained | UI manifests explained]]<br />
* [[AppSuite:Upsell | Upsell]]<br />
* [[AppSuite:VGrid | VGrid]]<br />
* [[AppSuite:Mobile | Mobile development]]<br />
* [[AppSuite:Mobile_Support | Mobile support]]<br />
<br />
=== Server communication ===<br />
* [[AppSuite:APIs | APIs]]<br />
* [[AppSuite:API_Factory | API Factory]]<br />
* [[AppSuite:http.js | http.js]]<br />
<br />
=== Extension points ===<br />
* [[AppSuite:Extending_the_UI_(Hands-on_introduction)| Hands-on introduction]]<br />
* [[AppSuite:Extending_the_UI | General information on extension points]]<br />
* [[AppSuite:Extension points for email | E-Mail extension points]]<br />
* [[AppSuite:Modifying forms by using extension points | Modifying forms]]<br />
<br />
=== Writing components ===<br />
* [[AppSuite:Writing a portal plugin | Writing a portal plugin]]<br />
* [[AppSuite:Writing a simple application | Writing a simple application]]<br />
* [[AppSuite:Writing a notification area plugin | Writing a plugin for the notification area]]<br />
<br />
== Miscellaneous articles ==<br />
* [[AppSuite:External libraries for the UI | External libraries used by the UI]]<br />
* [[AppSuite:Configuration| Configuration]]<br />
* [[AppSuite:UI build system| The UI build system]]<br />
* All articles regarding the UI are filed in the category [[:Category:UI]]</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Mobile&diff=14538AppSuite:Mobile2013-05-10T13:48:24Z<p>Alexander.quast: </p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Developing for mobile devices</div><br />
<br />
==Introduction==<br />
<br />
App Suite is designed to work on all device types and sizes. The UI uses responsive design principles to scale nicely on each device size. We do define three display sizes to macht the majority of devices. These are simply named "small", "medium" and "large". Theses classes are used to match smartphones, tablets and desktop PCs. If you are developing a app for App Suite make sure it runs nicely and looks great on all of these three device categories. (If you are not familiar with latest CSS techniques and the principles of responsive design you should have a look at this [[AppSuite:UI_developer_primer | article]]).<br />
<br />
Often the simple use of media queries is not enough to customize your app for small and medium screens, you may need to customize your application code as well. We have integrated a function to detect everything you might want to know during runtime in your javascript code.<br />
<br />
==Sizes==<br />
<br />
The minimum device target size is 320 x 480 pixels. Your App should work on devices with this resolution.<br />
<br />
{| border=1<br />
|-<br />
|small || up to 480px<br />
|-<br />
|medium || 481px up to 1024px<br />
|-<br />
|large || 1025px and higher<br />
|}<br />
<br />
==The _.device function==<br />
<br />
We extended underscore with a new function called <tt>_.device</tt><br />
<br />
The <tt>_.device()</tt> function can be used to retrieve informations about the device. The function takes a string as argument which contains a boolean expression. This expression will be evaluated and the result is returned as a boolean.<br />
<br />
The device function uses <tt>_.browser</tt> object for informations in combination with <tt>_.screenInfo</tt><br />
<br />
==Examples for _.device==<br />
<pre class="language-javascript"><br />
// handle different mobile operating systems<br />
if (_.device('ios')) {<br />
// true for all devices running iOS, no matter what version<br />
console.log('you are running iOS');<br />
}<br />
<br />
// combined statements<br />
if (_.device('ios && android')) {<br />
// true for all android and iOS devices<br />
}<br />
<br />
// negation<br />
if (_.device('!android')) {<br />
// true for all devices except android <br />
}<br />
<br />
// screen information<br />
if (_.device('small && iOS ')) {<br />
// true for iPhone, not for iPad<br />
}<br />
<br />
// shorthands<br />
_.device('smartphone')<br />
// true for small devices running a mobile OS (iOS, Android, BB or Windowsphone)<br />
<br />
_.device('tablet')<br />
// true for medium sized devices running a mobile OS<br />
<br />
_.device('desktop')<br />
// true for all devices not running a mobile OS<br />
<br />
// getting version informations<br />
_.device('ios > 5 || android > 4') <br />
// true for ios > 5, i.e. 5.1 and 6. Same for Android, 4.0 will fail 4.1 or 4.2 will be true. <br />
<br />
// enhanced screen information <br />
_.device('iOS && retina && small')<br />
// true for iPhone 4, 4s and 5 (retina display)<br />
<br />
_.device('landscape && android && medium') <br />
// true for android tablet held in landscape mode<br />
<br />
// other information, simple browser detection<br />
_.device('safari || firefox')<br />
<br />
</pre><br />
<br />
Please note that information about device orientation may change during usage.<br />
<br />
==Mobile considerations==<br />
<br />
As of today mobile usage has become much more important than some years ago. Always consider the the fact a user may want to use your App on a smartphone. So, optimizing for mobile should not be last step in your development process, it should be one of the first. This will safe you a lot of painful debugging and layout fixes.<br />
<br />
You should ask you a simple question: Does function X in my App do have a mobile use case? Or more simple: Will anybody use this on a smartphone? <br />
If not, disable or remove this function on a mobile device. Nobody will perform a complex 35-click action in your App on a smartphone.<br />
<br />
Developing for mobile should follow some simple rules:<br />
* Mobile phones do have small screens. Safe space in your layout, reduce margins and paddings.<br />
* Touch is not click, keep buttons and links big enough to be touchable. 40px should be a minium.<br />
* Mobile networks are slow and have a high latency. Safe network requests and handle failing requests properly<br />
* Mobile devices are not as fast as desktop PCs. Not everybody has a high end smartphone so keep your code clean and fast<br />
* Always test your App on a real device</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Mobile&diff=14537AppSuite:Mobile2013-05-10T13:46:03Z<p>Alexander.quast: </p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Developing for mobile devices</div><br />
<br />
==Introduction==<br />
<br />
App Suite is designed to work on all device types and sizes. The UI uses responsive design principles to scale nicely on each device size. We do define three display sizes to macht the majority of devices. These are simply named "small", "medium" and "large". Theses classes are used to match smartphones, tablets and desktop PCs. If you are developing a app for App Suite make sure it runs nicely and looks great on all of these three device categories. (If you are not familiar with latest CSS techniques and the principles of responsive design you should have a look at this [[AppSuite:UI_developer_primer | article]]).<br />
<br />
Often the simple use of media queries is not enough to customize your app for small and medium screens, you may need to customize your application code as well. We have integrated a function to detect everything you might want to know during runtime in your javascript code.<br />
<br />
==Sizes==<br />
<br />
The minimum device target size is 320 x 480 pixels. Your App should work on devices with this resolution.<br />
<br />
{| border=1<br />
|-<br />
|small || up to 480px<br />
|-<br />
|medium || 481px up to 1024px<br />
|-<br />
|large || 1025px and higher<br />
|}<br />
<br />
==The _.device function==<br />
<br />
We extended underscore with a new function called <tt>_.device</tt><br />
<br />
The <tt>_.device()</tt> function can be used to retrieve informations about the device. The function takes a string as argument which contains a boolean expression. This expression will be evaluated and the result is returned as a boolean.<br />
<br />
The device function uses <tt>_.browser</tt> object for informations in combination with <tt>_.screenInfo</tt><br />
<br />
==Examples for _.device==<br />
<pre class="language-javascript"><br />
// handle different mobile operating systems<br />
if (_.device('ios')) {<br />
// true for all devices running iOS, no matter what version<br />
console.log('you are running iOS');<br />
}<br />
<br />
// combined statements<br />
if (_.device('ios && android')) {<br />
// true for all android and iOS devices<br />
}<br />
<br />
// negation<br />
if (_.device('!android')) {<br />
// true for all devices except android <br />
}<br />
<br />
// screen information<br />
if (_.device('small && iOS ')) {<br />
// true for iPhone, not for iPad<br />
}<br />
<br />
// shorthands<br />
_.device('smartphone')<br />
// true for small devices running a mobile OS (iOS, Android, BB or Windowsphone)<br />
<br />
_.device('tablet')<br />
// true for medium sized devices running a mobile OS<br />
<br />
_.device('desktop')<br />
// true for all devices not running a mobile OS<br />
<br />
// getting version informations<br />
_.device('ios > 5 || android > 4') <br />
// true for ios > 5, i.e. 5.1 and 6. Same for Android, 4.0 will fail 4.1 or 4.2 will be true. <br />
<br />
// enhanced screen information <br />
_.device('iOS && retina && small')<br />
// true for iPhone 4, 4s and 5 (retina display)<br />
<br />
_.device('landscape && android && medium') <br />
// true for android tablet held in landscape mode<br />
<br />
// other information, simple browser detection<br />
_.device('safari || firefox')<br />
<br />
</pre><br />
<br />
Please note that information about device orientation may change during usage.<br />
<br />
==Mobile considerations==<br />
<br />
As of today mobile usage has become much more important than some years ago. Always consider the the fact a user may want to use your App on a smartphone. So, optimizing for mobile should not be last step in your development process, it should be one of the first. This will safe you a lot of painful debugging and layout fixes.<br />
<br />
You should ask you a simple question: Does function X in my App do have a mobile use case? Or more simple: Will anybody use this on a smartphone? <br />
If not, disable or remove this function on a mobile device. Nobody will perform a complex 35-click action in your App on a smartphone.<br />
<br />
Developing for mobile should follow some simple rules:<br />
* Mobile phones do have small screens. Safe space in your layout, reduce margins and paddings.<br />
* Touch is not click, keep buttons and links big enough to be touchable. 40px should be a minium.<br />
* Mobile networks are slow and have a high latency. Safe network requests and handle failing requests properly<br />
* Mobile devices are not as fast as dekstop PC. Not everybody has a high end smartphone so keep your code clean and fast<br />
* Always test your App on a real device</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Mobile&diff=14536AppSuite:Mobile2013-05-10T13:27:03Z<p>Alexander.quast: </p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Developing for mobile devices</div><br />
<br />
==Introduction==<br />
<br />
App Suite is designed to work on all device types and sizes. The UI uses responsive design principles to scale nicely on each device size. We do define three display sizes to macht the majority of devices. These are simply named "small", "medium" and "large". Theses classes are used to match smartphones, tablets and desktop PCs. If you are developing a app for App Suite make sure it runs nicely and looks great on all of these three device categories. (If you are not familiar with latest CSS techniques and the principles of responsive design you should have a look at this [[AppSuite:UI_developer_primer | article]]).<br />
<br />
Often the simple use of media queries is not enough to customize your app for small and medium screens, you may need to customize your application code as well. We have integrated a function to detect everything you might want to know during runtime in your javascript code.<br />
<br />
==Sizes==<br />
<br />
The minimum device target size is 320 x 480 pixels. Your App should work on devices with this resolution.<br />
<br />
{| border=1<br />
|-<br />
|small || up to 480px<br />
|-<br />
|medium || 481px up to 1024px<br />
|-<br />
|large || 1025px and higher<br />
|}<br />
<br />
==The _.device function==<br />
<br />
We extended underscore with a new function called <tt>_.device</tt><br />
<br />
The <tt>_.device()</tt> function can be used to retrieve informations about the device. The function takes a string as argument which contains a boolean expression. This expression will be evaluated and the result is returned as a boolean.<br />
<br />
The device function uses <tt>_.browser</tt> object for informations in combination with <tt>_.screenInfo</tt><br />
<br />
==Examples==<br />
<pre class="language-javascript"><br />
// handle different mobile operating systems<br />
if (_.device('ios')) {<br />
// true for all devices running iOS, no matter what version<br />
console.log('you are running iOS');<br />
}<br />
<br />
// combined statements<br />
if (_.device('ios && android')) {<br />
// true for all android and iOS devices<br />
}<br />
<br />
// negation<br />
if (_.device('!android')) {<br />
// true for all devices except android <br />
}<br />
<br />
// screen information<br />
if (_.device('small && iOS ')) {<br />
// true for iPhone, not for iPad<br />
}<br />
<br />
// shorthands<br />
_.device('smartphone')<br />
// true for small devices running a mobile OS (iOS, Android, BB or Windowsphone)<br />
<br />
_.device('tablet')<br />
// true for medium sized devices running a mobile OS<br />
<br />
_.device('desktop')<br />
// true for all devices not running a mobile OS<br />
<br />
// getting version informations<br />
_.device('ios > 5 || android > 4') <br />
// true for ios > 5, i.e. 5.1 and 6. Same for Android, 4.0 will fail 4.1 or 4.2 will be true. <br />
<br />
// enhanced screen information <br />
_.device('iOS && retina && small')<br />
// true for iPhone 4, 4s and 5 (retina display)<br />
<br />
_.device('landscape && android && medium') <br />
// true for android tablet held in landscape mode<br />
<br />
// other information, simple browser detection<br />
_.device('safari || firefox')<br />
<br />
</pre><br />
<br />
Please note that information about device orientation may change during usage.</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Mobile&diff=14535AppSuite:Mobile2013-05-10T13:26:16Z<p>Alexander.quast: </p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Developing for mobile devices</div><br />
<br />
==Introduction==<br />
<br />
App Suite is designed to work on all device types and sizes. The UI uses responsive design principles to scale nicely on each device size. We do define three display sizes to macht the majority of devices. These are simply named "small", "medium" and "large". Theses classes are used to match smartphones, tablets and desktop PCs. If you are developing a app for App Suite make sure it runs nicely and looks great on all of these three device categories. (If you are not familiar with latest CSS techniques and the principles of responsive design you should have a look at this [[AppSuite:UI_developer_primer | article]]).<br />
<br />
Often the simple use of media queries is not enough to customize your app for small and medium screens, you may need to customize your application code as well. We have integrated a function to detect everything you might want to know during runtime in your javascript code.<br />
<br />
==Sizes==<br />
<br />
The minimum device target size is 320 x 480 pixels. Your App should work on devices with this resolution.<br />
<br />
{| border=1<br />
|-<br />
|small || up to 480px<br />
|-<br />
|medium || 481px up to 1024px<br />
|-<br />
|large || 1025px and higher<br />
|}<br />
<br />
==The _.device function==<br />
<br />
We extended underscore with a new function called <tt>_.device</tt><br />
<br />
The <tt>_.device()</tt> function can be used to retrieve informations about the device. The function takes a string as argument which contains a boolean expression. This expression will be evaluated and the result is returned as a boolean.<br />
<br />
The device function uses <tt>_.browser</tt> object for informations in combination with <tt>_.screenInfo</tt><br />
<br />
==Examples==<br />
<pre class="language-javascript"><br />
// handle different mobile operating systems<br />
if (_.device('ios')) {<br />
// true for all devices running iOS, no matter what version<br />
console.log('you are running iOS');<br />
}<br />
<br />
// combined statements<br />
if (_.device('ios && android')) {<br />
// true for all android and iOS devices<br />
}<br />
<br />
// negation<br />
if (_.device('!android')) {<br />
// true for all devices except android <br />
}<br />
<br />
// screen information<br />
if (_.device('small && iOS ')) {<br />
// true for iPhone, not for iPad<br />
}<br />
<br />
// shorthands<br />
_.device('smartphone')<br />
// true for small devices running a mobile OS (iOS, Android, BB or Windowsphone)<br />
<br />
_.device('tablet')<br />
// true for medium sized devices running a mobile OS<br />
<br />
_.device('desktop')<br />
// true for all devices not running a mobile OS<br />
<br />
// getting version informations<br />
_.device('ios > 5 && android > 4') <br />
// true for ios > 5, i.e. 5.1 and 6. Same for Android, 4.0 will fail 4.1 or 4.2 will be true. <br />
<br />
// enhanced screen information <br />
_.device('iOS && retina && small')<br />
// true for iPhone 4, 4s and 5 (retina display)<br />
<br />
_.device('landscape && android && medium') <br />
// true for android tablet held in landscape mode<br />
<br />
// other information, simple browser detection<br />
_.device('safari || firefox')<br />
<br />
</pre><br />
<br />
Please note that information about device orientation may change during usage.</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Mobile&diff=14534AppSuite:Mobile2013-05-10T13:22:03Z<p>Alexander.quast: </p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Developing for mobile devices</div><br />
<br />
==Introduction==<br />
<br />
App Suite is designed to work on all device types and sizes. The UI uses responsive design principles to scale nicely on each device size. We do define three display sizes to macht the majority of devices. These are simply named "small", "medium" and "large". Theses classes are used to match smartphones, tablets and desktop PCs. If you are developing a app for App Suite make sure it runs nicely and looks great on all of these three device categories. (If you are not familiar with latest CSS techniques and the principles of responsive design you should have a look at this [[AppSuite:UI_developer_primer | article]]).<br />
<br />
Often the simple use of media queries is not enough to customize your app for small and medium screens, you may need to customize your application code as well. We have integrated a function to detect everything you might want to know during runtime in your javascript code.<br />
<br />
==Sizes==<br />
<br />
The minimum device target size is 320 x 480 pixels. Your App should work on devices with this resolution.<br />
<br />
{| border=1<br />
|-<br />
|small || up to 480px<br />
|-<br />
|medium || 481px up to 1024px<br />
|-<br />
|large || 1025px and higher<br />
|}<br />
<br />
==The _.device function==<br />
<br />
We extended underscore with a new function called <tt>_.device</tt><br />
<br />
The <tt>_.device()</tt> function can be used to retrieve informations about the device. The function takes a string as argument which contains a boolean expression. This expression will be evaluated and the result is returned as a boolean.<br />
<br />
The device function uses <tt>_.browser</tt> object for informations in combination with <tt>_.screenInfo</tt><br />
<br />
==Examples==<br />
<pre class="language-javascript"><br />
// handle different mobile operating systems<br />
if (_.device('ios')) {<br />
// true for all devices running iOS, no matter what version<br />
console.log('you are running iOS');<br />
}<br />
<br />
// combined statements<br />
if (_.device('ios && android')) {<br />
// true for all android and iOS devices<br />
}<br />
<br />
// negation<br />
if (_.device('!android')) {<br />
// true for all devices except android <br />
}<br />
<br />
// screen information<br />
if (_.device('small && iOS ')) {<br />
// true for iPhone, not for iPad<br />
}<br />
<br />
// shorthands<br />
_.device('smartphone')<br />
// true for small devices running a mobile OS (iOS, Android, BB or Windowsphone)<br />
<br />
_.device('tablet')<br />
// true for medium sized devices running a mobile OS<br />
<br />
_.device('desktop')<br />
// true for all devices not running a mobile OS<br />
<br />
// getting version informations<br />
_.device('ios > 5 && android > 4') <br />
// true for ios > 5, i.e. 5.1 and 6. Same for Android, 3.x will fail 4.0 or 4.1 will be true. <br />
<br />
// enhanced screen information <br />
_.device('iOS && retina && small')<br />
// true for iPhone 4, 4s and 5 (retina display)<br />
<br />
_.device('landscape && android && medium') <br />
// true for android tablet held in landscape mode<br />
<br />
// other information, simple browser detection<br />
_.device('safari || firefox')<br />
<br />
</pre><br />
<br />
Please note that information about device orientation may change during usage.</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Mobile&diff=14533AppSuite:Mobile2013-05-10T13:13:11Z<p>Alexander.quast: </p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Developing for mobile devices</div><br />
<br />
==Introduction==<br />
<br />
App Suite is designed to work on all device types and sizes. The UI uses responsive design principles to scale nicely on each device size. We do define three display sizes to macht the majority of devices. These are simply named "small", "medium" and "large". Theses classes are used to match smartphones, tablets and desktop PCs. If you are developing a app for App Suite make sure it runs nicely and looks great on all of these three device categories. (If you are not familiar with latest CSS techniques and the principles of responsive design you should have a look at this [[AppSuite:UI_developer_primer | article]]).<br />
<br />
Often the simple use of media queries is not enough to customize your app for small and medium screens, you may need to customize your application code as well. We have integrated a function to detect everything you might want to know during runtime in your javascript code.<br />
<br />
==Sizes==<br />
<br />
The minimum device target size is 320 x 480 pixels. Your App should work on devices with this resolution.<br />
<br />
{| border=1<br />
|-<br />
|small || up to 480px<br />
|-<br />
|medium || 480px up to 1024px<br />
|-<br />
|large || 1024px and higher<br />
|}<br />
<br />
==The _.device function==<br />
<br />
We extended underscore with a new function called <tt>_.device</tt><br />
<br />
The <tt>_.device()</tt> function can be used to retrieve informations about the device. The function takes a string as argument which contains a boolean expression. This expression will be evaluated and the result is returned as a boolean.<br />
<br />
The device function uses <tt>_.browser</tt> object for informations in combination with <tt>_.screenInfo</tt><br />
<br />
==Examples==<br />
<pre class="language-javascript"><br />
// handle different mobile operating systems<br />
if (_.device('ios')) {<br />
// true for all devices running iOS, no matter what version<br />
console.log('you are running iOS');<br />
}<br />
<br />
// combined statements<br />
if (_.device('ios && android')) {<br />
// true for all android and iOS devices<br />
}<br />
<br />
// negation<br />
if (_.device('!android')) {<br />
// true for all devices except android <br />
}<br />
<br />
// screen information<br />
if (_.device('small && iOS ')) {<br />
// true for iPhone, not for iPad<br />
}<br />
<br />
// shorthands<br />
_.device('smartphone')<br />
// true for small devices running a mobile OS (iOS, Android, BB or Windowsphone)<br />
<br />
_.device('tablet')<br />
// true for medium sized devices running a mobile OS<br />
<br />
_.device('desktop')<br />
// true for all devices not running a mobile OS<br />
<br />
// getting version informations<br />
_.device('ios > 5 && android > 4') <br />
// true for ios > 5, i.e. 5.1 and 6. Same for Android, 3.x will fail 4.0 or 4.1 will be true. <br />
<br />
// enhanced screen information <br />
_.device('iOS && retina && small')<br />
// true for iPhone 4, 4s and 5 (retina display)<br />
<br />
_.device('landscape && android && medium') <br />
// true for android tablet held in landscape mode<br />
<br />
// other information, simple browser detection<br />
_.device('safari || firefox')<br />
<br />
</pre><br />
<br />
Please note that information about device orientation may change during usage.</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Mobile&diff=14532AppSuite:Mobile2013-05-10T13:11:13Z<p>Alexander.quast: </p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Developing for mobile devices</div><br />
<br />
==Introduction==<br />
<br />
App Suite is designed to work on all device types and sizes. The UI uses responsive design principles to scale nicely on each device size. We do define three display sizes to macht the majority of devices. These are simply named "small", "medium" and "large". Theses classes are used to match smartphones, tablets and desktop PCs. If you are developing a app for App Suite make sure it runs nicely and looks great on all of these three device categories. (If you are not familiar with latest CSS techniques and the principles of responsive design you should have a look at this [[AppSuite:UI_developer_primer | article]]).<br />
<br />
Often the simple use of media queries is not enough to customize your app for small and medium screens, you may need to customize your application code as well. We have integrated a function to detect everything you might want to know during runtime in your javascript code.<br />
<br />
==Sizes==<br />
<br />
The minimum device target size is 320 x 480 pixels. Your App should work on devices with this resolution.<br />
<br />
{| border=1<br />
|-<br />
|small || up to 480px<br />
|-<br />
|medium || 480px up to 1024px<br />
|-<br />
|large || 1024px and higher<br />
|}<br />
<br />
==The _.device function==<br />
<br />
We extended underscore with a new function called <tt>_.device</tt><br />
<br />
The <tt>_.device</tt> function can be used to retrieve informations about the device. The function takes a string as argument which contains a boolean expression. This expression will be evaluated and the result is returned as a boolean.<br />
<br />
The device function uses <tt>_.browser</tt> object for informations in combination with <tt>_.screenInfo</tt><br />
<br />
<br />
==Examples==<br />
<br />
<pre class="language-javascript"><br />
// handle different mobile operating systems<br />
if (_.device('ios')) {<br />
// true for all devices running iOS, no matter what version<br />
console.log('you are running iOS');<br />
}<br />
<br />
// combined statements<br />
if (_.device('ios && android')) {<br />
// true for all android and iOS devices<br />
}<br />
<br />
// negation<br />
if (_.device('!android')) {<br />
// true for all devices except android <br />
}<br />
<br />
// screen information<br />
if (_.device('small && iOS ')) {<br />
// true for iPhone, not for iPad<br />
}<br />
<br />
// shorthands<br />
_.device('smartphone')<br />
// true for small devices running a mobile OS (iOS, Android, BB or Windowsphone)<br />
<br />
_.device('tablet')<br />
// true for medium sized devices running a mobile OS<br />
<br />
_.device('desktop')<br />
// true for all devices not running a mobile OS<br />
<br />
// getting version informations<br />
_.device('ios > 5 && android > 4') <br />
// true for ios > 5, i.e. 5.1 and 6. Same for Android, 3.x will fail 4.0 or 4.1 will be true. <br />
<br />
// enhanced screen information <br />
_.device('iOS && retina && small')<br />
// true for iPhone 4, 4s and 5 (retina display)<br />
<br />
_.device('landscape && android && medium') <br />
// true for android tablet held in landscape mode<br />
<br />
// other information, simple browser detection<br />
_.device('safari || firefox')<br />
<br />
</pre><br />
<br />
Please note that information about device orientation may change during usage.</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Mobile&diff=14531AppSuite:Mobile2013-05-10T13:02:35Z<p>Alexander.quast: </p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Developing for mobile devices</div><br />
<br />
==Introduction==<br />
<br />
App Suite is designed to work on all device types and sizes. The UI uses responsive design principles to scale nicely on each device size. We do define three display sizes to macht the majority of devices. These are simply named "small", "medium" and "large". Theses classes are used to match smartphones, tablets and desktop PCs. If you are developing a app for App Suite make sure it runs nicely and looks great on all of these three device categories. (If you are not familiar with latest CSS techniques and the principles of responsive design you should have a look at this [[AppSuite:UI_developer_primer | article]]).<br />
<br />
Often the simple use of media queries is not enough to customize your app for small and medium screens, you may need to customize your application code as well. We have integrated a function to detect everything you might want to know during runtime in your javascript code.<br />
<br />
==Sizes==<br />
<br />
The minimum device target size is 320 x 480 pixels. Your App should work on devices with this resolution.<br />
<br />
<br />
<br />
==The _.device function==<br />
<br />
We extended underscore with a new function called <tt>_.device</tt><br />
<br />
The <tt>_.device</tt> function can be used to retrieve informations about the device. The function takes a string as argument which contains a boolean expression. This expression will be evaluated and the result is returned as a boolean.<br />
<br />
The device function uses <tt>_.browser</tt> object for informations in combination with <tt>_.screenInfo</tt><br />
<br />
<br />
==Examples==<br />
<br />
<pre class="language-javascript"><br />
// handle different mobile operating systems<br />
if (_.device('ios')) {<br />
// true for all devices running iOS, no matter what version<br />
console.log('you are running iOS');<br />
}<br />
<br />
// combined statements<br />
if (_.device('ios && android')) {<br />
// true for all android and iOS devices<br />
}<br />
<br />
// negation<br />
if (_.device('!android')) {<br />
// true for all devices except android <br />
}<br />
<br />
// screen information<br />
if (_.device('small && iOS ')) {<br />
// true for iPhone, not for iPad<br />
}<br />
<br />
// shorthands<br />
_.device('smartphone')<br />
// true for small devices running a mobile OS (iOS, Android, BB or Windowsphone)<br />
<br />
_.device('tablet')<br />
// true for medium sized devices running a mobile OS<br />
<br />
_.device('desktop')<br />
// true for all devices not running a mobile OS<br />
<br />
// getting version informations<br />
_.device('ios > 5 && android > 4') <br />
// true for ios > 5, i.e. 5.1 and 6. Same for Android, 3.x will fail 4.0 or 4.1 will be true. <br />
<br />
// enhanced screen information <br />
_.device('iOS && retina && small')<br />
// true for iPhone 4, 4s and 5 (retina display)<br />
<br />
_.device('landscape && android && medium') <br />
// true for android tablet held in landscape mode<br />
<br />
// other information, simple browser detection<br />
_.device('safari || firefox')<br />
<br />
</pre><br />
<br />
Please note that information about device orientation may change during usage.</div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Mobile&diff=14530AppSuite:Mobile2013-05-10T12:52:51Z<p>Alexander.quast: </p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Developing for mobile devices</div><br />
<br />
==Introduction==<br />
<br />
App Suite is designed to work on all device types and sizes. The UI uses responsive design principles to scale nicely on each device size. We do define three display sizes to macht the majority of devices. These are simply named "small", "medium" and "large". Theses classes are used to match smartphones, tablets and desktop PCs. If you are developing a app for App Suite make sure it runs nicely and looks great on all of these three device categories. (If you are not familiar with latest CSS techniques and the principles of responsive design you should have a look at this [[AppSuite:UI_developer_primer | article]]).<br />
<br />
Often the simple use of media queries is not enough to customize your app for small and medium screens, you may need to customize your application code as well. We have integrated a function to detect everything you might want to know during runtime in your javascript code.<br />
<br />
==The _.device function==<br />
<br />
We extended underscore with a new function called <tt>_.device</tt><br />
<br />
The <tt>_.device</tt> function can be used to retrieve informations about the device. The function takes a string as argument which contains a boolean expression. This expression will be evaluated and the result is returned as a boolean.<br />
<br />
The device function uses <tt>_.browser</tt> object for informations in combination of <br />
<br />
==Examples==<br />
<br />
<pre class="language-javascript"><br />
// handle different mobile operating systems<br />
if (_.device('ios')) {<br />
// true for all devices running iOS, no matter what version<br />
console.log('you are running iOS');<br />
}<br />
<br />
// combined statements<br />
<br />
if (_.device('ios && android')) {<br />
// true for all android and iOS devices<br />
}<br />
<br />
// negation<br />
if (_.device('!android')) {<br />
// true for all devices except android <br />
}<br />
<br />
// screen information<br />
if (_.device('small && iOS ')) {<br />
// true for iPhone, not for iPad<br />
}<br />
<br />
// getting version informations<br />
_.device('ios > 5 && android > 4') <br />
// true for ios > 5, i.e. 5.1 and 6. Same for Android, 3.x will fail 4.0 or 4.1 will be true. <br />
<br />
// enhanced screen information <br />
_.device('iOS && retina && small')<br />
// true for iPhone 4, 4s and 5 (retina display)<br />
<br />
_.device('landscape && android && medium') <br />
// true for android tablet held in landscape mode<br />
<br />
// other information, simple browser detection<br />
_.device('safari || firefox')<br />
<br />
</pre></div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Mobile&diff=14529AppSuite:Mobile2013-05-10T12:41:36Z<p>Alexander.quast: </p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Developing for mobile devices</div><br />
<br />
==Introduction==<br />
<br />
App Suite is designed to work on all device types and sizes. The UI uses responsive design principles to scale nicely on each device size. We do define three display sizes to macht the majority of devices. These are simply named "small", "medium" and "large". Theses classes are used to match smartphones, tablets and desktop PCs. If you are developing a app for App Suite make sure it runs nicely and looks great on all of these three device categories. (If you are not familiar with latest CSS techniques and the principles of responsive design you should have a look at this [[AppSuite:UI_developer_primer | article]]).<br />
<br />
Often the simple use of media queries is not enough to customize your app for small and medium screens, you may need to customize your application code as well. We have integrated a function to detect everything you might want to know during runtime in your javascript code.<br />
<br />
==The _.device function==<br />
<br />
We extended underscore with a new function called <tt>_.device</tt><br />
<br />
The <tt>_.device</tt> function can be used to retrieve informations about the device. The function takes a string as argument which contains a boolean expression. This expression will be evaluated and the resulted is returned as a boolean.<br />
<br />
==Examples==<br />
<br />
<pre class="language-javascript"><br />
// handle different mobile operating systems<br />
if (_.device('ios')) {<br />
// true for all devices running iOS, no matter what version<br />
console.log('you are running iOS');<br />
}<br />
<br />
// combined statements<br />
<br />
if (_.device('ios && android')) {<br />
// true for all android and iOS devices<br />
}<br />
<br />
// negation<br />
if (_.device('!android')) {<br />
// true for all devices except android <br />
}<br />
<br />
// screen information<br />
if (_.device('small && iOS ')) {<br />
// true for iPhone, not for iPad<br />
}<br />
<br />
// getting version informations<br />
_.device('ios > 5 && android > 4') // true for ios > 5, i.e. 5.1 and 6. Same for Android, 3.x will fail 4.0 or 4.1 will be true<br />
<br />
<br />
</pre></div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Mobile&diff=14528AppSuite:Mobile2013-05-10T12:06:19Z<p>Alexander.quast: </p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Developing for mobile devices</div><br />
<br />
==Introduction==<br />
<br />
App Suite is designed to work on all device types and sizes. The UI uses responsive design principles to scale nicely on each device size. We do define three display sizes to macht the majority of devices. These are simply named "small", "medium" and "large". Theses classes are used to match smartphones, tablets and desktop PCs. If you are developing a app for App Suite make sure it runs nicely and looks great on all of these three device categories. (If you are not familiar with latest CSS techniques and the principles of responsive design you should have a look at this [[AppSuite:UI_developer_primer | article]]).<br />
<br />
Often the simple use of media queries is not enough to customize your app for small and medium screens, you may need to customize your application code as well. We have integrated a function to detect everything you might want to know during runtime in your javascript code.<br />
<br />
==The _.device function==<br />
<br />
We extended underscore with a new function called <tt>_.device</tt><br />
<br />
The <tt>_.device</tt> function can be used to retrieve informations about the device. The function takes a string as argument which contains a boolean expression. This expression will be evaluated and the resulted is returned as a boolean.<br />
<br />
==Examples==<br />
<br />
<pre class="language-javascript"><br />
// handle different mobile operating systems<br />
if (_.device('ios')) {<br />
// true for all devices running iOS, no matter what version<br />
console.log('you are running iOS');<br />
}<br />
<br />
<br />
<br />
</pre></div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Mobile&diff=14527AppSuite:Mobile2013-05-10T11:41:27Z<p>Alexander.quast: </p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Developing for mobile devices</div><br />
<br />
==Introduction==<br />
<br />
App Suite is designed to work on all device types and sizes. The UI uses responsive design principles to scale nicely on each device size. We do define three display sizes to macht the majority of devices. These are simply named "small", "medium" and "large". Theses classes are used to match smartphones, tablets and desktop PCs. If you are developing a app for App Suite make sure it runs nicely and looks great on all of these three device categories. (If you are not familiar with latest CSS techniques and the principles of responsive design you should have a look at this [[AppSuite:UI_developer_primer | article]]).<br />
<br />
Often the simple use of media queries is not enough to customize your app for small and medium screens, you may need to customize your application code as well. We have integrated a function to detect everything you might want to know during runtime in your javascript code.<br />
<br />
==The _.device function==<br />
<br />
We extended underscore with a new function called <tt>_.device</tt></div>Alexander.quasthttps://oxpedia.org/wiki/index.php?title=AppSuite:Mobile&diff=14526AppSuite:Mobile2013-05-10T11:11:36Z<p>Alexander.quast: Created page with "{{Stability-experimental}} <div class="title">Developing for mobile devices</div> ==Introduction== App Suite is designed to work on all device types and sizes. The UI uses r..."</p>
<hr />
<div>{{Stability-experimental}}<br />
<br />
<div class="title">Developing for mobile devices</div><br />
<br />
==Introduction==<br />
App Suite is designed to work on all device types and sizes. The UI uses responsive design principles to scale nicely on each device size. We do define three display sizes to macht the majority of devices. These are simply named "small", "medium" and "large". Theses classes are used to match smartphones, tablets and desktop PCs. These three classes are defined via CSS media queries. If you are not familiar with latest CSS techniques and the principles of responsive design you should have a look at this [[AppSuite:UI_developer_primer | article]]</div>Alexander.quast