Page History
...
Familiarity with these technologies (or even just CSS + HTML) is all you need to do basic theming of the DSpace UI.
Creating a Custom Theme
Theme Directories & Configuration
Out of the box, there are three theming layers/directories to be aware of:
- Base Theme (
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. - Custom Theme (
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. - DSpace 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 & 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.
More information on the UI Design principles/technologies can be found at DSpace UI Design principles and guidelines
The theming configuration can be found in the src/environments/environment.*.ts
. See User Interface Configuration.
Getting Started
...
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 namedsrc/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 "arc/themes/amazingtheme", then the "bundleName" MUST be "amazingtheme-theme"
Running the UI in Developer Mode
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 |
---|
yarn start:dev |
This mode has several development-specific advantages:
- UI starts more rapidly
- UI will use a separate "config.dev.yml" configuration file (in 7.1 or 7.0 this file was named "environment.dev.ts"). This lets you have development specific configs, separate from your Production settings in "config.prod.yml" (in 7.1 or 7.0 this file was named "environment.prod.ts")
- UI will automatically reload anytime you modify a file. Essentially the UI will constantly "watch" for changes (as you make them) & will reload anytime you modify a file. This lets you find issues/bugs more rapidly and also test more rapidly.
Keep in mind, you should NEVER run the UI in developer mode in production scenarios. Production mode provides much better performance and ensures your site fully supports SEO, etc.
Creating a Custom Theme
Theme Directories & Design Principles
A theme's directory should include the following files and directories
contains the theme's Angular components and should mirror the structure of
src/app/
assets/
contains the theme's custom assets, such as fonts or imagesstyles/
contains the theme's global styleseager-theme.module.ts
declares the components that should be included in the app's main bundle, such asEager components are those that should be available immediately when first loading, such as the main parts of the homepage and components that are present on every page.
that are registered via a decorator such as
@listableObjectComponent
. These must also be included in the module'sproviders
.
lazy-theme.module.ts
Out of the box, there are three theming layers/directories to be aware of:
- Base Theme (
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. - Custom Theme (
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. - DSpace 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.
The DSpace UI design principles & technologies are described in more detail at DSpace UI Design principles and guidelines
Getting Started
- Choose a theme to start from: As documented above, there are two "src/theme/" directories provided out of the box: "custom" or "dspace". You should select one to use as the basis for your theme. Which you choose is up to you, but here are a few things to consider:
- DSpace 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).- Advantages: This theme is small and simple. It provides an easy starting point / example for basic themes. Future User Interface upgrades (e.g. from 7.1 → 7.2) are likely to be easier because the theme is smaller in size.
- Disadvantages: It has very few component directories by default. But you can always add more. See "Adding Component Directories to your Theme" below.
- Custom Theme (
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 Interface- Advantages: All theme-able components are provided in subdirectories. This makes it easier to modify the look and feel of any area of the User Interface.
- Disadvantages: After creating your theme, you may wish to remove any component directories that you didn't modify (see "Removing Component Directories from your Theme" below). Generally speaking, upgrades (e.g. from 7.1 → 7.2) are often easier if your theme includes fewer components (as your theme may require updates if any component it references change significantly).
- DSpace Theme (
- Create your own theme folder OR edit the existing theme folder: Either edit the theme directory in place, or copy it (and all its contents) into a new folder under
src/themes/
(choose whatever folder name you want) - Register your theme folder (only necessary if you create a new folder in previous step): Now, we need to make the UI aware of this new theme folder, before it can be used in configuration.
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 namedsrc/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
inthemes/eager-themes.module.ts
Code Block title themes/eager-themes.module.ts // 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 namedsrc/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 language yml title Format for 7.2 or above (config.*.yml) # In this example, we only show one theme enabled. It's possible to enable multiple (see below note) themes: - name: 'mydspacesite'
Code Block title Format for 7.1 or 7.0 (environment.*.ts) // In this example, we only show one theme enabled. It's possible to enable multiple (see below note) themes: [ { name: 'mydspacesite' }, ]
NOTE: The "name" used is the name of the theme's folder, so the example is for enabling a theme atsrc/themes/mydspacesite/
globally. You should also comment out the default "dspace" theme, if you intend to replace it entirely.
NOTE #2: You may also choose to enable multiple themes for your site, and even specify a different theme for different Communities, Collections, Items or URL paths. See User Interface Configuration for more details on "Theme Settings"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) yarn start:dev
- At this point, you can start making changes to your theme. See the following sections for examples of how to make common changes.
Global style/font/color customizations
Changes to the global Bootstrap variables or styles will apply to all pages / Angular components across the entire site.
- Global style changes: All global style changes can be made in your theme's
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 thenode_modules/bootstrap/scss/_variables.scss
file (which is installed in your source directory when you run "yarn 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 insrc/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 insrc/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.
- Modifying the default font: By default, DSpace uses Bootstrap's "native font stack", which just uses system UI fonts. However, the font used in your site can be quickly updated via Bootstrap variables in your theme's
_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;
- If your font requires installing local files, you can do the following
- Copy your font file(s) in your theme's
assets/fonts/
folder Create 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 title open-sans.scss @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;
- Copy your font file(s) in your theme's
- Keep in mind, as changing the font just requires adjusting Bootstrap Sass variables, there are a lot of Bootstrap guides out there that can help you make more advanced changes
- Modifying default color scheme: The colors used in your site can be quickly updated via Bootstrap variables in your theme's
_theme_sass_variable_overrides.scss
file.- Again, you can use entirely Bootstrap variables to adjust color schemes. See the Bootstrap Theming Colors documentation
- A list of all Bootstrap color variables can be found in the
node_modules/bootstrap/scss/_variables.scss
file - Additional examples can be found in the out-of-the-box "dspace" theme, which adjusts the default Bootstrap colors slightly for both accessibility & to match the DSpace logo.
- Any changes require rebuilding your UI. If you are running in "dev mode" (yarn start:dev), then the UI will restart automatically whenever changes are detected.
Note | ||
---|---|---|
| ||
Support for theme switching at runtime requires that components use CSS custom properties (which vary at runtime) rather than SASS variables (which are fixed at build time). Thus, SASS variables will be undefined in individual components' stylesheets. The Bootstrap SASS variables are mapped to CSS properties for use in these places. For example, |
Customize Logo in Header
- Copy your logo to your theme's
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 title header.component.ts @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', })
- Your theme's version of the
header.component.html
file will be empty by default. Copy over the default HTML code fromsrc/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>
- Obviously, you can also make additional modifications to the HTML of the header in this file! You'll also see that the header references several other DSpace UI components (e.g.
<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. - Any changes require rebuilding your UI. If you are running in "dev mode" (yarn start:dev), then the UI will restart automatically whenever changes are detected.
- NOTE: If you have a theme based on the "dspace" theme, be aware that theme places the header logo in two locations. This allows the "dspace" theme to support a single-line header (whereas the "custom" theme's header is multi-line):
- The Header component (as described above) is only used on user profile pages
- The Navbar component (
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".
Customize Navigation Links in Header
This provides a basic example of adding in a hardcoded link to the header menu (displayed on every page in DSpace).
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 title navbar.component.html <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>
- Obviously, you can also make additional modifications to the HTML of the header in this file, as necessary for your navigation header. Keep in mind though that anything you remove may impact the dynamic content that is pulled into this navigation header.
- An example is that the header logo for the "dspace" theme also exists in this same file.
- Any changes require rebuilding your UI. If you are running in "dev mode" (yarn start:dev), then the UI will restart automatically whenever changes are detected.
Customize Footer
- First, you'll want to decide if you want to modify just the footer's HTML, or the footer's styles (CSS/Sass), or both.
- If you want to modify the HTML, you'll need to create a copy of "footer.component.html" in your theme, where you place your changes.
- If you want to modify the styles, you'll need to create a copy of "footer.component.scss" in your theme, where you place your changes.
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 title footer.component.ts @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' })
- Now, based on what you want to modify, you will need to either update your theme's copy of
footer.component.html
orfooter.component.scss
or both.- To change footer HTML: Your theme's version of the
footer.component.html
file will be empty by default. Copy over the default HTML code fromsrc/app/footer/footer.component.html
into your version of this file. - To change footer Styles: Your theme's version of the
footer.component.scss
file will be empty by default. Copy over the default Sass code fromsrc/app/footer/footer.component.scss
into your version of this file.
- To change footer HTML: Your theme's version of the
- Modify the HTML or Sass as you see fit.
- If you want to add images, add them to your theme's
assets/images
folder. Then reference them at the/assets/[theme-name]/images/
URL path. - Keep in mind, all Bootstrap variables, utility classes & styles can be used in these files. Take advantage of Bootstrap when you can do so.
- If you want to add images, add them to your theme's
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 title footer.component.ts 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 title footer.component.html <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>
- Any changes require rebuilding your UI. If you are running in "dev mode" (yarn start:dev), then the UI will restart automatically whenever changes are detected.
Customize Favicon for site or theme
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 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.
Note that a simple hardcoded favicon is set in case no head tags are currently active. The hardcoded favicon is stored at src/assets/images/favicon.ico
. This implies that if head tags are added to a theme, the favicon should also be configured explicitly for that theme, else the behavior is undefined.
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
- In 7.2 or above, any changes to this configuration just require restarting your site (no rebuild necessary). In 7.1 or 7.0, you must rebuild your site after modifying the favicon.ico.
- NOTE: If you specify multiple formats for your favicon (e.g. favicon.svg and favicon.ico), then your browser will select which one it prefers (e.g. Chrome seems to favor SVG over ICO). However, if you want to force all browser to use a single favicon, then you may wish to only specify one "icon" format in your
headTags
section.
Customize Home Page News
The primary Home page content is all included in the source code under "src/app/home-page". The News section is specifically under "src/app/home-page/home-news".
- First, you'll want to decide if you want to modify just the Home Page News HTML, or styles (CSS/Sass), or both.
- If you want to modify the HTML, you'll need to create a copy of the HTML in "app/home-page/home-news/home-news.component.html" in your theme. This is where you place your changes.
- If you want to modify the styles, you'll need to create a copy of the CSS in "app/home-page/home-news/home-news.component.scss" in your theme. This is where you place your changes.
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 title home-news.component.ts @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' })
- Now, based on what you want to modify, you will need to either update your theme's copy of
home-news.component.html
orhome-news.component.scss
or both.- To change HTML: Your theme's version of the
home-news.component.html
file will be empty by default. Copy over the default HTML code fromsrc/app/home-page/home-news/home-news.component.html
into your version of this file. - To change Styles: Your theme's version of the
home-news.component.scss
file will be empty by default. Copy over the default Sass code fromsrc/app/home-page/home-news/home-news.component.scss
into your version of this file.
- To change HTML: Your theme's version of the
- Modify the HTML or Sass as you see fit.
- If you want to add images, add them to your theme's
assets/images
folder. Then reference them at the/assets/[theme-name]/images/
URL path. - Keep in mind, all Bootstrap variables, utility classes & styles can be used in these files. Take advantage of Bootstrap when you can do so.
- If you want to add images, add them to your theme's
- Any changes require rebuilding your UI. If you are running in "dev mode" (yarn start:dev), then the UI will restart automatically whenever changes are detected.
Customize the simple Item page
The "simple" Item page is the default display for an Item (when you visit any item via a URL like [dspace.ui.url]/items/[uuid]). If you want to modify the metadata fields displayed on that page by default, that can be done quite easily.
- Normal Item: The code for the simple Item page for a normal Item (i.e. not an Entity) can be found in the source code at "
src/app/item-page/simple/item-types/untyped-item/
" - Publication Entity: If you are wanting to modify the display of Publication Entities, it has separate source code under "
src/app/item-page/simple/item-types/publication/
"
Here's the basics of modifying this page. The below examples assume you are working with a normal Item. But the same logic would work for modifying the Publication pages (you'd just need to modify it's HTML/CSS instead)
- First, you'll want to decide if you want to modify just the Item Page HTML, or styles (CSS/Sass), or both.
- If you want to modify the HTML, you'll need to create a copy of the HTML in "
src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html
" in your theme. This is where you place your changes. - If you want to modify the styles, you'll need to create a copy of the CSS in "
src/app/item-page/simple/item-types/untyped-item/untyped-item.component.scss
" in your theme. This is where you place your changes.
- If you want to modify the HTML, you'll need to create a copy of the HTML in "
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 title untyped-item.component.ts // 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', })
- Now, based on what you want to modify, you will need to either update your theme's copy of
untyped-item.component.html
oruntyped-item.component.scss
or both.- To change HTML: Your theme's version of the
untyped-item
.component.html
file may be empty by default. Copy over the default HTML code fromsrc/item-page/simple/item-types/untyped-item/untyped-item.component.html
into your version of this file. - To change Styles: Your theme's version of the
untyped-item
.component.scss
file may be empty by default. Copy over the default Sass code fromsrc/item-page/simple/item-types/untyped-item/untyped-item.component
.scss
into your version of this file
- To change HTML: Your theme's version of the
- In the HTML of the Simple Item page, you'll see a number of custom "ds-" HTML-like tags which make displaying individual metadata fields easier. These tags make it easier to add/remove metadata fields on this page.
<ds-generic-item-page-field>
- This tag can be used to display the value of any metadata field (as a string).- Put the name of the metadata field in the "[fields]" attribute... see existing fields as an example.
- Put the i18n label you want to use for this field in the "[label]" attribute. Again, see existing fields as an example. This i18n tag MUST then be added to your "
src/assets/i18n/en.json5
" file (or corresponding file depending on your language) - For example, here's a new ds-generic-item-page-field which displays the value of the "dc.title.alternative" field with a label defined in the "
<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)- This field has the same attributes at
<ds-generic-item-page-field>
above.
- This field has the same attributes at
- Some specific tags exist for other fields (e.g.
<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.
- To add new fields, just add new "<ds-generic-item-page-field>" tags (or similar). To remove fields, just comment them out or remove the HTML. You can also restructure the columns on that page using simple HTML and Bootstrap CSS.
- Any changes require rebuilding your UI. If you are running in "dev mode" (yarn start:dev), then the UI will restart automatically whenever changes are detected.
NOTE: If your changes to the simple item page don't appear to be working, make sure that you have updated the eager-theme.module.ts
to load your custom theme as described in the "Getting Started" section above! This small change is REQUIRED for the untyped-item component to work in a custom theme. You also may wish to restart your dev server to ensure nothing is being cached.
Customize other Components in your Theme
By now, if you've followed this entire guide, you'll notice a pattern! Customizing specific DSpace UI components requires just three steps:
- Configure your theme to use its copies of files: Modify the corresponding
*.component.ts
in your theme.- If you want to modify component style, replace the "styleUrls" in that file to point at the copy of
*.component.scss
in your theme. - If you want to modify component HTML, replace the "template" in that file to point at the copy of
*.component.html
in your theme.
- If you want to modify component style, replace the "styleUrls" in that file to point at the copy of
- Copy the default UI code into your theme file(s)
- If you want to modify component style, copy the default
*.component.scss
code (fromsrc/app/
) into your theme'scomponent.scss
file. - If you want to modify component HTML, copy the default
*.component.html
code (fromsrc/app/
) into your theme'scomponent.html
file.
- If you want to modify component style, copy the default
- Modify those theme-specific files
- If you want to add images, add them to your theme's
assets/images
folder. Then reference them at the/assets/[theme-name]/images/
URL path. - Keep in mind, all Bootstrap variables, utility classes & styles can be used in these files. Take advantage of Bootstrap when you can do so.
- If you want to add images, add them to your theme's
- Remember to either rebuild the UI after each change, or run in dev mode (yarn start:dev) while you are doing theme work.
Customize UI labels using Internationalization (i18n) files
Much of the text (like headers and labels) displayed by the DSpace UI is captured in translation (language pack) files to support the use of DSpace in multiple languages. This model of multi-language support is called internationalization (abbreviated i18n). The default set of these i18n files are stored in src/assets/i18n
and named using the language code, so en.json5
is the English translation, fr.json5
is the French translation, etc. In each of these files, a set of "keys" is mapped to text in the given language.
If you would like to change the text displayed in the UI, you will need to edit the i18n translation files. There are two approaches you can take:
- You can edit the
src/assets/i18n/*.json5
file(s) directly- For example, to change the label for the browse menu when viewing the UI in English (which defaults to "All of DSpace"), you would edit
src/assets/i18n/en.json5
and change the value formenu.section.browse_global
.
- For example, to change the label for the browse menu when viewing the UI in English (which defaults to "All of DSpace"), you would edit
- And/or, you can create a separate *.json5 file in your theme which only lists the keys you have changed. This can keep your language changes in your theme, and will override the default keys in the
src/assets/i18n/
files. However, a specific setup is necessary, see the "Theme override approach" instructions below.
Info | ||
---|---|---|
| ||
The following "theme override" approach to capture i18n changes within a theme is only supported in DSpace 7.1 or above. |
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.
To capture i18n changes in your theme, you will need to:
- Create an i18n directory under
src/themes/[theme-name]/assets
- For each language you would like to update, add a file to the new i18n directory following the naming scheme in the default i18n directory (en.json5 for English, fr.json5 for French, etc)
- In each translation file add only the settings that you wish to add or override
There is an example of this configuration in the custom theme, which you can find in src/themes/custom/assets/i18n
.
Once you have changes in place within your theme, they need to be applied by executing a script:
Code Block |
---|
yarn 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.
Extending other Themes
Info |
---|
This is only supported in 7.1 and above |
Themes can extend other themes using the "extends" configuration. See User Interface Configuration for more examples.
Extending another theme means that you inherit all the settings of the extended theme. So, if the current theme does NOT specify a component style, its ancestor theme(s) will be checked recursively for their styles before falling back to the default. In other words, this "extends" setting allows for a theme to inherit all styles/components from the extended theme, and only override those styles/components you wish to override.
Here's a basic example:
Code Block | ||||
---|---|---|---|---|
| ||||
themes:
# grandchild theme
- name: custom-A
extends: custom-B
handle: '10673/34'
# child theme
- name: custom-B
extends: custom
handle: 10673/2
# default theme
- name: custom |
Code Block | ||
---|---|---|
| ||
themes: [
// grandchild theme
{
name: 'custom-A',
extends: 'custom-B',
handle: '10673/34',
},
// child theme
{
name: 'custom-B',
extends: 'custom',
handle: '10673/2',
},
// default theme
{
name: 'custom',
},
], |
In the above examples:
- When the object at Handle '10673/2' (and any child objects) is viewed, the 'custom-B' theme will be used. By default, you'll have the same styles as the extended 'custom' theme. However, you can override individual styles in your 'custom-B' theme.
- When the object at Handle '10673/34' (and any child objects) is viewed, the 'custom-A' theme will be used. By default, your overall theme will be based on the 'custom' theme (in this case a "grandparent" theme). But, you can override those styles in your 'custom-B' theme or 'custom-A' theme.
- The order of priority is 'custom-A', then 'custom-B', then 'custom'. If a style/component is in 'custom-A' it will be used. If not, 'custom-B' will be checked and if it's there, that version will be used. If not in either 'custom-A' or 'custom-B', then the style/component from 'custom' will be used. If the style/component is not in ANY of those themes, then the default (base theme) style will be used.
Adding Component Directories to your Theme
If you come across an Angular Component which is NOT in your theme but want to customize it, you can add it into your theme directory. This involves copying the component from the "Custom" theme over into your theme.
You can add/copy over a Component Directory as follows:
- First, copy the Angular Component directory in question from the "Custom" theme folder (src/themes/custom) into your theme's folder. NOTE: at this time, not all components are theme-able. So, if it doesn't exist in the "Custom" theme folder, then it may not be possible to theme.
- For example, if you wanted to add the Footer Component to your theme, it can be found in the "Custom" theme at "src/themes/custom/app/footer".
- Copy that entire folder into your theme folder, retaining the same relative path. For example, to add the Footer Component, copy "src/themes/custom/app/footer" (and all contents) into "src/themes/[your-theme]/app/footer".
Now, you need to "register" that component in one of your theme's module files: lazy-theme.module.ts or eager-theme.module.ts. For performance it's best to put as many components into lazy-theme.module.ts as that means they'll only be downloaded if they're needed. Components in eager-theme.module.ts are included in the initial JS download for the app, so you should only add components there that are necessary on every page, such as the header and footer, these
DECLARATIONS
array. You should also include components using one of our custom decorators (such as @listableObjectComponent), because those decorators need to be registered when the app starts to be able to be picked up. TheseENTRY_COMPONENTS
array, which will both declare them as well as ensure they're loaded when the app starts.Add an import of the new component file, or copy the corresponding import from "src/themes/custom/lazy-theme.module.ts" or "src/themes/custom/eager-theme.module.ts". For example, the Footer Component import can be found in "src/themes/custom/eager-theme.module.ts" and looks like this:
Code Block import { FooterComponent } from './app/footer/footer.component';
In that same module file, also add this imported component to the "DECLARATIONS" section. (Again, you can optionally look in the custom theme's module files to see how its done). For example, the Footer Component would then be added to the list of DECLARATIONS (the order of the declarations list doesn't matter):
Code Block const DECLARATIONS = [ .... FooterComponent, .... ];
- At this point, you should rebuild/restart your UI to ensure nothing has broken. If you did everything correctly, no build errors will occur. Generally speaking, it's best to add Components one by one, rebuilding in between.
- Now, you can customize your newly added Component by following the "Customizing Other Components in your Theme" instructions above.
Removing Component Directories from your Theme
While there is no harm in keeping extra, unmodified component directories in your theme, it can be beneficial to remove component directories which are unchanged.
The main advantage to keeping your theme simple/small is that it can make future upgrades easier. Generally speaking, the fewer components you have in your theme, the less likely your theme will need modification in a future upgrade (as generally your theme may require updates if one of the components it references underwent structural/major changes).
You can remove a Component directory as follows:
- First you MUST remove all references to that directory/component from your theme's
lazy-theme.module.ts
eager-theme.module.ts
.For example, to delete the "./app/login-page" directory, you'd want to find which component(s) use that directory in your
lazy-theme.module.ts
file.If you search that file, you'd fine this reference:
Code Block import { LoginPageComponent } from './app/login-page/login-page.component';
That means you not only need to remove that "import" statement. You'd also need to remove all other references to "LoginPageComponent" in that same
lazy-theme.module.ts
file. So, you'd also need to remove it from the DECLARATIONS section:Code Block const DECLARATIONS = [ .... LoginPageComponent, .... ];
- Finally, delete the directory in question from your theme.
- At this point, you should rebuild/restart your UI to verify nothing has broken. If you did everything correctly, no build errors will occur.
- If you failed to edit your
lazy-theme.module.ts
correctly, you may see "Cannot find module [path-to-module]" errors which reference the directories that Angular/Node can no longer find in your theme. Either restore those directories, or remove the reference(s) from thelazy-theme.module.ts
similar to step 1 above.
- If you failed to edit your
Debugging which theme is being used
While you are working on themes, sometimes you may discover that it's difficult to tell which theme is being used to generate specific HTML elements. Luckily, there's an easy way to determine which theme is used on every HTML element.
Simply view the HTML source of the page, and look for the "data-used-theme" attribute. This attribute will tell you which named theme matched that HTML element. By default, a name of "base" references the core or "base" code ( under ./src/app) was used.
For example:
Code Block | ||||
---|---|---|---|---|
| ||||
<!-- This example shows the theme named "dspace" was used for the "themed-header-navbar-wrapper.component.ts" -->
<ds-themed-header-navbar-wrapper ... data-used-theme="dspace"></ds-themed-header-navabar-wrapper>
<main>
<!-- But, on the same page, the theme named "base" (core code) was used for the "themed-breadcrumbs.component.ts" -->
<ds-themed-breadcrumbs ... data-used-theme="base"></ds-themed-breadcrumbs>
</main> |
Finding which component is generating the content on a page
See "Finding which component is generating the content on a page" in our User Interface Debugging guide.
Additional Theming Resources
- User Interface Debugging - Our guide to debugging basic behaviors in the User Interface
- "Getting Started with DSpace 7.0" Basic Workshop at OR2021 Conference
- Bootstrap Documentation - DSpace's UI strives to be compliant with "out-of-the-box" Bootstrap as much as possible. Therefore, Bootstrap knowledge is very beneficial in customizing DSpace.
- Sass Documentation - Bootstrap and DSpace both use Sass to enhance your ability to customize styles quickly via variables, etc. Some familiarity with Sass is recommended, though you need not be an expert
Enable your theme: Modify your src/environments/environment.*.ts
configuration file, adding your new theme to the "themes" array in that file. Pay close attention to modify the correct file (e.g. modify environment.dev.ts if running in dev mode, or environment.prod.ts if running in prod mode). The "name" used is the name of the theme's folder, so the below example is for enabling a theme at src/themes/mydspacesite/
globally. You should also comment out the default "dspace" theme, if you intend to replace it entirely.
Code Block |
---|
// In this example, we only show one theme enabled. It's possible to enable multiple (see below note)
themes: [
{
name: 'mydspacesite'
},
] |
...
- .