Skip to content

EJS & JavaScript

Hapify offers the possibility to write templates with the EJS syntax or in pure JavaScript. Both options are based on the same object described below.

Model object

Templates of type one model receive the model object via the model variable (alias m). In the case of a template of type all models, an array of model objects will be available via the models variable (alias m).

The following block is a JSON representation of this model object for a very simple case. Here, the User profile model has 3 fields including a reference to an entity. To keep this JSON as short as possible, we have removed all aliases, many recurring properties and sub-model details. This JSON is a partial representation of the actual injected model object, but it gives you a good overview of its structure.

See also

If you want to know the complete structure of the model object, you can refer to the model object documentation, or to the TypeScript interface ExplicitModel in the source code of hapify/generator.

{
  "id": "b0993d03-70d1-0448-1eef-25bde4818d15",
  "name": "User profile",
  "names": {
    "raw": "User profile",
    "kebab": "user-profile",
    "snake": "user_profile",
    "header": "User-Profile",
    "constant": "USER_PROFILE",
    "big": "USER-PROFILE",
    "capital": "User Profile",
    "lower": "user profile",
    "upper": "USER PROFILE",
    "compact": "userprofile",
    "pascal": "UserProfile",
    "camel": "userProfile"
  },
  "notes": "The user's details",
  "hasNotes": true,
  "fields": {
    "list": [
      {
        "names": {
          "raw": "_id",
          "kebab": "-id",
          "snake": "_id",
          "header": "-Id",
          "constant": "_ID",
          "big": "-ID",
          "capital": "_Id",
          "lower": "_id",
          "upper": "_ID",
          "compact": "id",
          "pascal": "Id",
          "camel": "id"
        },
        "name": "_id",
        "notes": "",
        "hasNotes": false,
        "type": "string",
        "subtype": null,
        "value": null,
        "primary": true,
        "unique": false,
        "label": false,
        "nullable": false,
        "multiple": false,
        "embedded": false,
        "searchable": false,
        "sortable": false,
        "hidden": false,
        "internal": true,
        "restricted": false,
        "ownership": false
      },
      {
        "names": {
          "raw": "created at",
          "kebab": "created-at",
          "snake": "created_at",
          "header": "Created-At",
          "constant": "CREATED_AT",
          "big": "CREATED-AT",
          "capital": "Created At",
          "lower": "created at",
          "upper": "CREATED AT",
          "compact": "createdat",
          "pascal": "CreatedAt",
          "camel": "createdAt"
        },
        "name": "created at",
        "notes": "",
        "hasNotes": false,
        "type": "datetime",
        "subtype": null,
        "value": null,
        "primary": false,
        "unique": false,
        "label": false,
        "nullable": false,
        "multiple": false,
        "embedded": false,
        "searchable": false,
        "sortable": true,
        "hidden": false,
        "internal": true,
        "restricted": false,
        "ownership": false
      },
      {
        "names": {
          "raw": "avatar",
          "kebab": "avatar",
          "snake": "avatar",
          "header": "Avatar",
          "constant": "AVATAR",
          "big": "AVATAR",
          "capital": "Avatar",
          "lower": "avatar",
          "upper": "AVATAR",
          "compact": "avatar",
          "pascal": "Avatar",
          "camel": "avatar"
        },
        "name": "avatar",
        "notes": "",
        "hasNotes": false,
        "type": "entity",
        "subtype": null,
        "value": "ac046aac-7a20-de65-2209-57e80a2bbea4",
        "primary": false,
        "unique": false,
        "label": false,
        "nullable": false,
        "multiple": false,
        "embedded": false,
        "searchable": false,
        "sortable": false,
        "hidden": false,
        "internal": false,
        "restricted": false,
        "ownership": false,
        "model": "// Avatar model details..."
      },
      {
        "names": {
          "raw": "role",
          "kebab": "role",
          "snake": "role",
          "header": "Role",
          "constant": "ROLE",
          "big": "ROLE",
          "capital": "Role",
          "lower": "role",
          "upper": "ROLE",
          "compact": "role",
          "pascal": "Role",
          "camel": "role"
        },
        "name": "role",
        "notes": "restricted to admins",
        "hasNotes": true,
        "type": "enum",
        "subtype": null,
        "value": ["admin", "user", "customer"],
        "primary": false,
        "unique": false,
        "label": false,
        "nullable": false,
        "multiple": false,
        "embedded": false,
        "searchable": true,
        "sortable": false,
        "hidden": false,
        "internal": false,
        "restricted": false,
        "ownership": false,
        "enum": [
            {
              "name": "admin",
              "names": {
                "raw": "admin",
                "kebab": "admin",
                "snake": "admin",
                "header": "Admin",
                "constant": "ADMIN",
                "big": "ADMIN",
                "capital": "Admin",
                "lower": "admin",
                "upper": "ADMIN",
                "compact": "admin",
                "pascal": "Admin",
                "camel": "admin"
              }
            },
            "// Same structure for each enum"
          ]
        }
    ],
    "primary": "// Primary field details...",
    "unique": ["// unique fields details (if any)..."],
    "label": ["// label fields details (if any)..."],
    "nullable": ["// nullable fields details (if any)..."],
    "multiple": ["// multiple fields details (if any)..."],
    "embedded": ["// embedded fields details (if any)..."],
    "searchable": ["// searchable fields details (if any)..."],
    "sortable": ["// sortable fields details (if any)..."],
    "hidden": ["// hidden fields details (if any)..."],
    "internal": ["// internal fields details (if any)..."],
    "restricted": ["// internal fields details (if any)..."],
    "ownership": ["// ownership fields details (if any)..."],
    "searchableLabel": ["// searchableLabel fields details (if any)..."],
    "references": ["// references fields details (if any)..."]
  },
  "properties": {
    "fieldsCount": 3,
    "hasPrimary": true,
    "hasUnique": false,
    "hasLabel": false,
    "hasNullable": false,
    "hasMultiple": false,
    "hasEmbedded": false,
    "hasSearchable": false,
    "hasSortable": true,
    "hasHidden": false,
    "hasInternal": true,
    "hasRestricted": false,
    "hasOwnership": false,
    "hasSearchableLabel": false,
    "mainlyHidden": false,
    "mainlyInternal": true,
    "isGeolocated": false,
    "isGeoSearchable": false,
    "hasDependencies": true,
    "isReferenced": false
  },
  "accesses": {
    "list": [
      {
        "action": "create",
        "admin": false,
        "owner": false,
        "auth": false,
        "guest": true,
        "gteAdmin": true,
        "gteOwner": true,
        "gteAuth": true,
        "gteGuest": true,
        "lteAdmin": false,
        "lteOwner": false,
        "lteAuth": false,
        "lteGuest": true
      },
      {
        "action": "read",
        "admin": false,
        "owner": false,
        "auth": false,
        "guest": true,
        "gteAdmin": true,
        "gteOwner": true,
        "gteAuth": true,
        "gteGuest": true,
        "lteAdmin": false,
        "lteOwner": false,
        "lteAuth": false,
        "lteGuest": true
      }
    ],
    "properties": {
      "onlyAdmin": false,
      "onlyOwner": false,
      "onlyAuth": false,
      "onlyGuest": true,
      "maxAdmin": false,
      "maxOwner": false,
      "maxAuth": false,
      "maxGuest": true,
      "noAdmin": true,
      "noOwner": true,
      "noAuth": true,
      "noGuest": false,
      "hasAdmin": false,
      "hasOwner": false,
      "hasAuth": false,
      "hasGuest": true
    },
    "admin": [],
    "owner": [],
    "auth": [],
    "guest": [
      {
        "action": "create",
        "admin": false,
        "owner": false,
        "auth": false,
        "guest": true,
        "gteAdmin": true,
        "gteOwner": true,
        "gteAuth": true,
        "gteGuest": true,
        "lteAdmin": false,
        "lteOwner": false,
        "lteAuth": false,
        "lteGuest": true
      }
    ],
    "create": {
      "action": "create",
      "admin": false,
      "owner": false,
      "auth": false,
      "guest": true,
      "gteAdmin": true,
      "gteOwner": true,
      "gteAuth": true,
      "gteGuest": true,
      "lteAdmin": false,
      "lteOwner": false,
      "lteAuth": false,
      "lteGuest": true
    },
    "read": "// Same structure as create",
    "update": "// Same structure as create",
    "remove": "// Same structure as create",
    "search": "// Same structure as create",
    "count": "// Same structure as create"
  },
  "dependencies": {
    "list": ["// Avatar model details..."],
    "self": false
  },
  "referencedIn": ["// Referring models come here, populated with entity fields only."]
}

Templating

Here are examples of EJS and JavaScript templates using this model object.

Template of type `one model

class <%= model.names.pascal %> {
    private primaryKey = '<%= model.fields.primary.names.snake %>';
}
return `class ${model.names.pascal} {
    private primaryKey = '${model.fields.primary.names.snake}';
}`;
class Place {
    private primaryKey = '_id';
}

Warning

A JavaScript template must return a string.

Tip

Empty generated files will not be saved.

Template of type all models

<% for (let model of models) { -%>
require_once('./<%= model.names.kebab %>.php');
<% } -%>
let output = '';
for (let model of models) {
    output += `require_once('./${model.names.kebab}.php');\n`;
}
return output;
require_once('./user.php');
require_once('./place.php');
require_once('./service.php');
require_once('./place-category.php');

See also

For more examples, please read this article.