All Versions
DSpace Documentation
...
Whenever you are testing changes in the User Interface, may wish to see you changes "live" instead of rebuilding after each change. The easiest way to achieve this is to run the User Interface locally (i.e. on localhost) in developer mode by running:
| Code Block |
|---|
yarnnpm run start:dev |
This mode has several development-specific advantages:
...
src/app/ directories): The primary look & feel of DSpace (e.g. HTML layout, header/footer, etc) is defined by the HTML5 templates under this directory. Each HTML5 template is stored in a subdirectory named for the Angular component where that template is used. The base theme includes very limited styling (CSS, etc), based heavily on default Bootstrap (4.x) styling, and only allowing for minor tweaks to improve WCAG 2.1 AA accessibility.src/themes/custom directories): This directory acts as the scaffolding or template for creating a new custom theme. It provides (empty) Angular components/templates which allow you to change the theme of individual components. Since all files are empty by default, if you enable this theme (without modifying it), it will look identical to the Base Theme.src/themes/dspace directories): This is the default theme for DSpace 7. It's a very simple example theme providing a custom color scheme, header & homepage on top of the Base Theme. It's important to note that this theme ONLY provides custom CSS/images to override our Base Theme. All HTML5 templates are included at the Base Theme level, as this ensures those HTML5 templates are also available to the Custom Theme....
src/themes/dspace): This is a simple, example theme for novice users. Primarily, in this theme, you can immediately customize the CSS, header & homepage components. You can add other components as needed (see "Adding Component Directories to your Theme" below).src/themes/custom): This theme provides all available theme-able components for more advanced or complex theming options. This provides you full control over everything that is theme-able in the User Interfacesrc/themes/ (choose whatever folder name you want)Modify angular.json (in the root folder), adding your theme folder's main "theme.scss" file to the "styles" list. The below example is for a new theme folder named src/themes/mydspacesite/
| Code Block |
|---|
"styles": [
"src/styles/startup.scss",
{
"input": "src/styles/base-theme.scss",
"inject": false,
"bundleName": "base-theme"
},
...
{
"input": "src/themes/mydspacesite/styles/theme.scss",
"inject": false,
"bundleName": "mydspacesite-theme"
},
] |
NOTE: the "bundleName" for your custom them MUST use the format "${folder-name}-theme". E.g. if the folder is named "src/themes/amazingtheme", then the "bundleName" MUST be "amazingtheme-theme"
eager-theme.module.ts in themes/eager-themes.module.ts
| Code Block | ||
|---|---|---|
| ||
// COMMENT out the imports for any themes you are NOT using
//import { EagerThemeModule as DSpaceEagerThemeModule } from './dspace/eager-theme.module';
//import { EagerThemeModule as CustomEagerThemeModule } from './custom/eager-theme.module';
// Add a new import for your custom theme. Give its EagerThemeModule a unique name (e.g. "as [choose-a-unique-name]").
// Make sure the path points at its "eager-theme.module.ts" (see 'from' portion of the import statement).
// NOTE: You can import multiple themes if you plan to use multiple themes
import { EagerThemeModule as MyThemeEagerThemeModule } from './my-theme/eager-theme.module';
...
@NgModule({
imports: [
// Again, comment out any themes you are NOT using
//DSpaceEagerThemeModule,
//CustomEagerThemeModule,
// Add your custom theme's EagerThemeModule to this list
// NOTE: you can add multiple theme's to this list if you plan to use multiple themes.
MyThemeEagerThemeModule,
],
}) |
Enable your theme: Modify your config/config.*.yml configuration file (in 7.1 or 7.0 this file was named src/environments/environment.*.ts), adding your new theme to the "themes" array in that file. Pay close attention to modify the correct configuration file (e.g. modify config.dev.yml if running in dev mode, or config.prod.yml if running in prod mode). We recommend starting in "dev mode" (config.dev.yml) as this mode lets you see your changes immediately in a browser without a full rebuild of the UI – see next step.
| Code Block | ||||
|---|---|---|---|---|
| ||||
# In this example, we only show one theme enabled. It's possible to enable multiple (see below note) themes: - name: 'mydspacesite' |
| Code Block | ||
|---|---|---|
| ||
// In this example, we only show one theme enabled. It's possible to enable multiple (see below note)
themes: [
{
name: 'mydspacesite'
},
] |
src/themes/mydspacesite/ globally. You should also comment out the default "dspace" theme, if you intend to replace it entirely.Verify your settings by starting the UI (ideally in Dev mode): At this point, you should verify the basic settings you've made all "work". We recommend doing your theme work while running the UI in "dev mode", as the UI will auto-restart anytime you save a new change. This will allow you to quickly see the impact of each change in your browser.
| Code Block |
|---|
# Start in dev mode (which uses config.dev.yml) yarnnpm run start:dev |
...
styles folder (e.g. src/themes/mydspacesite/styles). There are four main files in that folder:_theme_sass_variable_overrides.scss - May be used to override Bootstrap's default Sass variables. This is the file you may wish to use for most style changes. There are a large number of Bootstrap variables available which control everything from fonts, colors and the base style for all Bootstrap web components. For a full list of Bootstrap variables you can override in this file, see the node_modules/bootstrap/scss/_variables.scss file (which is installed in your source directory when you run "yarn installnpm install"). More information may also be found in the Bootstrap Sass documentation at https://getbootstrap.com/docs/4.0/getting-started/theming/#sass_theme_css_variable_overrides.scss - May be used to override DSpace's default CSS variables. DSpace's UI uses CSS variables for all its components. These variables all start with "--ds-*", and are listed in src/styles/_custom_variables.scss. You can also use this file to add your own, custom CSS variables which you want to use for your theme. If you create custom variables, avoid naming them with a "--ds-*" or a "--bs-*" prefix, as those are reserved for DSpace and Bootstrap variables._global-styles.scss - May be used to modify the global CSS/SCSS for the site. This file may be used to override the default global style contained in src/styles/_global-styles.scss . Keep in mind, many styles can be more quickly changed by simply updating a variable in one of the above "*_variable_overrides.scss" files. So, it's often easier to use those first, where possible.theme.scss - This just imports all the necessary Sass files to create the theme. It's unnecessary to modify directly, unless you with to add new Sass files to your theme._theme_sass_variable_overrides.scss file. One option is to add a new import statement and modify the "$font-family-sans-serif" variable:
| Code Block |
|---|
// Import the font (from a URL)
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro');
// Configure Bootstrap to use this font (and list a number of backup fonts to use on various systems)
$font-family-sans-serif: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default; |
assets/fonts/ folderCreate a new ".scss" file specific to your font in that folder, e.g. assets/fonts/open-sans.scss, and use the "@font-face" CSS rule to load that font:
| Code Block | ||
|---|---|---|
| ||
@font-face {
font-family: "Open Sans";
src: url("/assets/fonts/OpenSans-Regular-webfont.woff2") format("woff2"),
url("/assets/fonts/OpenSans-Regular-webfont.woff") format("woff");
} |
Then, import that new "open-sans.scss" file and use it in the "$font-family-sans-serif" variable
| Code Block |
|---|
// Import the font via the custom SCSS file @import '../assets/fonts/open-sans'; // Configure Bootstrap to use this font (and list a number of backup fonts to use on various systems) $font-family-sans-serif: 'Open Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default; |
_theme_sass_variable_overrides.scss file. node_modules/bootstrap/scss/_variables.scss file...
assets/images/ folder. Anything in this theme folder will be deployed to /assets/[theme-name]/images/ URL path.Edit your theme's app/header/header.component.ts file. Swap the "templateUrl" property that your theme is using the local copy of "header.component.html"
| Code Block | ||
|---|---|---|
| ||
@Component({
selector: 'ds-header',
// styleUrls: ['header.component.scss'],
styleUrls: ['../../../../app/header/header.component.scss'],
// Uncomment the templateUrl which references the "header.component.html" file in your theme directory
templateUrl: 'header.component.html',
// Comment out the templateUrl which references the default "src/app/header/header.component.html" file.
//templateUrl: '../../../../app/header/header.component.html',
}) |
header.component.html file will be empty by default. Copy over the default HTML code from src/app/header/header.component.html into your version of this file.Then, modify your copy of header.component.html to use your logo. In this example, we're assuming your theme name is "mytheme" and the logo file is named "my-logo.svg"
| Code Block |
|---|
<header>
<div class="container">
<div class="d-flex flex-row justify-content-between">
<a class="navbar-brand my-2" routerLink="/home">
<!-- Modify the logo on the next line -->
<img src="/assets/mytheme/images/my-logo.svg" [attr.alt]="'menu.header.image.logo' | translate"/>
</a>
...
</header> |
<ds-search-navbar> is the search icon in the header). You can easily comment out these tags to disable them, or move them around to change where that component appears in the header.src/app/navbar/navbar.component.html) is used everywhere else. The Navbar component can be customized in the same way as the Header Component. Just edit the logo path in the "navbar.component.html"....
Edit your theme's existing app/navbar/navbar.component.html file. This file defines the entire <nav> which displays the navigation header across the entire DSpace site. While much of the content in this <nav> is loaded dynamically via other Angular components, it is possible to easily add a hardcoded link to the existing header. Find the section of this <nav> which is the <div id="collapsingNav">, as that's where you'll want to add your new link. See inline comments in the example below.
| Code Block | ||
|---|---|---|
| ||
<nav>
...
<!-- This DIV is where the header links are added dynamically.
You should see it surrounding all links in the header if you view HTML source -->
<div id="collapsingNav" ... >
<!-- The links themselves are in an unordered list (UL) -->
<ul class="navbar-nav" ... >
...
<!-- Add your new link at the end (or beginning) of this UL in a new LI tag -->
<!-- NOTE: All classes used below are the same Bootstrap CSS classes used by our 'dspace' and 'custom' themes.
You can modify them if the link doesn't look correct in your theme. -->
<li class="nav-item d-flex align-items-center">
<div class="text-md-center">
<a href="http://dspace.org" class="nav-link">DSpace.org</a>
</div>
</li>
</ul>
</div>
</nav> |
...
Edit your theme's app/footer/footer.component.ts file. Swap the "templateUrl" and "styleUrls" properties, based on which you want to modify in your theme.
| Code Block | ||
|---|---|---|
| ||
@Component({
selector: 'ds-footer',
// If you want to modify styles, then...
// Uncomment the styleUrls which references the "footer.component.scss" file in your theme's directory
// and comment out the one that references the default "src/app/footer/footer.component.scss"
styleUrls: ['footer.component.scss'],
//styleUrls: ['../../../../app/footer/footer.component.scss'],
// If you want to modify HTML, then...
// Uncomment the templateUrl which references the "footer.component.html" file in your theme's directory
// and comment out the one that references the default "src/app/footer/footer.component.html"
templateUrl: 'footer.component.html'
//templateUrl: '../../../../app/footer/footer.component.html'
}) |
footer.component.html or footer.component.scss or both.footer.component.html file will be empty by default. Copy over the default HTML code from src/app/footer/footer.component.html into your version of this file.footer.component.scss file will be empty by default. Copy over the default Sass code from src/app/footer/footer.component.scss into your version of this file.assets/images folder. Then reference them at the /assets/[theme-name]/images/ URL path.DSpace also has a option to display a two-level footer, which is becoming more common these days. By default. DSpace just displays a small, bottom footer. But, you can enable a top footer (above that default footer) by add this line into your theme's footer.component.ts
| Code Block | ||
|---|---|---|
| ||
export class FooterComponent extends BaseComponent {
// This line will enable the top footer in your theme
showTopFooter = true;
} |
This top footer appears in the footer.component.html within a div. Notice the "*ngIf='showTopFooter'", which only shows that div when that variable is set to "true"
| Code Block | ||
|---|---|---|
| ||
<footer class="text-lg-start">
<!-- This div and everything within it only displays if showTopFooter=true -->
<div *ngIf="showTopFooter" class="top-footer">
...
</div>
<!-- The bottom footer always displays -->
<div class="bottom-footer ...">
...
</div>
</footer> |
Available in 7.2 or above. In 7.1 or 7.0, the only way to change the favicon is to modify the src/assets/images/favicon.ico file.
Each theme has the ability to add Each theme has the ability to add a set of (attribute-only) HTML tags in the <head> section of the page. This is useful for example to change the favicon based on the active theme. Whenever the theme changes, the head tags are reset. A theme can inherit head tags from the parent theme only if it doesn't have any head tags itself. (E.g. theme B extends theme A; if theme B does not have head tags, the head tags of theme A will be used (if any). However, if theme B does have head tags, only the tags from theme B will be used.) If none of the themes in the inheritance hierarchy have head tags configured, the head tags of the default theme (if any) will be used.
...
In the "themes" section of your config/config.*.yml configuration file, add (one or more) "headTags", pointing at the favicon file you want to use. For example:
| Code Block |
|---|
themes:
# The default dspace theme
- name: dspace
# Whenever this theme is active, the following tags will be injected into the <head> of the page.
# Example use case: set the favicon based on the active theme.
headTags:
# Insert <link rel="icon" href="assets/dspace/images/favicons/favicon.ico" sizes="any"/> into the <head> of the page.
- tagName: link
attributes:
rel: icon
href: assets/dspace/images/favicons/favicon.ico
sizes: any
# Insert <link rel="icon" href="assets/dspace/images/favicons/favicon.svg" type="image/svg+xml"/> into the <head> of the page.
- tagName: link
attributes:
rel: icon
href: assets/dspace/images/favicons/favicon.svg
type: image/svg+xml
# Insert <link rel="apple-touch-icon" href="assets/dspace/images/favicons/apple-touch-icon.png"/> into the <head> of the page.
- tagName: link
attributes:
rel: apple-touch-icon
href: assets/dspace/images/favicons/apple-touch-icon.png
# Insert <link rel="manifest" href="assets/dspace/images/favicons/manifest.webmanifest"/> into the <head> of the page.
- tagName: link
attributes:
rel: manifest
href: assets/dspace/images/favicons/manifest.webmanifest |
headTags section....
Edit your theme's app/home-page/home-news/home-news.component.ts file. Swap the "templateUrl" and "styleUrls" properties, based on which you want to modify in your theme.
| Code Block | ||
|---|---|---|
| ||
@Component({
selector: 'ds-home-news',
// If you want to modify styles, then...
// Uncomment the styleUrls which references the "home-news.component.scss" file in your theme's directory
// and comment out the one that references the default "src/app/home-page/home-news/home-news.component.scss"
styleUrls: ['./home-news.component.scss'],
//styleUrls: ['../../../../../app/home-page/home-news/home-news.component.scss'],
// If you want to modify HTML, then...
// Uncomment the templateUrl which references the "home-news.component.html" file in your theme's directory
// and comment out the one that references the default "src/app/home-page/home-news/home-news.component.html"
templateUrl: './home-news.component.html'
//templateUrl: '../../../../../app/home-page/home-news/home-news.component.html'
}) |
home-news.component.html or home-news.component.scss or both.home-news.component.html file will be empty by default. Copy over the default HTML code from src/app/home-page/home-news/home-news.component.html into your version of this file.home-news.component.scss file will be empty by default. Copy over the default Sass code from src/app/home-page/home-news/home-news.component.scss into your version of this file.assets/images folder. Then reference them at the /assets/[theme-name]/images/ URL path....
src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html" in your theme. This is where you place your changes.src/app/item-page/simple/item-types/untyped-item/untyped-item.component.scss" in your theme. This is where you place your changes.Edit your theme's app/item-page/simple/item-types/untyped-item/untyped-item.component.ts file. Swap the "templateUrl" and "styleUrls" properties, based on which you want to modify in your theme. Also, MAKE SURE the "@listableObjectComponent" is using your theme... the last parameter should be the name of your theme!
| Code Block | ||
|---|---|---|
| ||
// MAKE SURE that the final parameter here is the name of your theme. This one assumes your theme is named "custom".
@listableObjectComponent(Item, ViewMode.StandalonePage, Context.Any, 'custom')
@Component({
selector: 'ds-untyped-item',
// If you want to modify styles, then...
// Uncomment the styleUrls which references the "untyped-item.component.scss" file in your theme's directory
// and comment out the one that references the default in "src/app/"
styleUrls: ['./untyped-item.component.scss'],
//styleUrls: ['../../../../../../../app/item-page/simple/item-types/untyped-item/untyped-item.component.scss'],
// If you want to modify HTML, then...
// Uncomment the templateUrl which references the "untyped-item.component.html" file in your theme's directory
// and comment out the one that references the default "src/app/"
templateUrl: './untyped-item.component.html',
//templateUrl: '../../../../../../../app/item-page/simple/item-types/untyped-item/untyped-item.component.html',
}) |
untyped-item.component.html or untyped-item.component.scss or both.untyped-item.component.html file may be empty by default. Copy over the default HTML code from src/item-page/simple/item-types/untyped-item/untyped-item.component.html into your version of this file.untyped-item.component.scss file may be empty by default. Copy over the default Sass code from src/item-page/simple/item-types/untyped-item/untyped-item.component.scss into your version of this file<ds-generic-item-page-field> - This tag can be used to display the value of any metadata field (as a string). src/assets/i18n/en.json5" file (or corresponding file depending on your language)<ds-item-page-uri-field> - This tag can be used to display the value of any metadata field as an HTML link. (The value must already be a URL)<ds-generic-item-page-field> above.<ds-item-page-date-field> and <ds-item-page-abstract-field>). These are currently separate components under "src/app/item-page/simple/field-components/specific-field/" directories. They are hardcoded to use a specific metadata field and label, but you could customize the components in that location....
*.component.ts in your theme. *.component.scss in your theme.*.component.html in your theme.*.component.scss code (from src/app/) into your theme's component.scss file.*.component.html code (from src/app/) into your theme's component.html file.assets/images folder. Then reference them at the /assets/[theme-name]/images/ URL path....
src/assets/i18n/*.json5 file(s) directlysrc/assets/i18n/en.json5 and change the value for menu.section.browse_global .src/assets/i18n/ files. However, a specific setup is necessary, see the "Theme override approach" instructions below....
| title | Theme override approach |
|---|
...
While editing the default i18n files directly is effective, the recommended approach is to capture i18n changes in your theme. This ensures that your changes to the default values are easy to find and review and also removes the risk of losing your changes when upgrading to newer versions of DSpace.
...
Once you have changes in place within your theme, they need to be applied by executing a script:
| Code Block |
|---|
yarnnpm merge-i18n -s src/themes/[theme-name]/assets/i18n |
The merge-i18n script will merge the changes captured in your theme with the default settings, resulting in updated versions of the default i18n files. Any setting you included in your theme will override the default setting. Any new properties will be added. Files will be merged based on file name, so en.json5 in your theme will be merged with the en.json5 file in the default i18n directory.
...
Themes can extend other themes using the "extends" configuration. See User Interface Configuration for more examples.
...