Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/luchiniatwork/contentql
Access Contentful data using Om Next Queries
https://github.com/luchiniatwork/contentql
clojure clojurescript cms content contentful omnext query-language
Last synced: 2 months ago
JSON representation
Access Contentful data using Om Next Queries
- Host: GitHub
- URL: https://github.com/luchiniatwork/contentql
- Owner: luchiniatwork
- License: other
- Created: 2017-08-31T13:16:37.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-04-25T21:50:33.000Z (over 5 years ago)
- Last Synced: 2024-10-18T19:32:36.431Z (3 months ago)
- Topics: clojure, clojurescript, cms, content, contentful, omnext, query-language
- Language: Clojure
- Homepage:
- Size: 41 KB
- Stars: 15
- Watchers: 2
- Forks: 3
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ContentQL
ContentQL allows one to access Contentful data using Om Next Queries.
[Contentful](https://www.contentful.com/) is a popular headless, cloud-based CMS system. Beyond
being purely an API-first CMS system it also supports somewhat complex data schemas, responsive
images and webhooks making it a very compelling content platform.Despite the great features provided by Contentful, one thing remains somewhat challenging:
its API is not the most straightforward to use.Instead of porting Contentful's API on a one-on-one basis to Clojure and ClojureScript, this
library takes an abstraction route to querying: it uses Om Next's Query language as its main
interface.## Table of Contents
* [Getting Started](#getting-started)
* [Motivation](#motivation)
* [Features](#features)
* [Query Syntax](#query-syntax)
* [Usage](#usage)
* [Pagination](#pagination)
* [Bugs](#bugs)
* [Help!](#help)## Getting Started
Add the following dependency to your `project.clj` file:
[![Clojars Project](http://clojars.org/luchiniatwork/contentql/latest-version.svg)](http://clojars.org/luchiniatwork/contentql)
## Motivation
By using Om Next queries one can:
* easily describe deep nested joins
* clearly parameterize root (as well as other) queries
* easily express field selections
* easily dispatch queries to Contentful from Om Next remotes
* easy-to-use responsive images as part of the query
* describe your queries using macro syntax## Features
ContentQL's key features are:
1. Support for both Clojure and ClojureScript
2. Seamless `clojure.core.async` and `cljs.core.async` support
3. Use with or without Om Next - it's your call
4. Access to deep field selectors
5. Access to filters, ordering, and pagination
6. Dead simple, cached, responsive images## Query Syntax
The Om Next query syntax is beautifuly described by António Monteiro [here](https://anmonteiro.com/2016/01/om-next-query-syntax/) but if you need a quick primer, here it is:
### Simple properties
If you have a content type called `blogs`, you can query its entries with:
```clojure
'[:blogs]
```You can always combine several content types in one go:
```clojure
'[:blogs :articles]
```### Joins
If you want just the `title` and the `body` of your `blogs`, you can use a join such as:
```clojure
'[{:blogs [:title :body]}]
```### Nested joins
Assuming your `blogs` content type has an `author` embedded whose `name` you want to fetch
as well, simply nest your joins:```clojure
'[{:blogs [:title :body
{:author [:name]}]}]
```This will continue to give you the `title` and the `body` of each blog entry but now also
the name of each blog's author.### Parametrized queries
Queries can be parametrized by using a list where the second element is a map of parameters.
If you want the blog identified by `id` `"3x1YMtJ1CoOWk0ycYsOw4I"` you can fetch it with:```clojure
'[(:blogs {:id "3x1YMtJ1CoOWk0ycYsOw4I"})]
```This can be combined with joins, ie:
```clojure
'[({:blogs [:title :body]} {:id "3x1YMtJ1CoOWk0ycYsOw4I"})]
```Or even nested joins:
```clojure
'[({:blogs [:title :body
{:author [:name]}]}
{:id "3x1YMtJ1CoOWk0ycYsOw4I"})]
```
### Supported parameters for Query rootsAll your content types can be queries as part of a query root.
You've already seen above how to query a specific entry by its `id`:
```clojure
'[(:blogs {:id "3x1YMtJ1CoOWk0ycYsOw4I"})]
```In addition to `:id` the other supported query root parameters are:
* `:limit` - limits the page size to its value (i.e. `:limit 10`)
* `:skip` - skips the specified number of entries (i.e. `:skip 5` skips 5 entries)
* `:order` - allows ordering of the entries (i.e. `:order "fields.name"` ordres the dataset by `name`). Reverse ordering is supported with the addition of `-` (i.e. `:order "-fields.name"`)### Supported parameters for Images
Any image asset is immidetally wrapped in an image entity containing three fields `:width`, `:height` and `:url`. The asset can be scaled up or down by sending the intended `:width` or `:height` parameter.
In order to see it in action, suppose your `author` has an `avatar` image and you want it constrained within a `width` of 150 pixels:
```clojure
'[{:authors [({:avatar [:width
:height
:url]}
{:width 150})]}]
```## Usage
Async channels are slightly different between Clojure and ClojureScript due to underlying characteristics of how the JVM and the JavaScript environment deal with multi-threading. ContentQL supports both platforms seamlessly.
For Clojure, require `contentql.core` and `clojure.core.async`:
```clojure
(ns my-project
(:require [contentql.core :as contentql]
[clojure.core.async :refer [go