# Theming
You can override pretty much all the HTML generated by ng-admin, at different levels.
## Stylesheet
Ng-admin CSS is composed of styles from [sb-admin](http://ironsummitmedia.github.io/startbootstrap-sb-admin-2/), on top of [Bootstrap 3](http://getbootstrap.com/). By using your own CSS in addition to the ng-admin CSS, you can customize the look and feel of every displayed component.
To ease styling, ng-admin adds custom classes for the entities and fields currently displayed, to allow a finer styling. For instance, the datagrid in the list view always uses a class named `ng-admin-entity-[entityName]`. In the datagrid also, each header in the table uses a class named `ng-admin-column-[fieldName]`, which should allow precise sizing of columns.
Don't hesitate to inspect the generated source to look for the right CSS selector.
## Custom Classes
To ease theming, you can add a custom class to your fields in every view, using the `cssClasses()` method.
```js
myEntity.listView().fields([
nga.field('title').cssClasses(['foo', 'bar'])
]);
```
`cssClasses()` can optionally accept a function, to return a class depending on the current entry.
```js
myEntity.listView().fields([
nga.field('title').cssClasses(function(entry) {
if (entry && entry.values && entry.values.publishDate >= Date.now()) {
return 'bg-success';
}
})
]);
```
The `listView` calls `cssClasses()` for each datagrid cell, and for the datagrid headers. There is no active 'entry' in headers, that's why you should always check that the `entry` parameter is defined in a `cssClasses` function.
## Customizing The Template For A Given Field
All field types support the `template()` method, which makes it easy to customize the look and feel of a particular field, without sacrificing the native features.
For instance, if you want to customize the appearance of a `NumberField` according to its value:
```js
listview.fields([
nga.field('amount', 'number')
.format('$0,000.00')
.template('')
]);
```
The template scope exposes the following variables:
* `value`, `field`, `entry`, `entity`, and `datastore` in `listView` and `showView`
* `value`, `field`, `values`, and `datastore` in filters
* `value`, `field`, `entry`, `entity`, `form`, and `datastore` in `editionView` and `creationView`
In `showView`, `editionView`, and `creationView`, the template zone covers only the field itself - not the label. To force the template to replace the entire line (including the label), pass `true` as second argument to the `template()` call. This can be very useful to conditionally hide a field according to a property of the entry:
```js
post.editionView()
.fields([
nga.field('category', 'choice')
.choices([
{ label: 'Tech', value: 'tech' },
{ label: 'Lifestyle', value: 'lifestyle' }
]),
nga.field('subcategory', 'choice')
.choices(function(entry) {
return subCategories.filter(function (c) {
return c.category === entry.values.category;
});
})
// display subcategory only if there is a category
.template('', true),
]);
```
Most of the time, `template()` is used to customize the existing ng-admin directives (like `ma-number-column>` in the previous example), for instance by decorating them. If you want to learn about these native directives, explore the [column](../src/javascripts/ng-admin/crud/column), [field](../src/javascripts/ng-admin/crud/field), and [fieldView](../src/javascripts/ng-admin/crud/fieldView) directories in ng-admin source.
## Customizing Directives Templates
Using Angular's [`$provide`](https://docs.angularjs.org/api/auto/service/$provide) service, and the ability to decorate another provider, you can customize the template of any directive used by ng-admin for your entire application. Here is an example of customization of the 'text' input field:
```js
var myApp = angular.module('myApp', ['ng-admin']);
myApp.config(function(NgAdminConfigurationProvider, $provide) {
// Override textarea template
$provide.decorator('maTextFieldDirective', ['$delegate', function ($delegate) {
// You can modify directly the template
$delegate[0].template = angular.element($delegate[0].template).addClass('MyClass')[0].outerHTML;
// or use a templateURL (loaded from a file or a tag)
$delegate[0].template = '';
$delegate[0].templateUrl = 'string.html';
return $delegate;
}]);
// ...
});
```
## Customizing The View Template For A Given Entity
For a given entity, each of the main views (`list`, `show`, `create`, `edit`, `delete`) can use a custom HTML template instead of the default one. Just pass it to the `template()` function on the view:
```js
var myTemplate = require('text!./path/to/list.html');
var myEntity = nga.entity('foo_endpoint');
myEntity.listView().template(myTemplate);
// continue myEntity configuration
// ...
var admin = nga.application('My Application');
admin.addEntity(myEntity);
```
## Customizing The View Templates For The Entire Application
You can use the `app.customTemplate()` method to customize the template of a given view across the entire application (for all entities). This method expects a function argument, which should return the template as a string.
```js
var myTemplate = require('text!./path/to/list.html');
var admin = nga.application('My Application');
admin.customTemplate(function(viewName) {
if (viewName === 'ListView') {
return myTemplate;
}
})
```
## Customizing the Dashboard
If you want to use a custom template dashboard, you must [define a custom dashboard configuration](Dashboard.md). This will give you access to the `dashboard.template()` function:
```js
var myTemplate = require('text!./path/to/dashboard.html');
var admin = nga.application('My Application');
admin.dashboard(nga.dashboard()
.template(mytemplate)
})
```
## Customizing the Application Header
If you want to override the application header (for instance to add authentication status on the top bar), use the `admin.header()` setter with a valid HTML content. Angular directives are executed in the context of the layout. For instance, to display a custom title and a right aligned link, use the following code:
```js
var customHeaderTemplate =
'
' +
'' +
'' +
' View Source' +
'' +
'
';
var admin = nga.application('My Application');
admin.header(customHeaderTemplate);
```
## Customizing the Application Layout
If the header is not enough, and you need to override the entire application layout use the `admin.layout()` setter:
```js
var myLayout = require('text!./path/to/layout.html');
var admin = nga.application('My Application');
admin.layout(myLayout);
```
The original layout can be found in [src/javascripts/ng-admin/Main/view/layout.html](../src/javascripts/ng-admin/Main/view/layout.html).
## Customizing Error Messages
You can use the `app.errorMessage()`, `entity.errorMessage()` or `view.errorMessage()` methods to customize the message displayed when an error occurred with the API. These methods expect a function argument with the response as parameter, which should return the message as a string.
```js
entity.errorMessage(function (response) {
return 'Global error: ' + response.status + '(' + response.data + ')';
});
```
## Customizing HTTP Error Messages
If you want to override, patch or extend the way HTTP errors are handled by the ng-admin [Http Error Service](../src/javascripts/ng-admin/Main/component/provider/HttpErrorService.js) then you may use an [Angular decorator](https://docs.angularjs.org/guide/decorators), as per the below example:
Create a decorator, HttpErrorDecorator.js
```js
// Change HTTP 403 error notification to display them as information
// and not errors ('humane-flatty-info' instead of 'humane-flatty-error')
export const HttpErrorDecorator = ($delegate, $translate, notification) => {
$delegate.handle403Error = error => {
$translate('STATE_FORBIDDEN_ERROR', {
message: error.data.message,
}).then(text => notification.log(text, {
addnCls: 'humane-flatty-info',
}));
throw error;
};
return $delegate;
}
HttpErrorDecorator.$inject = ['$delegate', '$translate', 'notification'];
export default HttpErrorDecorator;
```
Bind the decorator to your application:
```js
myApp.decorator('HttpErrorService',require('HttpErrorDecorator'));
```