pollen start gives error if there are other directories #40

Closed
opened 4 years ago by adamfeuer · 11 comments
adamfeuer commented 4 years ago (Migrated from github.com)

Hi,

I want to have some javascript and css static files in my pollen content directory so that the web pages render correctly. These are from Zurb Foundation Sites. When pollen tries to compile the project, I get an error, see below.

My directory layout is like this:

content/
  index.html.pm
  pollen.rkt
  template.html.p
  css/
    app.css
  js/
    app.js

How can I use the pollen webserver and also have static css and js at the same paths that they would be when published...?

I created a small publish script that does pollen render to an output directory, and then copies in the css and js static files which I can serve using npm. This works, but it requires the additional manual step to run the publish script.

Here's the error:

Servlet (@ /index.html) exception:
select: contract violation
  expected: existing Pollen source, or name of its output path
  given: #<path:/Users/adam/personal/proj/hcpr/hcpr/content/js1>

  context...:
   get-metas
   /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/core.rkt:28:25: select*
   select
   /Applications/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   'g354: [running body]
   temp35_0
   for-loop
   run-module-instance!
   perform-require!
   for-loop
   top-level: [running body]
   eval-one-top
   begin-loop
   /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/render.rkt:343:0: render-markup-or-markdown-source
   /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/render.rkt:269:25: render
   /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/private/cache-utils.rkt:110:2: generate-dest-file
   ...```
Hi, I want to have some javascript and css static files in my pollen content directory so that the web pages render correctly. These are from [Zurb Foundation Sites](https://get.foundation/sites/docs/). When pollen tries to compile the project, I get an error, see below. My directory layout is like this: ``` content/ index.html.pm pollen.rkt template.html.p css/ app.css js/ app.js ``` How can I use the pollen webserver and also have static css and js at the same paths that they would be when published...? I created a small publish script that does pollen render to an output directory, and then copies in the css and js static files which I can serve using npm. This works, but it requires the additional manual step to run the publish script. Here's the error: ```pollen: rendering /index.html.pm Servlet (@ /index.html) exception: select: contract violation expected: existing Pollen source, or name of its output path given: #<path:/Users/adam/personal/proj/hcpr/hcpr/content/js1> context...: get-metas /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/core.rkt:28:25: select* select /Applications/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18 'g354: [running body] temp35_0 for-loop run-module-instance! perform-require! for-loop top-level: [running body] eval-one-top begin-loop /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/render.rkt:343:0: render-markup-or-markdown-source /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/render.rkt:269:25: render /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/private/cache-utils.rkt:110:2: generate-dest-file ...```
mbutterick commented 4 years ago (Migrated from github.com)

The error message refers to js1 but there’s no file called js1 in your project. Could this error be the result of a typo in index.html.pm or template.html.p?

The error message refers to `js1` but there’s no file called `js1` in your project. Could this error be the result of a typo in `index.html.pm` or `template.html.p`?
adamfeuer commented 4 years ago (Migrated from github.com)

I had been trying different things, creating a js1 directory instead of symlinks, so that directory did exist, I made a mistake entering the layout above. If I remove the directory js1 to make the directory conform to the layout above, I get the same error:

select: contract violation
  expected: existing Pollen source, or name of its output path
  given: #<path:/Users/adam/personal/proj/hcpr/hcpr/content/js>

  context...:
   get-metas
   /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/core.rkt:28:25: select*
   select
   /Applications/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   'g246: [running body]
   temp35_0
   for-loop
   run-module-instance!
   perform-require!
   for-loop
   top-level: [running body]
   eval-one-top
   begin-loop
   /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/render.rkt:343:0: render-markup-or-markdown-source
   /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/render.rkt:269:25: render
   /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/private/cache-utils.rkt:110:2: generate-dest-file
I had been trying different things, creating a `js1` directory instead of symlinks, so that directory did exist, I made a mistake entering the layout above. If I remove the directory `js1` to make the directory conform to the layout above, I get the same error: ``` select: contract violation expected: existing Pollen source, or name of its output path given: #<path:/Users/adam/personal/proj/hcpr/hcpr/content/js> context...: get-metas /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/core.rkt:28:25: select* select /Applications/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18 'g246: [running body] temp35_0 for-loop run-module-instance! perform-require! for-loop top-level: [running body] eval-one-top begin-loop /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/render.rkt:343:0: render-markup-or-markdown-source /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/render.rkt:269:25: render /Users/adam/Library/Racket/7.6/pkgs/pollen/pollen/private/cache-utils.rkt:110:2: generate-dest-file ```
mbutterick commented 4 years ago (Migrated from github.com)

If content is essentially a mirror of your public web directory, then to simulate the live environment, you’d want to a) start the project server from content as the top-level directory, and b) usually it’s easiest to use absolute URLs to refer to CSS and JS resources located near the top. For instance, in template.html.p you would refer to "/js/app.js" and "/css/app.css" — these URLs would work in the project server, and also in your public directory, since it has the same structure.

If `content` is essentially a mirror of your public web directory, then to simulate the live environment, you’d want to a) start the project server from `content` as the top-level directory, and b) usually it’s easiest to use absolute URLs to refer to CSS and JS resources located near the top. For instance, in `template.html.p` you would refer to `"/js/app.js"` and `"/css/app.css"` — these URLs would work in the project server, and also in your public directory, since it has the same structure.
adamfeuer commented 4 years ago (Migrated from github.com)

Here's an excerpt of what's in content/template.p:

[...]
    <link rel="stylesheet" type="text/css" mgdia="all" href="/css/app.css" />
    <link rel="stylesheet" type="text/css" mgdia="all" href="/styles.css" />
[...]
    <script src="/js/jquery.min.js"></script>
    <script src="/js/foundation.js"></script>
    <script src="/js/app.js"></script>
[...]

So it seems like I'm doing what you are suggesting. But why am I getting a rendering error? It seems like pollen doesn't like something about these directories.

Note that if I remove the css and js directories, I can render using the raco pollen start webserver, but the HTML won't be displayed right in my web browser; or I can render to a separate output dir via my script, and then add the css and js directories back in.

Here's an excerpt of what's in `content/template.p`: ``` [...] <link rel="stylesheet" type="text/css" mgdia="all" href="/css/app.css" /> <link rel="stylesheet" type="text/css" mgdia="all" href="/styles.css" /> [...] <script src="/js/jquery.min.js"></script> <script src="/js/foundation.js"></script> <script src="/js/app.js"></script> [...] ``` So it seems like I'm doing what you are suggesting. But why am I getting a rendering error? It seems like pollen doesn't like something about these directories. Note that if I remove the `css` and `js` directories, I can render using the `raco pollen start` webserver, but the HTML won't be displayed right in my web browser; or I can render to a separate output dir via my script, and then add the `css` and `js` directories back in.
sorawee commented 4 years ago (Migrated from github.com)

Perhaps you can show your

  • index.html.pm
  • pollen.rkt
  • template.html.p

to make it easier to debug?

Perhaps you can show your - index.html.pm - pollen.rkt - template.html.p to make it easier to debug?
adamfeuer commented 4 years ago (Migrated from github.com)

@sorawee Thanks, here's the files:

index.html.pm:

#lang pollen

◊section{
  ◊h1{◊a[#:name "introduction"]{Book}}

  ◊p{
    This is a book.
  }

  ◊p{
    ◊ol{
      ◊li{ ◊a[#:href "#1-what-is-this-book"]{What is this book?}}
      }
    ◊br
  }
}

◊section{
  ◊h2{ ◊a[#:name "1-what-is-this-book"]{1◊br What is this book?}}

  ◊p{ Paragraph text }

  ◊p{}
}

pollen.rkt

#lang racket/base

(require pollen/decode)
(require pollen/misc/tutorial)
(require txexpr)
(require racket/format)

(provide root br div em p pindent pclose pclosetop pclosebottom opening blockquote section §)

(define chapter-counter 0)
(define section-counter 0)
(define (section-link) (set! section-counter (+ section-counter 1))
  (string-append "#chapter-" (~a chapter-counter) ":section-" (~a section-counter)))

(define (root . elements)
 (txexpr 'root empty (decode-elements elements
   #:txexpr-elements-proc decode-paragraphs
   #:string-proc (compose1 smart-quotes smart-dashes))))

(define br (txexpr 'br empty empty))
(define (§) (let ([link-value (section-link)])
    (txexpr 'span '((class "section")) `((a ((href ,link-value) (title ,link-value)
    (class "section-link")) "§")))))

(define (opening . elements)
   (txexpr 'span '((class "opening")) elements))
(define (pindent . elements)
   (txexpr 'p '((class "indent-bottom-padding")) elements))
(define (pclose . elements)
   (txexpr 'p '((class "close")) elements))
(define (pclosebottom . elements)
   (txexpr 'p '((class "close-bottom-padding")) elements))
(define (pclosetop . elements)
   (txexpr 'p '((class "closetop")) elements))

(define (div . elements)
   (txexpr 'div empty elements))
(define (em . elements)
   (txexpr 'em empty elements))
(define (blockquote . elements)
   (txexpr 'blockquote empty elements))
(define (p . elements)
   (txexpr 'p empty elements))
(define (section . elements)
   (set! chapter-counter (+ chapter-counter 1))
   (txexpr 'section empty elements))

template.html.p

<!doctype html>
<html class="no-js" lang="en">
    <meta charset="UTF-8">
    <title>This is the title</title>
    <link rel="stylesheet" type="text/css" mgdia="all" href="/css/app.css" />
    <link rel="stylesheet" type="text/css" mgdia="all" href="/styles.css" />
</head>
<body>
    <div class="grid-x">
      <div class="cell medium-6 large-8">◊(->html doc #:splice? #t)</div>
      <div class="cell small-2">sidebar</div>
    </div>

    <script src="/js/jquery.min.js"></script>
    <script src="/js/foundation.js"></script>
    <script src="/js/app.js"></script>
    <script>
      $(document).ready(function () {
        $(document).foundation();
      });
    </script>

    ◊(define prev-page (previous here))
    ◊when/splice[prev-page]{
    <div id="prev">← <a href="◊|prev-page|">◊(select 'h1 prev-page)</a></div>}
    ◊(define next-page (next here))
    ◊when/splice[next-page]{
    <div id="next"><a href="◊|next-page|">◊(select 'h1 next-page)</a> →</div>}
</body>
</html>
@sorawee Thanks, here's the files: index.html.pm: ``` #lang pollen ◊section{ ◊h1{◊a[#:name "introduction"]{Book}} ◊p{ This is a book. } ◊p{ ◊ol{ ◊li{ ◊a[#:href "#1-what-is-this-book"]{What is this book?}} } ◊br } } ◊section{ ◊h2{ ◊a[#:name "1-what-is-this-book"]{1◊br What is this book?}} ◊p{ Paragraph text } ◊p{} } ``` pollen.rkt ``` #lang racket/base (require pollen/decode) (require pollen/misc/tutorial) (require txexpr) (require racket/format) (provide root br div em p pindent pclose pclosetop pclosebottom opening blockquote section §) (define chapter-counter 0) (define section-counter 0) (define (section-link) (set! section-counter (+ section-counter 1)) (string-append "#chapter-" (~a chapter-counter) ":section-" (~a section-counter))) (define (root . elements) (txexpr 'root empty (decode-elements elements #:txexpr-elements-proc decode-paragraphs #:string-proc (compose1 smart-quotes smart-dashes)))) (define br (txexpr 'br empty empty)) (define (§) (let ([link-value (section-link)]) (txexpr 'span '((class "section")) `((a ((href ,link-value) (title ,link-value) (class "section-link")) "§"))))) (define (opening . elements) (txexpr 'span '((class "opening")) elements)) (define (pindent . elements) (txexpr 'p '((class "indent-bottom-padding")) elements)) (define (pclose . elements) (txexpr 'p '((class "close")) elements)) (define (pclosebottom . elements) (txexpr 'p '((class "close-bottom-padding")) elements)) (define (pclosetop . elements) (txexpr 'p '((class "closetop")) elements)) (define (div . elements) (txexpr 'div empty elements)) (define (em . elements) (txexpr 'em empty elements)) (define (blockquote . elements) (txexpr 'blockquote empty elements)) (define (p . elements) (txexpr 'p empty elements)) (define (section . elements) (set! chapter-counter (+ chapter-counter 1)) (txexpr 'section empty elements)) ``` template.html.p ``` <!doctype html> <html class="no-js" lang="en"> <meta charset="UTF-8"> <title>This is the title</title> <link rel="stylesheet" type="text/css" mgdia="all" href="/css/app.css" /> <link rel="stylesheet" type="text/css" mgdia="all" href="/styles.css" /> </head> <body> <div class="grid-x"> <div class="cell medium-6 large-8">◊(->html doc #:splice? #t)</div> <div class="cell small-2">sidebar</div> </div> <script src="/js/jquery.min.js"></script> <script src="/js/foundation.js"></script> <script src="/js/app.js"></script> <script> $(document).ready(function () { $(document).foundation(); }); </script> ◊(define prev-page (previous here)) ◊when/splice[prev-page]{ <div id="prev">← <a href="◊|prev-page|">◊(select 'h1 prev-page)</a></div>} ◊(define next-page (next here)) ◊when/splice[next-page]{ <div id="next"><a href="◊|next-page|">◊(select 'h1 next-page)</a> →</div>} </body> </html> ```
adamfeuer commented 4 years ago (Migrated from github.com)

@sorawee @mbutterick If I remove the css and js dirs, I get this error from the web server, pollen seems like it's reading the links in the HTML and trying to find and render pollen files. Then it fails, and reads from cache.

Is there a way to tell the pollen web server that these are static directories? So it won't try to render them?

$ raco pollen start .
pollen: starting project server ...
pollen: welcome to Pollen 2.2.2419.786 (Racket 7.6)
pollen: project root is /Users/adam/personal/proj/hcpr/hcpr/content/
pollen: project server is http://localhost:8080 (Ctrl+C to exit)
pollen: project dashboard is http://localhost:8080/index.ptree
pollen: ready to rock
pollen: /index.html from 127.0.0.1
pollen: from cache /index.html
pollen: /css/app.css from 127.0.0.1
pollen: can't find /css/app.css
pollen: /js/app.js from 127.0.0.1
pollen: can't find /js/app.js
pollen: /js/foundation.js from 127.0.0.1
pollen: can't find /js/foundation.js
pollen: /js/jquery.min.js from 127.0.0.1
pollen: can't find /js/jquery.min.js
pollen: /styles.css from 127.0.0.1
pollen: from cache /styles.css
@sorawee @mbutterick If I remove the `css` and `js` dirs, I get this error from the web server, pollen seems like it's reading the links in the HTML and trying to find and render pollen files. Then it fails, and reads from cache. Is there a way to tell the pollen web server that these are static directories? So it won't try to render them? ``` $ raco pollen start . pollen: starting project server ... pollen: welcome to Pollen 2.2.2419.786 (Racket 7.6) pollen: project root is /Users/adam/personal/proj/hcpr/hcpr/content/ pollen: project server is http://localhost:8080 (Ctrl+C to exit) pollen: project dashboard is http://localhost:8080/index.ptree pollen: ready to rock pollen: /index.html from 127.0.0.1 pollen: from cache /index.html pollen: /css/app.css from 127.0.0.1 pollen: can't find /css/app.css pollen: /js/app.js from 127.0.0.1 pollen: can't find /js/app.js pollen: /js/foundation.js from 127.0.0.1 pollen: can't find /js/foundation.js pollen: /js/jquery.min.js from 127.0.0.1 pollen: can't find /js/jquery.min.js pollen: /styles.css from 127.0.0.1 pollen: from cache /styles.css ```
sorawee commented 4 years ago (Migrated from github.com)

The problem, I think, is due to the use of ◊(select 'h1 prev-page) and ◊(select 'h1 next-page) in your template.html.p. Since you didn't define index.ptree, Pollen automatically generates one for you, which contains non-Pollen files. Therefore, the lookup for h1 fail.

So either create index.ptree that contains only Pollen files, or if you don't actually want the previous and next links, just remove:

    ◊(define prev-page (previous here))
    ◊when/splice[prev-page]{
    <div id="prev">← <a href="◊|prev-page|">◊(select 'h1 prev-page)</a></div>}
    ◊(define next-page (next here))
    ◊when/splice[next-page]{
    <div id="next"><a href="◊|next-page|">◊(select 'h1 next-page)</a> →</div>}

from your template.html.p.

The problem, I think, is due to the use of `◊(select 'h1 prev-page)` and `◊(select 'h1 next-page)` in your `template.html.p`. Since you didn't define `index.ptree`, Pollen automatically generates one for you, which contains non-Pollen files. Therefore, the lookup for `h1` fail. So either create `index.ptree` that contains only Pollen files, or if you don't actually want the previous and next links, just remove: ``` ◊(define prev-page (previous here)) ◊when/splice[prev-page]{ <div id="prev">← <a href="◊|prev-page|">◊(select 'h1 prev-page)</a></div>} ◊(define next-page (next here)) ◊when/splice[next-page]{ <div id="next"><a href="◊|next-page|">◊(select 'h1 next-page)</a> →</div>} ``` from your `template.html.p`.
sorawee commented 4 years ago (Migrated from github.com)

See https://docs.racket-lang.org/pollen/second-tutorial.html#%28part.tutorial-2..Pagetrees%29 for more details about the pagetree file.

See https://docs.racket-lang.org/pollen/second-tutorial.html#%28part._tutorial-2._.Pagetrees%29 for more details about the pagetree file.
mbutterick commented 4 years ago (Migrated from github.com)

I get the same errors as you (because I am missing the files — those are the errors I would expect). When I create stub files in the "js" and "css" directories that match those filenames, the errors go away (as I also expect).

There isn’t a fixed boundary between “static directories” and others. Suppose you link to a file "/dir/src.js". If it exists as a static file, the project server uses that. If it doesn’t, the project server looks for a corresponding Pollen source file, renders it, and serves the result.

In other words, a directory of static web files is itself a valid Pollen project and ought to function normally without any need for further configuration.

I get the same errors as you (because I am missing the files — those are the errors I would expect). When I create stub files in the `"js"` and `"css"` directories that match those filenames, the errors go away (as I also expect). There isn’t a fixed boundary between “static directories” and others. Suppose you link to a file `"/dir/src.js"`. If it exists as a static file, the project server uses that. If it doesn’t, the project server looks for a corresponding Pollen source file, renders it, and serves the result. In other words, a directory of static web files is itself a valid Pollen project and ought to function normally without any need for further configuration.
adamfeuer commented 4 years ago (Migrated from github.com)

@sorawee You're right, it was the lack of a pagetree file. I will want the previous and next links when I expand my book, so having the pagetree is necessary. I created this:

#lang pollen

index.html

And now I can use the pollen server with my static css and js files.

Thank you @sorawee and @mbutterick for the help!

@sorawee You're right, it was the lack of a pagetree file. I will want the previous and next links when I expand my book, so having the pagetree is necessary. I created this: ``` #lang pollen index.html ``` And now I can use the pollen server with my static css and js files. Thank you @sorawee and @mbutterick for the help!
This repo is archived. You cannot comment on issues.
No Milestone
No project
No Assignees
1 Participants
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: mbutterick/pollen-users#40
Loading…
There is no content yet.