bridgetown-prismic 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5527c934765e18198f16674eacd9443f5676aba706b9d58327c1ebe49c378234
4
- data.tar.gz: fc37b56802422b8dbba4f4a5686891cd7db5466f7ee3b904d265446c4e645e5a
3
+ metadata.gz: c9490120f332e574829b9e86bb4e5cd8e116cc5d56459deaa6d008918d1259e7
4
+ data.tar.gz: 429b14738f5b6d15cee42b023085b71aa27ce69fcb9a108398efcabccc4aca33
5
5
  SHA512:
6
- metadata.gz: cf5848a62d57b3fd43d501c36e7448cf2ae04600f9683a5faba03940f684c8ad7045218724bc9969b290c20e57b02061f7bf025ed1792d1a26743bc139b778ff
7
- data.tar.gz: 6c4a1f4d5afeab66b929033f5a716a9c5d16e67305f80a71ff25534117276838ec8efed8845d849b434d7c1bb6cc371bf9d07edd7822a71413899b081a50f630
6
+ metadata.gz: 847aebd7f01e975dead3b109ff69d65171da42d1f2a163b1ebf2fc26ffffc5b54db23949ab7027687b20d5b02da6266a1bcb6c90191343658ddfe138d1be1e52
7
+ data.tar.gz: 1d3cde2d78fcd09a22fa26b67caec953a8f9074b101079ead246f74f6e1c19936b405c9e3857c56c9d97eb7612f3f9d459c4dadabe62800b24fbc42ed6920df9
data/CHANGELOG.md CHANGED
@@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ...
11
11
 
12
+ ## 0.2.0
13
+
14
+ - Automatically paginate through results sets
15
+
12
16
  ## 0.1.2
13
17
 
14
18
  - Add hash option to `provide_data`
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2020-present
3
+ Copyright (c) 2021-present Jared White & Bridgetown contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,61 +1,297 @@
1
- # Sample plugin for Bridgetown
1
+ # Bridgetown Prismic CMS Plugin
2
2
 
3
- _NOTE: This isn't a real plugin! Copy this sample code and use it to create your own Ruby gem! [Help guide here…](https://www.bridgetownrb.com/docs/plugins)_ 😃
3
+ The [Bridgetown](https://edge.bridgetownrb.com) Prismic plugin allows you to pull content directly out of your [Prismic CMS](https://prismic.io) repository and generate resources you can use in all of your templates and plugins the same as if they were files saved directly in your site's `src` folder. Posts, pages, and any custom collections you want to set up are fully supported.
4
4
 
5
- _Starting with Bridgetown v0.15, you can run_ `bridgetown plugins new` _to easily set up a customized verison of this starter repo._
5
+ In addition, this plugin allows you to set up draft previews so you can see how your content will look before it's published and deployed as a static site. This will require you to host a preview site on a platform which supports Ruby Rack-based applications. We recommend [Render](https://render.com), but you can use Heroku or most other platforms which support Ruby (Rails, etc.).
6
6
 
7
- A Bridgetown plugin to [fill in the blank]
7
+ This plugin requires Ruby 3 and the latest alpha version of [Bridgetown 1.0](https://edge.bridgetownrb.com).
8
8
 
9
9
  ## Installation
10
10
 
11
- Run this command to add this plugin to your site's Gemfile:
11
+ Add the gem to your Gemfile and set up initial configuration by running the automation script:
12
12
 
13
- ```shell
14
- $ bundle add my-awesome-plugin -g bridgetown_plugins
13
+ ```sh
14
+ $ bin/bridgetown apply https://github.com/bridgetownrb/bridgetown-prismic
15
15
  ```
16
16
 
17
- Or if there's a `bridgetown.automation.rb` automation script, you can run that instead for guided setup:
17
+ This will add a `prismic_repository` setting to your `bridgetown.config.yml` file. Replace that with the subdomain of your Prismic repo.
18
+
19
+ It will also set up a `models` folder where you will add the Bridgetown models corresponding to your Prismic custom types. More details on that below.
20
+
21
+ ### Draft Previews
22
+
23
+ To set up previews using your Bridgetown Roda backend, modify your `server/roda_app.rb` file by adding:
24
+
25
+ ```ruby
26
+ require "bridgetown-prismic/roda/previews"
27
+ ```
28
+
29
+ to the top of the file, and then adding:
30
+
31
+ ```ruby
32
+ include BridgetownPrismic::Roda::Previews
33
+ ```
34
+
35
+ right underneath `class RodaApp < Bridgetown::Rack::Roda`.
36
+
37
+ Also ensure you have the Bridgetown SSR plugin installed (aka `plugin :bridgetown_ssr` is somewhere above your `route do |r|` block).
38
+
39
+ Your file should end up looking something like this:
40
+
41
+ ```ruby
42
+ require "bridgetown-prismic/roda/previews"
43
+
44
+ class RodaApp < Bridgetown::Rack::Roda
45
+ include BridgetownPrismic::Roda::Previews
46
+
47
+ plugin :bridgetown_ssr
48
+
49
+ route do |r|
50
+ Bridgetown::Rack::Routes.start! self
51
+ end
52
+ end
53
+ ```
54
+
55
+ Next, create a `server/routes/preview.rb` route file:
56
+
57
+ ```ruby
58
+ class Routes::Preview < Bridgetown::Rack::Routes
59
+ route do |r|
60
+ r.on "preview" do
61
+ # Route hit by the Prismic preview flow
62
+ # route: /preview
63
+ r.is do
64
+ unless prismic_preview_token
65
+ response.status = 403
66
+ next prismic_token_error_msg
67
+ end
68
+
69
+ r.redirect prismic_preview_redirect_url
70
+ end
71
+
72
+ # Rendering pathway to preview a page
73
+ # route: /preview/:custom_type/:id
74
+ r.is String, String do |custom_type, id|
75
+ unless prismic_preview_token
76
+ response.status = 403
77
+ next prismic_token_error_msg
78
+ end
79
+
80
+ save_prismic_preview_token
81
+
82
+ Bridgetown::Model::Base
83
+ .find("prismic://#{custom_type}/#{id}")
84
+ .render_as_resource
85
+ .output
86
+ end
87
+ end
88
+ end
89
+ end
90
+ ```
91
+
92
+ This file handles two routes: `/preview` and `/preview/:custom_type/:id`. Upon clicking the preview icon in the Prismic editing interface, Prismic will hit your `/preview` route first with an access token. That saves a cookie, which is then used after the redirect to the `/preview/:custom_type/:id` route (which in practice will look something like `/page/YYsenhEAACIADwbi`). As long as you've set up your models correctly, Bridgetown will automatically know how to render the resource for the preview.
93
+
94
+ ## Setting Up Your Content Models
95
+
96
+ This is where all the magic happens. ✨
97
+
98
+ By creating a content model class for each custom type in Prismic, you establish a 1:1 mapping between a piece of content in Prismic and a piece of content your site will use to build resources. The automation script installed an example of a **Post** content model. Let's take a closer look.
99
+
100
+ At the top of the file are a series of configuration options:
101
+
102
+ ```ruby
103
+ class << self
104
+ def collection_name = :posts
105
+ def prismic_custom_type = :blog_post
106
+ def prismic_slug(doc) = doc.slug
107
+ def prismic_url(doc)
108
+ doc_date = doc["blog_post.optional_publish_datetime"]&.value&.localtime || doc.first_publication_date
109
+ ymd = "#{doc_date.strftime("%Y")}/#{doc_date.strftime("%m")}/#{doc_date.strftime("%d")}"
110
+ "/#{ymd}/#{prismic_slug(doc)}/"
111
+ end
112
+ end
113
+ ```
114
+
115
+ * `collection_name`: this can be a built-in collection such as `posts` or `pages`, or it can be a custom collection you've configured in `bridgetown.config.yml`.
116
+ * `prismic_custom_type`: this will be the "API ID" of the custom type in Prismic.
117
+ * `prismic_slug`: this should return the "slug" (aka `my-document-title`) of a Prismic document. In this example the slug Prismic chose is being used verbatim, but you can make alterations as you see fit.
118
+ * `prismic_url`: this should return the full URL of the final destination for the content. It should match the permalink settings of your collection. This is used by the "link resolver"—aka anywhere in a Prismic document where you've added a link to another Prismic document, the URL for that link to resolved using this return value for the custom type.
119
+
120
+ All right, with those options out of the way, on to the main event:
121
+
122
+ ```ruby
123
+ def self.process_prismic_document(doc)
124
+ provide_data do
125
+ # Variable # Prismic Field # Formatting
126
+ id doc.id
127
+ slug from: -> { prismic_slug(doc) }
128
+ type doc.type
129
+ created_at doc.first_publication_date
130
+ date doc["blog_post.optional_publish_datetime"]&.value&.localtime || created_at
131
+
132
+ title doc["blog_post.title"] .as_text
133
+ subtitle doc["blog_post.subtitle"] &.as_text
134
+ author doc["blog_post.author_name"] &.as_text
135
+ featured_image doc["blog_post.featured_image"] &.url
136
+
137
+ content doc["blog_post.post_body"] &.as_html with_links
138
+ end
139
+ end
140
+ ```
141
+
142
+ This where you create the 1:1 mappings between the Prismic fields and the "front matter" (aka data) + content of your model/resource. Any time you access the resource in templates by writing `resource.data.title` or `resource.content`, it will be pulling those values from these mappings.
143
+
144
+ Within the `provide_data` block, you use a special Ruby DSL in a spreadsheet-like manner to set up the mappings. On the left-hand "column", you specify the name of the front matter variable (or content). In the middle column, you use Prismic's Ruby API to get a field value or metadata. On the right-hand column, you "coerce" the value into the type of data you'r looking for. Note that any field which the author hasn't filled in has a `nil` value, so you can see this is using Ruby's safe navigation operator `&` (whimsically known as the "lonely operator") most of the time so nil values won't crash the import process.
145
+
146
+ You can [read more about Prismic's Ruby Document API here](https://prismic.io/docs/technologies/the-document-object-ruby) for information on when to use `value` or `as_text` or `url`, etc.
147
+
148
+ A few notes on the Ruby DSL:
149
+
150
+ * Any time you see `from: -> { ... }`, that's a lambda which is evaluated directly in the model object scope. Essentially it's a way to "escape" the DSL.
151
+ * You can nest values using a block, for example:
152
+ ```ruby
153
+ attachment do
154
+ name doc["bulletin.name"] .value.downcase
155
+ pdf_url doc["bulletin.pdf_file"] .url
156
+ end
157
+ ```
158
+ which would let you access the data like so:
159
+ ```ruby
160
+ resource.data.attachment.name
161
+ resource.data.attachment.pdf_url
162
+ ```
163
+ * You can call `provide_data` from within a `from:` lambda, which is very useful when looping through Prismic slices and generating nested content. For example:
164
+ ```ruby
165
+ tiles from: -> {
166
+ doc["homepage.body"].slices.map do |slice|
167
+ case slice.slice_type
168
+ when "homepage_tile"
169
+ slice.repeat.group_documents.map do |tile|
170
+ provide_data do
171
+ backdrop tile["backdrop"] &.url
172
+ heading tile["heading"] &.as_text
173
+ description tile["description"]&.as_html with_links
174
+ end
175
+ end
176
+ end
177
+ end.flatten.compact
178
+ }
179
+ ```
180
+ This would result in a `resource.data.tiles` array with one or more hashes including `backdrop`, `heading`, and `description` keys.
181
+
182
+ The Ruby DSL is pretty nifty, but you may occasionally run into a conflict between your variable name and an existing Ruby method. For example, you couldn't add something like `method doc["page.method"] .as_text` because `method` is an existing Ruby object method. Instead, use `set` like so:
18
183
 
19
184
  ```ruby
20
- $ bundle exec bridgetown apply https://github.com/username/my-awesome-plugin
185
+ set :method, doc["page.method"].as_text
186
+ ```
187
+
188
+ Finally, if you decide to need to bail and want to provide a standard hash instead of using the Ruby DSL, you can do that too!
189
+
190
+ ```ruby
191
+ def self.process_prismic_document(doc)
192
+ provide_data({
193
+ # Variable # Prismic Field # Formatting
194
+ id: doc.id,
195
+ slug: prismic_slug(doc),
196
+ type: doc.type,
197
+ created_at: doc.first_publication_date,
198
+
199
+ title: doc["test_page.title"] .as_text,
200
+
201
+ content: doc["test_page.body"] &.as_html(with_links),
202
+ })
203
+ end
204
+ ```
205
+
206
+ Just remember to put all your colons, commas, and parentheses in the right places! 😅
207
+
208
+ ### Trying Out Your Models
209
+
210
+ The Bridgetown console is a good place to inspect your content. Just run `bin/bridgetown console` or `c` and then you can poke through your collections and see what's what.
211
+
212
+ ```
213
+ irb> resource = site.collections.pages.resources.find { |page| page.data.slug == "my-page" }
214
+
215
+ irb> resource.data
216
+
217
+ irb> resource.content
218
+
219
+ irb> resource.model.prismic_doc # access the original Prismic Document object
21
220
  ```
22
221
 
23
- ## Usage
222
+ ## Indicating Previews in Your Site's Layout
24
223
 
25
- The plugin will
224
+ When previewing content, it's helpful to know at a glance that you're looking at a preview, not a piece of published content. You can add a conditional block to the top of your layout's `<body>` which will detect the presense of a preview token and display a preview notice at the top of the page.
26
225
 
27
- ### Optional configuration options
226
+ Example for a Liquid layout:
28
227
 
29
- The plugin will automatically use any of the following metadata variables if they are present in your site's `_data/site_metadata.yml` file.
228
+ ```liquid
229
+ {% if site.prismic_preview_token %}
230
+ <p class="text-center" style="padding:7px; background:rgb(255, 230, 0); border-bottom:2px solid #333; margin:0; font-family:sans-serif; font-weight:bold; font-size:110%">
231
+ PREVIEW
232
+ </p>
233
+ {% endif %}
234
+ ```
235
+
236
+ or an ERB layout:
237
+
238
+ ```erb
239
+ <% if site.data.prismic_preview_token %>
240
+ <p class="text-center" style="padding:7px; background:rgb(255, 230, 0); border-bottom:2px solid #333; margin:0; font-family:sans-serif; font-weight:bold; font-size:110%">
241
+ PREVIEW
242
+ </p>
243
+ <% end %>
244
+ ```
245
+
246
+ ## Deploying on Render
247
+
248
+ You can easily deploy your preview site on [Render](https://render.com) and use it for previewing draft content. For modest website deployments, your preview site could also serve as your public site (with the public only seeing the "static" published content), but generally we recommend a second static site deployment for the public to access (which Render also supports—you can run `bin/bridgetown configure render` to set up a static site config).
249
+
250
+ The starter plan (US $7/month as of the time of this writing) is recommended. Simply add (or edit) a `render.yaml` file in the root of your site repo:
251
+
252
+ ```yaml
253
+ services:
254
+ - type: web
255
+ name: your-site-name-here
256
+ env: ruby
257
+ repo: https://github.com/username/your-site-name-here
258
+ buildCommand: bundle install && yarn install && bin/bridgetown frontend:build
259
+ startCommand: bin/bridgetown start
260
+ envVars:
261
+ - key: BRIDGETOWN_ENV
262
+ value: production
263
+ ```
264
+
265
+ Once your repo is checked into GitHub, you can access it in Render and it will be configured and deployed "automagically." 😁
266
+
267
+ After that, in your Prismic CMS settings under "Previews", you can create a new preview with the following settings:
30
268
 
31
-
269
+ * Site Name: Preview
270
+ * Domain: https://your-site-name-here.onrender.com
271
+ * Link Resolver: /preview
32
272
 
33
- ## Testing
273
+ In addition, you'll want to set up a webhook so any published content will trigger a rebuild of your preview and public sites.
274
+
275
+ Go to the "Webhooks" settings page and add a new webook:
276
+
277
+ * Name of the webhook: Preview Site (or Public Site)
278
+ * URL: (you will need to obtain this from your [Render site's deploy hook config (see documentation)](https://render.com/docs/deploy-hooks)
279
+ * Secret: (leave this blank)
280
+
281
+ ## Questions? Feedback?
282
+
283
+ Please submit an issue to this GitHub repo and we'll address your concerns as soon as possible. In addition, [you can get in touch with the Bridgetown core team and community members](https://www.bridgetownrb.com/docs/community) through the usual channels.
284
+
285
+ ## Testing This Gem
34
286
 
35
287
  * Run `bundle exec rake test` to run the test suite
36
288
  * Or run `script/cibuild` to validate with Rubocop and Minitest together.
37
289
 
38
290
  ## Contributing
39
291
 
40
- 1. Fork it (https://github.com/username/my-awesome-plugin/fork)
292
+ 1. Fork it (https://github.com/bridgetownrb/bridgetown-prismic/fork)
41
293
  2. Clone the fork using `git clone` to your local development machine.
42
294
  3. Create your feature branch (`git checkout -b my-new-feature`)
43
295
  4. Commit your changes (`git commit -am 'Add some feature'`)
44
296
  5. Push to the branch (`git push origin my-new-feature`)
45
297
  6. Create a new Pull Request
46
-
47
- ----
48
-
49
- ## Releasing (you can delete this section in your own plugin repo)
50
-
51
- To release a new version of the plugin, simply bump up the version number in both `version.rb` and
52
- `package.json`, and then run `script/release`. This will require you to have a registered account
53
- with both the [RubyGems.org](https://rubygems.org) and [NPM](https://www.npmjs.com) registries.
54
- You can optionally remove the `package.json` and `frontend` folder if you don't need to package frontend
55
- assets for Webpack.
56
-
57
- If you run into any problems or need further guidance, please check out our [Bridgetown community resources](https://www.bridgetownrb.com/docs/community)
58
- where friendly folks are standing by to help you build and release your plugin or theme.
59
-
60
- **NOTE:** make sure you add the `bridgetown-plugin` [topic](https://github.com/topics/bridgetown-plugin) to your
61
- plugin's GitHub repo so the plugin or theme will show up on [Bridgetown's official Plugin Directory](https://www.bridgetownrb.com/plugins)! (There may be a day or so delay before you see it appear.)
@@ -1,8 +1,11 @@
1
+ say_status :prismic, "Installing the bridgetown-prismic plugin..."
2
+
1
3
  add_bridgetown_plugin("bridgetown-prismic")
2
4
 
3
5
  append_to_file "bridgetown.config.yml" do
4
6
  <<~YAML
5
7
 
8
+
6
9
  # Prismic config:
7
10
  prismic_repository: repo_name_here
8
11
  autoload_paths:
@@ -11,4 +14,8 @@ append_to_file "bridgetown.config.yml" do
11
14
  YAML
12
15
  end
13
16
 
14
- create_file "models/post.rb", File.read(File.join(__dir__, "test", "fixtures", "models", "post.rb")
17
+ get "https://raw.githubusercontent.com/bridgetownrb/bridgetown-prismic/main/test/fixtures/models/post.rb",
18
+ "models/post.rb"
19
+
20
+ say_status :prismic, "All set! Double-check your Prismic settings and model files and review docs at"
21
+ say_status :prismic, "https://github.com/bridgetownrb/bridgetown-prismic"
@@ -20,10 +20,27 @@ module BridgetownPrismic
20
20
  def query_prismic(custom_type, options = {})
21
21
  Bridgetown.logger.info "Prismic API:", "Loading #{custom_type.to_s.green}..."
22
22
 
23
- BridgetownPrismic
24
- .api
25
- .query(Prismic::Predicates.at("document.type", custom_type.to_s), options)
26
- .results
23
+ results = []
24
+ page = 1
25
+ finalpage = false
26
+ options["pageSize"] ||= 100 # pull in as much data as possible for a single request
27
+
28
+ until finalpage
29
+ options["page"] = page
30
+
31
+ response = BridgetownPrismic
32
+ .api
33
+ .query(Prismic::Predicates.at("document.type", custom_type.to_s), options)
34
+
35
+ results += response.results
36
+ if response.total_pages > page
37
+ page += 1
38
+ else
39
+ finalpage = true
40
+ end
41
+ end
42
+
43
+ results
27
44
  end
28
45
 
29
46
  def query_prismic_and_generate_resources_for(klass)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BridgetownPrismic
4
- VERSION = "0.1.2"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bridgetown-prismic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bridgetown Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-10 00:00:00.000000000 Z
11
+ date: 2021-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bridgetown