Table of contents
Creating themes
A theme defines the look and feel of websites in Veva. All pages in a Veva website belong to a certain template, which in turn belongs to a certain theme. You can have multiple Themes installed at the same time and use them all at once, i.e. one page can use Theme A while another page can use Theme B.
A theme defines the look and feel of websites in Veva. All pages in a Veva website belong to a certain template, which in turn belongs to a certain theme. You can have multiple Themes installed at the same time and use them all at once, i.e. one page can use Theme A while another page can use Theme B.
What is a theme?
A theme is basically a module which includes a class which implements ITheme. A custom Module can include one theme, or it can include multiple themes. The way this is organized is completely up to the developer.
What does a theme include?
A basic theme defines the base markup of a layout along with all required javascript, CSS and graphics. There are other things a nice theme can/should define, such as color palettes (Actually, any module can define a color palette!), CSS breakpoints and CSS classes.
Let's create a simple theme!
Before continuing, you should start by following the ${link:Developer reference/Getting started/Visual Studio 2022} guide to get up and running with a web application in VS, which has Veva installed. We'll assume that you have completed that guide and then you should have a solution which looks something like this:
At this time, we only have the "Default theme" installed, which is included in the "Veva.Web.Essentials" package. That's a basic Bootstrap theme. In this tutorial we are going to create a new theme which we can use on our website.
Creating the theme module
We could just be lazy and place the theme files directly under the project we already have, but we are going to go the recommended route instead. We are going to create a seperate class-library project for the theme. This has some advantages, other than just looking more clean - this way, the theme will be a separate assembly which we can reuse in other projects.
- Right-click the solution in the solution explorer and click "Add -> New project ..."
- Select "Class Library (.NET Core)" and click next
- Give the project a descriptive name, we'll name it "VevaWebsite.SimpleTheme"
- Make sure the location is correct (it should be)
- Hit "Create"
Once the new project has been created, follow these steps:
- Rename Class1.cs to Module.cs
- Right-click the SimpleTheme project and select "Add -> Class ..." and type Theme.cs and click "Add"
Then click the project file in the tree to view the project markup. We'll need to make sure that the TargetFramework node is set to "net8.0" and that we're using the correct SDK (Microsoft.NET.Sdk.Razor).
Save the changes to the project file.
Nuget packages
Before we can start to "wire up" our theme, we'll need some Nuget packages, so our theme module can reference some Veva functionality. We need to add the package "Veva.Core.Application.Modules" and "Veva.Core.Application.BlazorComponents" Nuget packages to the theme project.
- Right-click the theme project and select "Manage Nuget packages..."
- Make sure the Veva package source is select (or all)
- Search for "Veva.Core.Application.Modules" and select it
- Hit "Install"
- Search for "Veva.Core.Application.BlazorComponents" and select it
- Hit "Install"
Theme files
Let's quickly create our theme files, that is, the Layout razor component which contains the base HTML, and our CSS file.
- Right-click the theme project and select "Add -> New Folder"
- Give the folder a name, "Layout" for example, and hit "Create"
- Right-click the folder and select "Add -> New Razor Component..."
- Give it a name, let's call it "DefaultLayout.razor"
- Hit "Create"
This "DefaultLayout.razor" file contains the base HTML markup of our theme, but not the entire markup - only what's inside the <body> tag. Everything outside the <body> tag is taken care of by Veva. Now open the "DefaultLayout.razor" file and paste in this HTML markup:
@inherits LayoutComponentBase
@using Veva.Core.Application.BlazorComponents.Components;
@code { }
<div id="wrapper">
<section class="sidebar">
<TemplateContent name="sidebar" />
</section>
<main>
@Body
</main>
</div>
This is a pretty simple markup with a sidebar and a main content section. The <TemplateContent> tag is actually a Veva Blazor component which which creates an editable content area for users to place content into. The @Body statement will also create an editable content area.
Now let's create our CSS file.
- Right-click the Theme project, select "Add -> New folder"
- Name it "wwwroot" and hit "Create".
- Right-click the "wwwroot" folder and select "Add -> New Item ..."
- Locate the "Style sheet" template in the list and select it
- Name the file "styles.css" and hit "Add"
Open the "styles.css" file and paste in this CSS:
{ box-sizing: border-box; }
body, html { height:100%; }
body {
margin: 0;
font-family: sans-serif;
}#wrapper {
display:flex;
height:100%;
}section.sidebar {
background:#eaeaea;
box-shadow: 1px 1px 20px 0px silver;
min-width:200px;
}section.sidebar ul {
list-style:none;
margin:0;
padding:0;
}section.sidebar ul li a {
display:block;
padding:1em;
color:#333;
border-bottom:1px solid silver;
text-decoration:none;
}main {
padding: 1em 1em 1em 2em;
flex: 1;
}main img { max-width:100%; }
Configuring the theme
Now we will need to configure our theme and wire things up.
Open the Theme.cs file, and add these two using statements at the top:
using Veva.Core.Domain.Pages;
using VevaWebsite.SimpleTheme.Layout;
Then have the Theme class implement ITheme. Then right-click ITheme and click "Quick actions and refactoring ..." and select "Implement interface". You should get a bunch of properties and one method which need to be implemented. To save time, you can just copy-paste the following code:
using Veva.Core.Domain.Pages;
using VevaWebsite.SimpleTheme.Layout;
using System.Collections.Generic;
namespace VevaWebsite.SimpleTheme
{
public class Theme : ITheme
{
public string Name => "My Simple Theme";
public string Description => "A simple theme for demonstration purposes";
public IEnumerable<CssClass> CssClasses { get; set; } = new List<CssClass>()
{
//TODO: later
};
public IEnumerable<MediaQueryBreakpoint> MediaQueryBreakpoints { get; set; } = new List<MediaQueryBreakpoint>()
{
//TODO: later
};
public void ConfigurePageRequest(PageRequest pageRequest)
{
pageRequest.Layout = typeof(DefaultLayout);
string staticRoot = $"/_content/{GetType().Assembly.GetName().Name}";
pageRequest.MetaTags.Add(new MetaTag() { Name = "viewport", Content = "width=device-width, initial-scale=1.0" });
pageRequest.Styles.Add(new StyleReference() { Href = $"{staticRoot}/styles.css" });
}
}
}
This is how a basic Theme is wired up. We have public properties for Name, Description, CssClasses and MediaQueryBreakPoints. Then we have a void method called ConfigurePageRequest() which is takes in a PageRequest object.
A PageRequest is a Veva class which flows through the request pipeline and holds all information about the current page which is being requested. In the ConfigurePageRequest() method, the theme can set the Layout property of the PageRequest object, to specify which Razor component is used as the base markup, and also set metatags, attach styles, scripts and so forth.
That's exactly what we are doing here. We are specifying our DefaultLayout.razor file as the Layout and then we are getting the root path to our "wwwroot" folder (which is the "/_content/{GetType().Assembly.GetName().Name}" magic) and then we are adding a metatag and a reference to our styles.css file.
Configuring the Module class and registering the theme
Now we need to configure the Theme project as a Module so Veva knows about it - then we need to register the theme into the dependency-injection framework in Veva.
- Open the Module.cs file
- Make sure the class is public
- Add using Veva.Core.Domain.Modules; at the top
- Have the Module class implement IModule
- Right-click 'IModule' and click "Quick actions and refactoring ..." and select "Implement interface"
At this point you should get properties and methods which need an implementation. To save time, just copy-paste this code into your Module.cs file:
using Veva.Core.Application.DependencyInjection;
using Veva.Core.Domain.Modules;
using Veva.Core.Domain.Pages;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
namespace VevaWebsite.SimpleTheme
{
public class Module : IModule
{
public string Name => "Simple Theme";
public int Priority => 0;
public void Configure(IApplicationBuilder app, IHostEnvironment env, ILoggerFactory loggerFactory)
{
}
public void ConfigureMvc(IMvcBuilder mvc)
{
}
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
services.AddNamed<ITheme, Theme>("My Simple Theme");
}
}
}
NOTE: The name you pass as an argument into the AddNamed() method above must match the name of the theme, which is the Name property of the Theme class!
The final step is to have the VevaWebsite project reference the VevaWebsite.SimpleTheme project.
- Right-click the "Dependencies" node in the tree under the "VevaWebsite" project
- Click "Add project reference ..."
- You should see the "VevaWebsite.SimpleTheme" project in the list, check the checkbox next to it
- Hit "OK"
Your theme should now be ready for use!
Using the theme
Now run the project and once it has loaded up, append "/veva" to the URL and authenticate into the system if prompted. We are going to set this new theme as the default theme for our website, since all pages are set to use the "website default theme" initially. To do that, we need to go to the "Websites" module in Veva, by clicking the Veva logo and then clicking "Websites" in the navigation menu and you should get this screen:
Note that the default template for the website is currently set to "Default template (Default Theme)" which is the theme that "Veva.Web.Essentials" includes. We are going to create a new template which uses our new SimpleTheme.
- Click the pencil next to the default template selector
- Click the "Add +" button
- Give the template a name, for example "Simple Template"
- Under theme, make sure to select the correct theme, which should be "My Simple Theme"
- Hit "Save"
- Make sure to select the newly created template as the default template
- Hit the blue "Save" button in the top-right corner to save the Website settings
NOTE: If you dont see "My Simple Theme" in the list of available themes in step 4 above, make sure you added the correct project reference in step 3 in the chapter above
Now click the Veva logo and head back into the "Pages" module and if everything goes as planned, the "Frontpage" page should now be using the new template/theme and you should see something like this:
Now we can start adding content! Before we can add content to the page, we first have to switch to "Template mode" and add some components to the template itself.
Click the "Template" button which is located in the top-right corner of the screen and the page editor should switch over to template mode:
You'll notice that you can see the two areas we defined in the DefaultLayout.razor file become "alive" and ready to accept content. The "Content" area should have different content for each page and therefore we are going to add a component called "Page Area" to it.
- Click the blue "+" button on the "Content" area
- The "Add Content" dialog will slide up
- Use the search at the top and search for "Page area" and you should see the "Page Area" component
- Click it and it will be added to the page
Now for the "Sidebar" area. We would like the navigation of the website to be located there. Since we'd like that navigation to be on every page which uses this template, we are going to add the navigation component directly to the area, in template mode. Then below the navigation component we are going to place a "Page area" component so each and every page can have different content in the sidebar below the navigation.
- Click the blue "+" button on the "Sidebar" area
- The "Add Content" dialog will slide up
- Use the search at the top and search for "Navigation" and you should see the "Navigation menu" component
- Click it and it will be added to the page
By default, the navigation component will show all visible pages on the root of the website, so you should not have to make any changes to it's settings for now. Now we want to place รก "Page area" component below the navigation.
- Hover over the navigation component
- Two blue drop-shaped "+" buttons should be shown, one above and one below the component
- Since we want the area to be below the navigation, click the bottom "+" button
- The "Add Content" dialog will slide up
- Use the search at the top and search for "Page area" and you should see the "Page area" component
- Click it and it will be added to the page
- Click the blue publish button to publish the changes you've made in template mode
You should now have something that looks like this:
Now click the "Page" button in the top-right corner to go back to "page mode" and then you'll see the navigation component at the top of the sidebar and two empty areas, one below the navigation and one in the main section. These two areas are ready to accept content which will then only be applied to the selected page, the "Frontpage".
You can experiment with adding content to those areas, just by clicking the "+" button and going through the "Add content" dialog.