Memri / CVU Language / Introduction to CVU

Introduction to CVU

The CVU language (c-view or Cascading Views) is an easy to use language that combines capabilities of HTML and CSS. It is the language we’ve chosen for defining the views in the Memri app. You can think of it as a language that forms the window through which you can see your personal data (stored in your pod).

Check out the CVU Language Reference


CVU Basics

Expression Language

Here goes a general explanation of the expression language. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Selectors

Like in CSS, selectors allow you to apply styling to specific UI elements, but also rendering instructions. You can also nest selectors for more complex structures.

In CVU we use selectors to define everything, starting with the UI structure (session > view > renderer), the styling sets (color, stye), actions and even variables to be referenced in UI elements (e.g. language). Check out the complete list of supported definitions.

/* A session with a note view */
[session = all-notes] {
    /* A notes view */
    [view] {
        title: "All Notes"
        [datasource = pod] {
            query: "Note"
        }
        defaultRenderer: list
        /* A list renderer */
        [renderer = list] {
            ...
        }
    }
}

The Memri app is basically a data-browser that allows you to sort, search and navigate through your data, as well as interacting with it. If compared to a web browser, like browser-tabs it has sessions, and like web pages it has views.

By defining different views you can describe how you want to view and interact with your data.

/* A view showing multiple notes */
Note[] {
    title: "Notes view"
    [datasource = pod] {
        query: "Note"
    }
    defaultRenderer: list
    [renderer = list] {
        ...
    }
}

/* A view showing a single note */
Note {
    ...
}

Use a selector based on a list of the common types:

Note[] Person[] Message[] Label[]

Use *[] to apply to a list of any datatypes

Use mixed[] to apply to a list of mixed datatypes

/* color set */
[color = "background"] {
    light: #330000
    dark: #ff0000
}
/* color set */
[color = "highlight"] {
    light: #000
    dark: #fff
}
/* style set */
[style = "my-label-text"] {
    border: background 1
    color: highlight
}

/* Example usage */
Text {
    style: my-label-text
}
Text {
    color: highlight
}
Colors can be defined using a color selector and can then be applied to UI elements. Literal colors in views are highly discouraged. Users of views can override named colors in their settings, which they cannot do for literal colors.


[language = "English"] {
    sharewith: "Share with..."
    addtolist: "Add to list..."
    duplicate: "Duplicate"
    showtimeline: "Show Timeline"
    timelineof: "Timeline of this"
    starred: "Starred"
    all: "All"
}

/* Example usage */
Text {
    text: "$sharewith"
}
Language selectors are used to specify text used in views in various natural languages, by replacing the text with variables.

Separators

The CVU language is very forgiving. It it is compatible with JSON, however as a user you can leave out quotes, commas, brackets ([ and ]), and even colons (:) when defining objects. Newlines, commas, or semi-colons (;) can be used to separate statements from each other.

UI Elements

Inside a view you can use the predefined UI elements and customize them to your needs. Check out the complete list of UI elements.


An example of a Notes view using VStack:

Note[] {
/* Sets the list as the default 
renderer when viewing notes*/
defaultRenderer: list
/* Customizing the list renderer */
[renderer = list] {
    /* An element that stacks its 
    children vertically */
    VStack {
        alignment: left
        padding: 12 20 0 20
        Text {
            text: "{.title}"
            font: 18 semibold
            color: #333
            padding: 0 0 3 0
        }
        Divider
                ...
    }
}

Some of the most common UI elements:

Name Description
VStack Element that stacks its children vertically
HStack Element that stacks its children horizontally
ZStack Element that stacks its children on top of eachother
SubView Element that renders a view inside another view
FlowStack Element that horizontally stacks its children and wraps to the next line at the end of the container.
Button Element that renders a button in the user interface. Buttons connect to
Text Element that renders text on the screen
Textfield Element allows a user to change text

Properties

Something about properties. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Check out the complete list of UI elements and properties.

Actions

Remember CVU is not just for defining the looks, but also for interaction. It is possible to create a complete application by connecting different CVU views to each other. The CVU Editor is a great way to build small functionality in no time. Check out the complete list of supported actions.


actionButton:
    addDataItem {
        icon: "text.badge.plus"

        arguments {
            template {
                type: Note
                title: "Untitled Note"
            }
        }
    }

In this example, the names used for actionButton and filterButtons refer to pre-defined actions. Actions can optionally take arguments in order to control their behavior.

Note that all arguments are named. In this case the argument name template is used to define the properties of the default note. The type property points to the type of the element that is added.


Check out the schema explorer for a full list of all supported types and properties. We are actively growing this list and will accept all quality contributions.




Cascading Views

Cascading is a method well known from cascading style sheets (CSS), which is used in modern web browsers to describe how HTML is rendered when a website is displayed.

The word cascade describes the process of applying various view definitions one after the other in such a way that the resulting view contains the definitions of each view it cascaded from. During this process, values that are defined by multiple views are either merged or overridden by the view with the highest priority.

Layers

The user defined views always have the highest priority.

The values defined in a user view will override the values defined in other views. And all values not defined by the user will be loaded from lower priority views. This gives the user control to override what they need without having to start creating views from scratch.

/* A view for multiples notes */
Note[] {
    title: "All Notes"
    emptyResultText: "No notes here yet"
    defaultRenderer: list
    [renderer = list] {
		    ...
    }
}

Based on the query and its result, the Memri client app will determine what data type is being displayed and search for additional views to load. The selector views (based on a list of the same types) that are a match will be incorporated. If you’re working on a notes view, Note[] selector will be found.

Usually the values of selector views are used as a basis for the values in the higher priority views. The values of a session view override any values of the selector views, and the values in the user views will override both.

In the future the CVU language will also support more specific selectors such as Note[location = USA]

[session = all-notes] {
    [view] {
        title: "All Notes"
        [datasource = pod] {
            query: "Note"
        }
    }
}

When you navigate in the Memri app you either go back to a previous view in your browsing session, or you add a new view to the session. For instance by clicking on a button to load all notes.

Such a view definition is going to override the values of any selector views, but can be overridden by values defined in user views.

[renderer = list] {
    slideLeftActions: delete
    press: openView
    longPress: select
}
We can define how to render our data in various renderers (list, thumbnails, map, etc). A definition for a renderer outside of a view defines the default values for that renderer. These values are used when other values are not specified in any other view.
[renderer = list] {
    slideRightActions: schedule markAsDone
}
As mentioned above, the user is able to override any values set by the default views in their own view definitions. User defined views always have priority for any property it sets. For instance the following user defined renderer will override the above renderer definition. It determines that the slide right actions always include both the schedule and markAsDone actions.
The result is a cascaded view that has a combination of all properties of the views that cascaded into it. This view is then used to display data by the Memri browser.



Anatomy of a CVU definition

Anatomy of a view

All views in the Memri Browser have 3 main sections:

  • A navigation bar at the top with several buttons
  • A search bar in the bottom with another set of buttons.
  • A data renderer: the main area where your data is displayed.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3f60c254-3e8a-4431-a59a-ea86c219024f/Untitled.png

Anatomy of a CVU definition

To create a view you need to:

  • Configure the UI by defining the view attributes.
  • Define the data source.
  • Configure the action buttons.
  • Configure the renderer(s) where the data is going to be displayed.

Read the CVU language guide to learn more.

Read our guide on Creating a CVU definition.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/2702bc1a-31f2-4d8b-bc8b-80eabe2ea308/Untitled.png

Define the Data Type

  • Use a selector based on a list of the common types:

    Note[] Person[] Message[] Label[]

  • Use *[] to apply to a list of any datatypes

  • Use mixed[] to apply to a list of mixed datatypes

Define the data source

Custom sets

You can define custom sets that can then be applied to UI elements:

[datasource = pod]

[renderer = type]

Similarly styles can be combined into named sets that can then be applied to UI elements.

Language selectors are used to specify text used in views in various natural languages, by replacing the text with variables.

Configuring the UI

With the view attributes you can configure the user interface around the main rendering area: the top navigation bar and the bottom search bar.

Note[] {
	/* Set the title of the view, displayed in the top navigation */
    title: "All Notes"
	/* This text is displayed when there are no notes */
    emptyResultText: "There are no notes here yet"

	/* The action button on the right of the title (+ in the screenshot) */
    actionButton: addDataItem
   	/* The set of buttons displayed in the search area */
    filterButtons: showStarred toggleFilterPanel
}

Most relevant view attributes:

  • name

  • title

  • subtitle

  • datasource

  • emptyResultText

  • sortFields

  • defaultRenderer

  • actionButton

  • titleActonButton

  • editActionButton

  • filterButtons

Actions

Remember CVU is not just for defining the looks, but also for interaction. It is possible to create a complete application by connecting different CVU views to each other. The developer tool is a great way to build small functionality in no time.

The names of the actions used for actionButton and filterButtons refer to pre-defined “actions”. For a full list of actions click here. Actions can optionally take arguments in order to control their behavior. Let’s add an argument to addDataItem where we specify the defaults for a new note. We’ll also change the icon from the default + sign to one that is specific for adding a new note.

Click here to see the full list of attributes

View Attributes

Buttons & actions

Renderer

Creating a view

Displaying your data in a renderer

The screenshot below shows the Memri browser displaying a set of example notes. The Memri browser has a navigation bar at the top with several buttons. In the bottom there is a search bar with another set of buttons. All these buttons can be set in a CVU definition. This gives maximum control over the way you view your information.

We hope that there will eventually be many views created by an open community of user enthusiasts and professional view makers. We invite everyone to contribute to the Memri gitlab.

on your information.

Buttons

All these buttons can be set in a CVU definition. This gives maximum control over the way you view your information.

Plugins