prismicio / prismic-demo

14 stars 4 forks source link

Demo project for Prismic.io

It's meant to work with API v2 libs here:


1. Installation

Prismic CLI
NPM
Start
Dev

2. Query the content

3. Integrate the content

Embed
Image
Text
Number
Date
Timestamp
Select
Color
StructuredText
WebLink
DocumentLink
ImageLink
FileLink
Separator
Group
GeoPoint
Slices

4. Contribute

5. Implement I18N

6. Manage profiles

7. License

===================================================

Installation

Prismic CLI

NPM

npm install

Start

npm start

Dev

npm run dev

Query the content

To fetch documents from your repository, you need to fetch the Api data first.

var Prismic = require('prismic-javascript');

Prismic.api("http://your_repository_name.prismic.io/api", function(error, api) {
  var options = {}; // In Node.js, pass the request as 'req' to read the reference from the cookies
  api.query("", options, function(err, response) { // An empty query will return all the documents
    if (err) {
      console.log("Something went wrong: ", err);
    }
    console.log("Documents: ", response.documents);
  });
});

All asynchronous calls return ES2015 promises, so alternatively you can use them instead of callbacks.

var Prismic = require('prismic-javascript');

Prismic.api("https://your-repository-name.prismic.io/api").then(function(api) {
  return api.query(""); // An empty query will return all the documents
}).then(function(response) {
  console.log("Documents: ", response.results);
}, function(err) {
  console.log("Something went wrong: ", err);
});

See the developer documentation or the API documentation for more details on how to use it.

Integrate the content

In each case documented below, you will have a snippet of the custom type and another for the code needed to fill the content field into your JS Template. In these examples we have a doc parameter corresponding to the fetched prismic document.

Embed

Custom type

"video" : {
  "type" : "Embed"
}

Template JS

doc.data.video.embed_url

Image

Custom type

"photo" : {
  "type" : "Image",
  "fieldset" : "Image",
  "config" : {
    "constraint" : {
      "width" : 300,
      "height" : 300
    },
    "thumbnails" : [ {
      "name" : "Small",
      "width" : 100,
      "height" : 100
    }, {
      "name" : "Medium",
      "width" : 200,
      "height" : 200
    }, {
      "name" : "Large",
      "width" : 300,
      "height" : 300
    } ]
  }
}

Template JS

//main view
doc.data.photo.url
doc.data.photo.alt
doc.data.photo.width
doc.data.photo.height

//thumbnails => example for small view
doc.data.photo.small.url
doc.data.photo.small.alt
doc.data.photo.small.width
doc.data.photo.small.height

Text

Custom type

"title" : {
  "type" : "Text",
}

Template JS

doc.data.title

Number

Custom type

"count" : {
  "type" : "Text",
}

Template JS

doc.data.count

Date

Custom type

"publication" : {
  "type" : "Date",
}

Template JS

import { Date } from 'prismic-dom'

// date as string from the API
doc.data.publication
// date as JS Date
Date(doc.data.publication)

Timestamp

Custom type

"time" : {
  "type" : "Timestamp",
}

Template JS

import { Date } from 'prismic-dom'

// timestamp as string from the API
doc.data.time
// timestamp as JS Datetime
Date(doc.data.time)

Select

Custom type

"gender" : {
  "type" : "Select",
}

Template JS

doc.data.gender

Color

Custom type

"background" : {
  "type" : "Color",
}

Template JS

doc.data.background

RichText

Custom type

"description" : {
  "type" : "StructuredText",
}

Template JS

import { RichText } from 'prismic-dom'

RichText.asText(doc.data.description)

//linkResolver must be declare somewhere
RichText.asHtml(doc.data.description, linkResolver)

WebLink

Custom type

"linktoweb" : {
  "type" : "Link",
  "config" : {
    "select" : "web"
  }
}

Template JS

doc.data.linktoweb.url

DocumentLink

Custom type

"linktodoc" : {
  "type" : "Link",
  "config" : {
    "select" : "document",
    "customtypes" : [ <your-custom-type-id> ],
    "tags" : [ <your-tag> ],
  }
}

Template JS

//return url of the document link
doc.data.linktodoc
//return url of the document
linkResolver(doc.data.linktodoc)

ImageLink

Custom type

"linktomedia" : {
  "type" : "Link",
  "config" : {
    "select" : "media"
  }
}

Template JS

doc.data.linktomedia.url

FileLink

Custom type

"linktofile" : {
  "type" : "Link",
  "config" : {
    "select" : "media"
  }
}

Template JS

doc.data.linktofile.url

Group

Custom type

"feature" : {
  "type" : "Group",
  "repeat": true, //default to true but put explicitly for the example
  "config" : {
    "field" : {
        "title" : {
          "type" : "Text",
        },
        "description" : {
          "type" : "StructuredText",
        }
    }
  }
}

Template JS

import { RichText } from 'prismic-dom'

doc.data.feature.forEach(item => {
    item.title
    RichText.asHtml(item.description, linkResolver)
})

GeoPoint

Custom type

"location" : {
  "type" : "GeoPoint",
}

Template JS

doc.data.latitude
doc.data.longitude

Slices

Slice with Group as value The Group value will be put directly as Slice value Custom type

"contentAsSlices" : {
    "fieldset" : "Dynamic page zone...",
    "type" : "Slices",
    "config" : {
        "choices" : {
            "slides" : {
                "type" : "Group",
                //required to display name in slice select in the writing room
                "fieldset" : "Slides",
                "config" : {
                    "fields" : {
                        "illustration" : {
                          "type" : "Image"
                        },
                        "title" : {
                          "type" : "StructuredText"
                        }
                    }
                }
            }
        }
    }
}

Template JS

doc.data.contentAsSlices.map((slice) => {
    switch(slice.slice_type) {
        case 'slides':
          slice.value.map((item) => {
            item.illustration.url
            item.title
          })
          break
    }
})

Slice with basic fragment like Text as value The fragment value will be put directly as Slice value Custom type

"contentAsSlices" : {
    "fieldset" : "Dynamic page zone...",
    "type" : "Slices",
    "config" : {
        "choices" : {
            "description" : {
              "type" : "StructuredText"
            }
        }
    }
}

Template JS

import { RichText } from 'prismic-dom'

doc.contentAsSlices.map((slice) => {
    switch(slice.slice_type) {
        case 'description':
            RichText.asHtml(slice.value, linkResolver)
            break
    }
})

new Slice the new Slice type allow you to create a repeatable area and a non repeatable one.

"contentAsSlices" : {
    "fieldset" : "Dynamic page zone...",
    "type" : "Slices",
    "config" : {
        "choices" : {
            "newslice" : {
              "type" : "Slice",
              "non-repeat": {
                "title": {
                  "type": "Text"
                }
              },
              "repeat": {
                "description": {
                  "type" : "StructuredText"
                }
              }
            }
        }
    }
}

Template JS

import { RichText } from 'prismic-dom'

doc.contentAsSlices.map((slice) => {
    switch(slice.slice_type) {
        case 'newslice':
          //non repeatable part
          slice.value.primary.title

          //repeatable part
          slice.value.items.map(item => {
            RichText.asHtml(item.description, linkResolver)
          })
          break
    }
})

Contribute

Run the project

Install dependencies:

npm install

Run the project in standard mode:

npm start

Run the project in dev mode: (start nodeJS Server + build sass files)

npm run dev

Stylesheets

Stylesheets are written with the preprocessor sass in scss format. They are localized in ./assets/stylesheets. You must split each slice in a file to simplify modularity and public sharing. Don't bother to prefix css properties for each browser, it's already done with autoprefixer when you start the project in dev mode.

Javascript

Since there is no complex javascript required yet, you only have one file ./public/javascript/main.js to interact directly with the DOM and make any js client code.

Slices

How to build a slice named MyDemoSlice:

Implement i18n

The localization is implemented out of the box. You got 4 things to check if you wanna customize it:

Manage Profiles

In this demo, you can manage different profiles of users out of the box. It's handled with a basic cookies system. You can just switch profile directly in the footer and it will set a new profile.

How it works? You must set your profiles in profiles.json according to the example in this file. Each time you switch profile from the select in the footer, it create a cookie prismic.profile with the value of the profile you just selected. You have now an easy access to the current profile directly from the cookies. You can access it from the back with the following code:

  res.locals.PrismicProfiles.current

You can also access the list of all profiles:

  res.locals.PrismicProfiles.profiles

But also the default profile:

  res.locals.PrismicProfiles.default

And finally you can access the same PrismicProfiles object from the client in window.PrismicProfiles. It contains exactly the same thing.

License

This software is licensed under the Apache 2 license, quoted below.

Copyright 2013-2017 Prismic.io (http://prismic.io).

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.