|
| 1 | +# Make it your own |
| 2 | + |
| 3 | +You can configure and customize your InvenioRDM instance to best suit your needs. |
| 4 | +From changing the style and look, to extending the data model and defining your |
| 5 | +own permissions, InvenioRDM provides you with much control. And if none of this |
| 6 | +is enough, extensions can also be created to add functionality. |
| 7 | + |
| 8 | +Adapting your instance to your needs is done by editing the `invenio.cfg` file |
| 9 | +appropriately and adding files to the local folders invenio-cli created for |
| 10 | +you (e.g. `app_data/`, `assets/`, `static/`, `templates/`). The configuration file |
| 11 | +`invenio.cfg` overrides the `config.py` variables provided by |
| 12 | +[Invenio modules](https://invenio.readthedocs.io/en/latest/general/bundles.html) |
| 13 | +and their dependencies. Conveniently, this means that if you name your files by |
| 14 | +the name used in the configurations for them, you won't even need to edit `invenio.cfg`! |
| 15 | + |
| 16 | +No worries, we go through *all* of the common customizations below. |
| 17 | + |
| 18 | +## Change the logo |
| 19 | + |
| 20 | +Having your instance represent your institution starts with using your |
| 21 | +institution's logo. We are going to change InvenioRDM's default logo to your logo. |
| 22 | + |
| 23 | +Take an *svg* file and copy it to your **local** static files. |
| 24 | +We'll use the [invenio color logo](https://github.com/inveniosoftware/invenio-theme/raw/master/invenio_theme/static/images/invenio-color.svg) as an example: |
| 25 | + |
| 26 | +``` bash |
| 27 | +cp ./path/to/new/color/logo.svg static/images/logo.svg |
| 28 | +``` |
| 29 | + |
| 30 | +Then, use the `update` command: |
| 31 | + |
| 32 | +``` bash |
| 33 | +invenio-cli update --no-install-js |
| 34 | +``` |
| 35 | +``` console |
| 36 | +# Summarized output |
| 37 | +Collecting statics and assets... |
| 38 | +Collect static from blueprints. |
| 39 | +Created webpack project. |
| 40 | +Copying project statics and assets... |
| 41 | +Symlinking assets/... |
| 42 | +Building assets... |
| 43 | +Built webpack project. |
| 44 | +``` |
| 45 | + |
| 46 | +Passing the `--no-install-js` option, skips re-installation of JS dependencies. |
| 47 | + |
| 48 | +!!! info "Assets and statics need to be updated" |
| 49 | + Whenever you change files in `assets/` or `static/`, you typically want to run `invenio-cli update --no-install-js`. In case of uncertainty, just run the `update` command; it isn't destructive. |
| 50 | + |
| 51 | +Go to the browser [*https://localhost:5000/*](https://localhost:5000) or refresh the page. And voilà! The logo has been changed! |
| 52 | + |
| 53 | +!!! warning "That evil cache" |
| 54 | + If you do not see it changing, check in an incognito window; the browser might have cached the logo. |
| 55 | + |
| 56 | +If your logo isn't an svg, you still copy it to `static/images/`, but you need to edit the `invenio.cfg` file appropriately: |
| 57 | + |
| 58 | +```diff |
| 59 | +- THEME_LOGO="images/logo.svg" |
| 60 | ++ THEME_LOGO="images/my-logo.png" |
| 61 | +``` |
| 62 | + |
| 63 | +You also need to run `update` as above and additionally restart the server: |
| 64 | + |
| 65 | +```bash |
| 66 | +^C |
| 67 | +Stopping server and worker... |
| 68 | +Server and worker stopped... |
| 69 | +``` |
| 70 | +```bash |
| 71 | +invenio-cli update --no-install-js |
| 72 | +invenio-cli run |
| 73 | +``` |
| 74 | + |
| 75 | +!!! info "Re-run when invenio.cfg changes" |
| 76 | + All changes to `invenio.cfg` **MUST** be accompanied by a restart like the above to be picked up. This only restarts the server; it does not destroy any data. |
| 77 | + |
| 78 | +All other changes below follow the same pattern: add files and/or edit `invenio.cfg` and |
| 79 | +potentially execute `update` and/or rerun the server. |
| 80 | + |
| 81 | + |
| 82 | +## Change colors |
| 83 | + |
| 84 | +You might also be wondering: *How do I change the colors so I can make my instance look like my institution's theme?* |
| 85 | + |
| 86 | +We are going to change the top header section in the frontpage to apply our custom background color. Open the `assets/scss/<your instance shortname>/variables.scss` file and edit it as below: |
| 87 | + |
| 88 | +``` scss |
| 89 | +$navbar_background_image: unset; |
| 90 | +$navbar_background_color: #000000; // Note this hex value is an example. Choose yours. |
| 91 | +``` |
| 92 | + |
| 93 | +Then, run the `invenio-cli update` command as above and refresh the page! You should be able to see your top header's color changed! You can find all the available styling variables that you can change [here](https://github.com/inveniosoftware/invenio-app-rdm/blob/master/invenio_app_rdm/theme/assets/scss/invenio_app_rdm/variables.scss). |
| 94 | + |
| 95 | + |
| 96 | +## Change search results |
| 97 | + |
| 98 | +Changing how your results are presented in the search page is also something quite common. |
| 99 | + |
| 100 | +We are going to update the search result template so we can show more text in the result's description. Create a file called `ResultsItemTemplate.jsx` inside `assets/templates/search` folder and then edit it as below: |
| 101 | + |
| 102 | +```js |
| 103 | +import React from 'react'; |
| 104 | +import {Item} from 'semantic-ui-react'; |
| 105 | +import _truncate from 'lodash/truncate'; |
| 106 | + |
| 107 | +export function ResultsItemTemplate(record, index) { |
| 108 | + return ( |
| 109 | + <Item key={index} href={`/records/${record.id}`}> |
| 110 | + <Item.Content> |
| 111 | + <Item.Header>{record.metadata.titles[0].title}</Item.Header> |
| 112 | + <Item.Description> |
| 113 | + {_truncate(record.metadata.descriptions[0].description, { length: 400 })} |
| 114 | + </Item.Description> |
| 115 | + </Item.Content> |
| 116 | + </Item> |
| 117 | + ) |
| 118 | +}; |
| 119 | +``` |
| 120 | + |
| 121 | +Then, run the `invenio-cli update` command as above and refresh the page! You should be able to see more text in each result's description! You can find all the available templates [here](https://github.com/inveniosoftware/invenio-app-rdm/tree/master/invenio_app_rdm/theme/assets/templates/search). |
| 122 | + |
| 123 | + |
| 124 | +## Change the record landing page |
| 125 | + |
| 126 | +When you click on a search result, you navigate in the details page of a specific record. This section shows you how to change the way the information is displayed in the details page. |
| 127 | + |
| 128 | +We are going to configure our instance to use our template for displaying the information in the record's landing page. Open the `invenio.cfg` file and add the below: |
| 129 | + |
| 130 | +```python |
| 131 | +from invenio_rdm_records.config import RECORDS_UI_ENDPOINTS |
| 132 | +RECORDS_UI_ENDPOINTS['recid'].update(template='my_record_landing_page.html') |
| 133 | +``` |
| 134 | + |
| 135 | +You will note that `invenio.cfg` is really just a Python module. How convenient! |
| 136 | + |
| 137 | +Then, we create a file `my_record_landing_page.html` inside the `templates` folder and edit it as below: |
| 138 | + |
| 139 | +```jinja |
| 140 | +{%- extends 'invenio_rdm_records/record_landing_page.html' %} |
| 141 | +
|
| 142 | +{%- block page_body %} |
| 143 | +<!-- // Paste your code here --> |
| 144 | +{%- endblock page_body %} |
| 145 | +``` |
| 146 | + |
| 147 | +Inside the `page_body` block you can restructure the page as you want! You can check the default record landing page template [here](https://github.com/inveniosoftware/invenio-rdm-records/blob/master/invenio_rdm_records/theme/templates/invenio_rdm_records/record_landing_page.html). |
| 148 | + |
| 149 | +Since we modified `invenio.cfg`, we need to re-start the server to see our changes take effect. |
| 150 | + |
| 151 | + |
| 152 | +## Use a custom controlled vocabulary |
| 153 | + |
| 154 | + |
| 155 | +## Extend the metadata |
| 156 | + |
| 157 | + |
| 158 | +## Change permissions |
| 159 | + |
| 160 | +For the purpose of this example, we will only allow super users to create |
| 161 | +records through the REST API. To do so, we define our own permission policy. |
| 162 | + |
| 163 | +Open the `invenio.cfg` in your favorite text editor (or least favorite if you |
| 164 | +like to suffer) and add the following to the file: |
| 165 | + |
| 166 | +```python |
| 167 | +# imports at the top... |
| 168 | +from invenio_rdm_records.permissions import RDMRecordPermissionPolicy |
| 169 | +from invenio_records_permissions.generators import SuperUser |
| 170 | + |
| 171 | +# ... |
| 172 | + |
| 173 | +# At the bottom |
| 174 | +# Our custom Permission Policy |
| 175 | +class MyRecordPermissionPolicy(RDMRecordPermissionPolicy): |
| 176 | + can_create = [SuperUser()] |
| 177 | + |
| 178 | +RECORDS_PERMISSIONS_RECORD_POLICY = MyRecordPermissionPolicy |
| 179 | +``` |
| 180 | + |
| 181 | +and re-start the server. |
| 182 | + |
| 183 | +When we set `RECORDS_PERMISSIONS_RECORD_POLICY = MyRecordPermissionPolicy`, |
| 184 | +we are overriding `RECORDS_PERMISSIONS_RECORD_POLICY` provided by |
| 185 | +[invenio-records-permissions](https://github.com/inveniosoftware/invenio-records-permissions). |
| 186 | + |
| 187 | +!!! info "Pro tip" |
| 188 | + You can type `can_create = []` to achieve the same effect; any empty permission list only allows super users. |
| 189 | + |
| 190 | +That's it configuration-wise. If we try to create a record through the API, |
| 191 | +your instance will check if you are a super user before allowing you. |
| 192 | + |
| 193 | +Did the changes work? We are going to try to create a new record: |
| 194 | + |
| 195 | +``` bash |
| 196 | +curl -k -XPOST -H "Content-Type: application/json" https://localhost:5000/api/records/ -d '{ |
| 197 | + "_access": { |
| 198 | + "metadata_restricted": false, |
| 199 | + "files_restricted": false |
| 200 | + }, |
| 201 | + "_owners": [1], |
| 202 | + "_created_by": 1, |
| 203 | + "access_right": "open", |
| 204 | + "resource_type": { |
| 205 | + "type": "image", |
| 206 | + "subtype": "image-photo" |
| 207 | + }, |
| 208 | + "identifiers": { |
| 209 | + "DOI": "10.9999/rdm.0", |
| 210 | + }, |
| 211 | + "creators": [ |
| 212 | + { |
| 213 | + "name": "Marcus Junius Brutus", |
| 214 | + "type": "Personal", |
| 215 | + "given_name": "Marcus", |
| 216 | + "family_name": "Brutus", |
| 217 | + "identifiers": { |
| 218 | + "Orcid": "9999-9999-9999-9990" |
| 219 | + }, |
| 220 | + "affiliations": [ |
| 221 | + { |
| 222 | + "name": "Entity One", |
| 223 | + "identifier": "entity-one", |
| 224 | + "scheme": "entity-id-scheme" |
| 225 | + } |
| 226 | + ] |
| 227 | + } |
| 228 | + ], |
| 229 | + "titles": [ |
| 230 | + { |
| 231 | + "title": "A permission story", |
| 232 | + "type": "Other", |
| 233 | + "lang": "eng" |
| 234 | + } |
| 235 | + ], |
| 236 | + "descriptions": [ |
| 237 | + { |
| 238 | + "description": "A story about how permissions work.", |
| 239 | + "type": "Abstract", |
| 240 | + "lang": "eng" |
| 241 | + } |
| 242 | + ], |
| 243 | + "community": { |
| 244 | + "primary": "Maincom", |
| 245 | + "secondary": ["Subcom One", "Subcom Two"] |
| 246 | + }, |
| 247 | + "licenses": [ |
| 248 | + { |
| 249 | + "license": "Berkeley Software Distribution 3", |
| 250 | + "uri": "https://opensource.org/licenses/BSD-3-Clause", |
| 251 | + "identifier": "BSD-3", |
| 252 | + "scheme": "BSD-3" |
| 253 | + } |
| 254 | + ] |
| 255 | +}' |
| 256 | +``` |
| 257 | + |
| 258 | +As you can see, the server could not know if we are authenticated/superuser and rejected us: |
| 259 | + |
| 260 | +``` json |
| 261 | +{ |
| 262 | + "message": "The server could not verify that you are authorized to access the URL requested. You either supplied the wrong credentials (e.g. a bad password), or your browser doesn't understand how to supply the credentials required.", |
| 263 | + "status": 401 |
| 264 | +} |
| 265 | +``` |
| 266 | + |
| 267 | +Let's create a user with the right permission, generate her token and use the API |
| 268 | +with it. |
| 269 | + |
| 270 | +``` bash |
| 271 | +pipenv run invenio users create [email protected] --password=123456 --active |
| 272 | +``` |
| 273 | + |
| 274 | +``` bash |
| 275 | +pipenv run invenio roles add [email protected] admin |
| 276 | +``` |
| 277 | + |
| 278 | +Login through the browser as `[email protected]` with password `123456`. Then |
| 279 | +in the dropdown menu of the username (top-right), select `Applications`. Then |
| 280 | +click on `New token`, name your token and click `Create`. Copy this token (we |
| 281 | +will refer to it as `<your token>`) and put it in the API call as such: |
| 282 | + |
| 283 | +``` bash |
| 284 | +curl -k -XPOST -H "Authorization:Bearer <your token>" -H "Content-Type: application/json" https://localhost:5000/api/records/ -d '{ |
| 285 | + ...<fill with the above>... |
| 286 | +}' |
| 287 | +``` |
| 288 | + |
| 289 | +And it works! That's because InvenioRDM creates an `admin` role with super user |
| 290 | +access permissions when initially setting up the database. Above, we set |
| 291 | +`[email protected]` to be an admin, so that user can create records. |
| 292 | + |
| 293 | +Revert the changes in `invenio.cfg` and restart the server to get back to where |
| 294 | +we were. |
| 295 | + |
| 296 | + |
| 297 | +## Add functionality |
| 298 | + |
| 299 | +Need further customizations or additional features? Have you thought of |
| 300 | +creating your own extensions? |
| 301 | + |
| 302 | +How to make an extension and add it to your InvenioRDM instance is explained in |
| 303 | +the [Extensions section](../extensions/custom.md). |
0 commit comments