Skip to Content
Technical Articles
Author's profile photo Kevin Hu

Build an English Premier League app with SAP Cloud Application Programming Model – part 2 reuse, localization, annotations

part 1 the story begins

part 2 reuse, localization, annotations

part 3 part 3 build a UI and deploy to Cloud Foundry

part 4 deploy to cloud foundry as multi-target app

 

Once I finished part 1 of the series, I thought that if I want to build a bigger and more complex application with SAP Cloud Application Programming Model, maybe I should take reference of the itelo, product catalog and foundation and reorganize the project code a bit to make it more reusable and less messy before I heading up towards the UI part.

One more thing, we will have a look at how to use the “CodeList” from @sap/cds/common package.

The Plan

I am going to do some restructure of the project files, accrording to the cap development best practices, then experiment a bit on localization. Lastly I will put some annotations to make the preview screen of the matches and teams more beautiful.

Prepare

1. Remember to do an npm update and npm install to bring down the latest cds version and other dependencies.

>cds -v
@sap/cds: 3.18.1
@sap/cds-compiler: 1.19.2
@sap/cds-messaging: 1.2.1
@sap/cds-ql: 1.19.2
@sap/cds-reflect: 2.8.0
@sap/cds-rest: 1.2.0
@sap/cds-services: 1.19.1
@sap/generator-cds: 2.9.0

Get Started

Change on the data model

1. Here is the new db/data-model.cds. I have created a new “type” called “Team”, then I can reuse the type for both “homeTeam” and “awayTeam”. “Teams” entity is reusing the “CodeList” provided by @sap/cds/common package.

namespace com.epl;

using { managed, cuid, sap.common.CodeList } from '@sap/cds/common';

type Team : Association to Teams;

entity Teams : managed, CodeList {
  key ID : Integer @(title : '{i18n>homeTeam}');
}

entity Matches: cuid, managed {
  matchDate: Date;
  homeTeam : Team;
  awayTeam: Team;
  homeTeamScore: Integer;
  awayTeamScore: Integer;
}

No Change on the service catalog

namespace com.epl;

using com.epl as db from '../db/data-model';

service CatalogService {
    @readonly
    entity Teams as projection on db.Teams;
    @readonly 
    entity Matches as select from db.Matches
        order by matchDate desc;
}

Index.cds file

1. Best practice guide mentioned an index.cds on the project root is recommended to modularize cds projects. I created a new index.cds file like this

namespace com.epl;

using from './db/data-model';

using from './srv/cat-service';

using from './srv/Matches-annotations';

using from './srv/Teams-annotations';

2. Note that there are two new annotation files included in here. They will be addressing these files later in the post. In this way, we can include multiple data model files, catalog service files (which I am planning to do in the future posts) and we can easily include/exclude different modules.

3. Make sure this entry is updated in the package.json

  "files": [
    "srv",
    "db",
    "index.cds"
  ],

Annotations

1. I like to seperate annotations based on entities. It will make the project easy to maintain once it is growing bigger.

2. Matches-annotation.cds. See we created some filters with the code list (value help) just by putting annotations.

using com.epl.CatalogService from './cat-service';

annotate CatalogService.Matches with @(
  UI:{
    Identification: [{ Value: '{i18n>matches}' }],
    SelectionFields: [ 'matchDate','homeTeam_ID','awayTeam_ID' ],
    LineItem: [
      { Value: matchDate, Label: '{i18n>matchDate}' },            
      { Value: homeTeam.name, Label: '{i18n>homeTeam}' },  
      { Value: homeTeamScore },
      { Value: ':' },
      { Value: awayTeamScore },
      { Value: awayTeam.name, Label: '{i18n>awayTeam}' }
    ]
  }
){
  matchDate @title:'{i18n>matchDate}';
  homeTeam @(
    Common: {
      Label: '{i18n>homeTeam}',
      ValueList: {
        Label: '{i18n>homeTeam}',
        CollectionPath: 'Teams',
        Parameters:[
	  { $Type:'Common.ValueListParameterInOut', LocalDataProperty: 'homeTeam_ID', ValueListProperty:'ID' },
          { $Type:'Common.ValueListParameterDisplayOnly', ValueListProperty:'name' },
		    ]
      }
    }
  );
  awayTeam @(
    Common: {
      Label: '{i18n>awayTeam}'
    }
  );
};

3. Teams-annotations.cds is coving the annotations for the “Teams” entity. There is an annotation @cds.odata.valuelist which can also be used to “mark” an entity type as codelist (value list, value help or whatever…), if you do not want to borrow it from the out-of-box “sap.common.codelist”.

using com.epl.CatalogService from './cat-service';

annotate CatalogService.Teams with @(
  UI: {
    Identification : [name],
    SelectionFields: [name],
      LineItem: [
	{ Value: ID, Label: '{i18n>ID}' },            
        { Value: name, Label: '{i18n>name}' }
      ]
  }
){
	ID @title:'{i18n>ID}' @UI.HiddenFilter;
	name @title:'{i18n>name}';
}

//annotate CatalogService.Teams with @cds.odata.valuelist;

A Quick Test

1. We do a quick test by

cds deploy && cds watch .

2. Teams preview

3. Matches preview

4. Choose the Home Team or Away Team filter on the top. The Code List popped up.

5. Live update on the filter. Looks pretty good.

Localization

1. create a file _i18n/i18n_zh.properties. Obviously I already created _i18n/i18n.properties file for English (default language).

matches=比赛
matchDate=比赛日期
homeTeam=主队
awayTeam=客队
name=队名

2. Go to the url with the sap-language parameter

http://localhost:4004/$fiori-preview/?service=com.epl.CatalogService&entity=Matches&sap-language=zh_CN

3. Check the results. Awesome!!!

4. What about the team names, I want to display them in Chinese too. Let’s try to load some data into com.epl-Teams_text.csv.

ID,name,locale
1,阿森纳,zh
2,阿斯顿维拉,zh
3,伯恩茅斯,zh
4,布莱顿,zh
.....

5. Unfortunately it does not work. The cause is that cds only creates localized view on de and fr language in sqlite db. A possible bug we found?

6. To prove that I loaded the csv as de (German).

ID,name,locale
1,阿森纳,de
2,阿斯顿维拉,de
3,伯恩茅斯,de
4,布莱顿,de
.....

7. Check the results in

http://localhost:4004/$fiori-preview/?service=com.epl.CatalogService&entity=Teams&sap-language=de_DE

Thanks Walldorf we got it working. 🙂

 

Next Step

I will official dive into the UI part, as I think we have played enough with the fiori preview.

Stay tuned. #epl-app

 

Part2 branch in github.

Assigned Tags

      1 Comment
      You must be Logged on to comment or reply to a post.
      Author's profile photo Volker Buzek
      Volker Buzek

      very cool demo project! specifically like the mandarin localization, nothing more challenging for internationalization features than this 🙂

      how about adding it to https://github.com/sapmentors/cap-community/tree/master/examples?

      you could then even file an issue in the same repo about the "de"- and "fr"-only loading of texts 🙂 the #CAP team monitors the issue space in above repo