First use
npm install
to install all the dependencies.
If you want to generate the production build, run:
npm run build
If instead you want to start an express server that simulates the client-only environment with hot reloading, run:
npm run dev
The web-app is written to be flexible to the content provided by the server. To let this application know which catalogue to load, start by rendering index.html
with a template variable named dunya_catalogue
, whose value must be in [carnatic, hindustani]
(although it's possible to extend these values, see section Customization/Adding new content).
All settings in the following paragraphs are stored in the file src/settings.js
. If you change one, please rebuild the bundle with the command npm run build
.
At initial mount, the app requests data from the server to fill up the sidebar with filters. The address for this request is the value of the setting FILTERS_DATA_URL[$dunya_catalogue]
, where $dunya_catalogue
is the content of the template variable dunya_catalogue
passed to index.html
(as explained in previous section). The response of the server at this address must be an object, whose values are arrays of entries for the corresponding key. An example:
{
"artists": [
{
"id": "a1",
"name": "artist 1",
"instruments": ["i1", "i2"]
}, {
"id": "a2",
"name": "artist 2",
"instruments": []
}, // ...other artists
],
"concerts": [
{
"id": "c1",
"name": "concert 1",
"aliases": ["that concert"]
}, {
"id": "c2",
"name": "concert 2"
}, // ...other concerts
],
"instruments": [
{
"uuid": "i1",
"name": "Violin"
}, {
"uuid": "i2",
"name": "Cello"
}, // ...other instruments
], // ...other keys
}
The key artists
in the response is mandatory. There are no other rules for the names and/or amount of the response keys. Each key of the response will be a section of filters in the sidebar.
Each entry of each field (the fields in this example are artists, concerts, instruments
) must have a name
property.
Each entry must as well contain an id field, but this is not required to be named id
; edit the setting ID_KEYS
to list all the possible keys for the id field and the app will automatically detect which entry key corresponds to the entry id. If an entry of a specific field has a key that is a reference to the ids of another field (in the example, the first entry of artists
has a reference to instruments
, i.e. it contains the list of instruments played by that artist), that reference will be used for advanced content filtering. In this case, if the user selected the instrument 'Violin', only "artist 1" would appear in the artists
section as he's the only one playing the violin. On the other hand, the content of the concerts
field wouldn't be affected as its entries don't have a reference to the instruments
fields.
If an entry has an aliases
field, the values on that field will be used during the search.
You might want to send data for autocomplete when the user is typing in the search bar. In this case, start by setting the proper address in AUTOCOMPLETE_URL[$dunya_catalogue]
. This address should then read the parameter query
from the incoming request and reply to it with a list of results, in the following shape:
[
{
"mbid": "8618ff0c-555e-4f3c-90d5-0438aeae4659",
"title": "Balagopala"
}, {
"mbid": "33ef2098-d4ba-40ec-b972-dbda5114e3e2",
"title": "Koovi Azhaithal"
}, ... other results
]
Each result must have the title
property.
If you don't want to enable autocomplete, just don't set the option AUTOCOMPLETE_URL[$dunya_catalogue]
(or put it to undefined
).
The client will send a request with the following two parameters:
{
"query": (str) // the query manually typed from the user (i.e. a searched recording)
"selectedData": {
"artists": ["a1"], // the ids of the artists selected by the user
"concerts": [], // empty array if the user didn't select anything in this category
}
}
The keys of selectedData
will equal the keys of the response sent by the server for the filters.
The server answers this request with a response that is a list of object, each one storing the details of a recording the matches the search. Each result should then have the following keys: concert
, image
, linkToRecording
, mainArtists
, name
.
The following one is an example of a correct response:
[
{
"collaborators": [ // list of collaborators (this key can be omitted if no collaborators are available)
{
"name": "artist 1", // name of the first collaborator
"instrument": "voice" // and the instrument he/she plays in this recording
}, ... // other collaborators
],
"concert": "concert 1", // the concert name
"image": "/static/image.png",
"linkToRecording": "/recording/1.html", // link to the recording page
"mainArtists": ["artist 1", "artist 2"], // the names of the main artists of the recording
"name": "recording 1", // the name of the recording
"taala": "aadi", // optional
... // other optional keys (such as "raaga", "form",... No fixed key names here, use what you want!)
}, ...// other search results, with the same shape
]
The client makes no assumption on the keys other than concert
, image
, linkToRecording
, mainArtists
, name
and collaborators
. If the response contain any other key, the value for that key will be displayed in the final UI. This means that the UI will correctly work with non-carnatic results without any change in the code.
In case of extending the application to support a new catalogue, the settings for the new catalogue have to be added in:
FILTERS_DATA_URL
SEARCH_URL
AUTOCOMPLETE_URL
SELF_EXPLANATORY_CATEGORY_ITEMS
might as well be extended in order to include new response keys that don't need an explanation on the search bar. In the same way, you might need to add new items to the list ID_KEYS
.
MIT