Part 3: Design and mobile implementation

Update (28/08/2017)

A complete and optional documentation is now available along the PnP Starter Intranet version 2.0.0 with an additional fee. It includes:
– A French or English version with free updates following the latest version of the solution
– A complete development guide (about 100 pages) on how to maintain and customize this solution (add a new language, create a new component, etc.)
– A complete user guide (about 40 pages) on how to use this solution from a contributor point of view (create content, manage navigation, etc.)

This present documentation is still relevant be only for the first version(s) of the PnP Starter Intranet solution.

By

Thank you for supporting us!

As I said in the previous article, nowadays, the mobile consideration is one of the most important criteria for intranet projects. That’s a fact: end users must be able to access their intranet from a mobile device. Don’t be confused here: in this situation we are usually talking about the « publishing » part of an intranet, the one where users view the company news, announcements, etc. not the « operational » part where users work together on documents, use business workflows and applications, etc. Generally speaking, this should not be your responsibility to adapt the core SharePoint experience to be mobile (if you really want to do this, take a look at the PnP Responsive UI). That’s why Microsoft recently released the SharePoint Intranet mobile application for iOS. With this application, users are able to do basic « operational » tasks like browse documents, search for documents or people from a mobile device but the responsive/mobile publishing part is still missing. All we have is the legacy publishing infrastructure feature of SharePoint. We know that a new experience is coming soon but we don’t know exactly when and how, so for now you have only two options:

Wait for the new mobile canvas and use the actual OOTB features (basically no cost).

Implement your own mobile/responsive solution ($ to $$$ depending of the service provider…).

Both options are viable but, good news, you have now a free starter solution for the second one ;).

Designing an intranet generally involves to work on specific SharePoint artefacts. In this example, design customizations were made on the following artefacts:

All files (JavaScript , CSS, images) are uploaded into the site collection root site « Style Library ». To improve performances, we could use a CDN instead. However, using the default style library is more convenient in a SharePoint allowing you to replace some files manually if needed. If you choose to upload your file in a CDN, be careful, the files are publicly accessible.

The master page

For this example, I just created a minimal master page from the SharePoint design manager:

The master page is here just to provide the HTML container markup. Without it, you will have some troubles to implement a beautiful responsive interface for all your pages ;). The structure looks like this (notice the Knockout JS custom elements binding syntax for components):

This area will be filled in by content you create in your page layouts.

</div>

</asp:ContentPlaceHolder>

</SharePoint:AjaxDelta>

</div>

</div>

</div>

<div class="push ms-dialogHidden"></div>

</div>

<!-- Footer component -->

<component-footer></component-footer>

</div>

Notice we use directly the .master file instead of the .html file because we don’t want to deal with the conversion process (and also because there is no PnP cmdlet for this).

Bootstrap

For those who have already worked with Bootstrap and SharePoint may know that Bootstrap overrides a lot of default SharePoint styles when imported within the global context. Usually, developers create a dedicated CSS « patch » file to fix style issues generated by this override. In my case, I didn’t want to create such a file and I found this very interesting blog article. The principle is relatively simple: isolate Bootstrap styles inside a custom named CSS class to be able to use it in a more granular way and to not conflict with SharePoint global styles (at least all styles outside the main workspace like, ribbon, app launcher, etc.). Because I don’t use a « patch » file, it may result of a slightly different design especially for Web parts inside the page. If you plan to you OOTB SharePoint styles (list Web Part ,etc.) inside the main workspace area (i.e. in your pages), you may have to create one for overrides.

Because we use Webpack in the solution, it is now very easy to use a LESS loader and do the transformation automatically during the bundling sequence:

LESS

1

2

3

4

5

6

7

8

.bootstrap-iso {

/* We use a precompiled version of the Bootstrap CSS with only required elements (responsive grid and navbar) */

@import (less) 'bootstrap.css';

...

}

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

...

{

// Isolate the Bootstrap CSS to avoid conflicts with the SharePoint default CSS

// More info here: https://formden.com/blog/isolate-bootstrap

// We used a customized CSS version of Bootstrap (http://getbootstrap.com/customize/) because we don't need the full package

Compile your own Bootstrap version!

When working with Bootstrap, this is not mandatory to use ALL the framework and components capabilities. It is possible to pick and choose the part you want to keep the very necessary. For this example, I’ve just needed of the grid layout system, some navigation components and… that’s it! Got to this address to compile your own version: http://getbootstrap.com/customize/.

Styles management with SASS

Because we use a component-based approach, styles have to be modular too. SASS is a good CSS extension to do this. As an example, is is possible to split styles for each component and use a shared file for common colors and general parameters. Then, with Webpack (again), we just use a SASS loader to merge all styles either into a single CSS file (portal.css) or separeted files (layouts.css and layouts-edit.css) during bundling. As a best practice, I’ve implemented styles for each component under a single CSS identifier to avoid conflicts with other components:

Styles for the top navigation bar

Sass

1

2

3

4

5

6

7

@import'variables';

#navbar {

...

}

Make it yours!

Don’t like the intranet default colors? You can just change them by updating the variable.scss file and re-bundling the application using the
webpack cmd:

$page-icon-color:#EA4300;// Used in page info component for metadata display

$contextual-selected-color:$primary-color;

Page layouts

Usually, the page layouts encountered in intranet projects are generally the same:

Home page

Static page

News page

Search page

And that’s pretty it. With these layouts, you have the basis to build a publishing intranet..

Apply styles depending the display mode

In SharePoint page layouts, you can control what element are displayed (or loaded) in edit or display mode. We use this capability to load different style sheets depending the page mode. In fact, in edit mode, we want apply dedicated styles for fields (for example, background fields) and also, we don’t need (and want) page layouts to be responsive so we stack all fields by default.

Display templates

In the previous article, I’ve mentionned that I’ve used some utility libraries like « trunk8 » or « Moment.js » to do something like this:

Before to be able to do this, you have something to remember: when you use Webpack, your code is by default isolated in the outputted bundle(s). It means your third party libraries and your own functions are not accessible from the global « window » namespace (like « $ » or « ko« ). But what happen if you want to use them inside a SharePoint display template which is not managed by your application (for instance the trunk8 plugin)?

For obvious reasons, and even if it works, we don’t want to expose third party libraries into the global « window » namespace by including them in the master page so we have to find another way to be able to make « communications » between the SharePoint world and the application one. Webpack has a special configuration allowing you to ouput your application as a library like any other third party library. By writing the following code, you basically tell Webpack to « turn visible » your application trough the « Intranet » variable.

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

module.exports=validate({

...

output:{

...

// Expose the entry point as the 'Intranet' global var.

// We need this to be able to apply Knockout JS bindings manually for SharePoint display templates (the 'ko' variable is not exposed in the global context)

library:['Intranet']

...

},

...

Then you can use this variable to call your application functions (static preferably) directly from the « window » namespace. Because of the entry point of the application is the main.ts file and we’ve exported the « Main » class, we can make a call like this:

We use this mechanism to apply custom Knockout JS view model inside a SharePoint display template (thanks to this blog post for the idea!). Combined with custom generic binding handlers, we are now able to use our plugin whitout problem like this:

Notice the « stopBinding: true » custom Knockout binding handler. It is useful to avoid conflicts with the main ko.applyBindings() call in the main file. More info here.

Be careful, there is a downside using this approach: the script loading order. By default, Web Part search results are always loaded synchronously. Your bindings may not apply because of the loading order (your application is loaded after the search results). To avoid this behavior, we set the loading behavior to asynchronous in the search query settings. By this way we can guarantee your application will be loaded before the search results (because links in master page have priority over dynamic scripts loading).

In the next article we will talk about the navigation implementation. Stay tuned!