Comments (8)
I think you’re on the right track. A lot of this is just creating a simple, consistent convention for handling paths in your project so you’re not switching between relative and absolute paths at the wrong moments.
For instance, on Beautiful Racket I have global prev/next navigation that traverses subdirectories correctly. The way I do this is by having one index.ptree
at the top level. The pagenodes are represented as relative to the top level. A partial listing of the output:
'(pagetree-root
(index.html
foreword.html
introduction.html
setup.html
acknowledgments.html
about-the-author.html
legal.html
how-to-pay.html
why-you-should-pay.html
(tutorials-group
(stacker/intro.html
stacker/why-make-languages.html
stacker/setup.html
stacker/the-reader.html
stacker/the-expander.html
stacker/recap.html
stacker/source-listing.html)
(funstacker/intro.html
funstacker/project-setup.html
funstacker/the-rewrite.html
funstacker/recap.html
funstacker/source-listing.html)
(stackerizer/intro.html
stackerizer/specification-and-setup.html
stackerizer/the-expander.html
stackerizer/recap.html
stackerizer/source-listing.html)
···
Then in my template.html.p
— there is only one, also at the top level — I make sure that my prev/next links are always rendered as absolute URLs. Meaning, they start with "/". Then each pagenode provides the rest of the path. Because I’m using absolute URLs, they work the same whether they appear on a top-level page or subdirectory page.
“But dude — that’s not DRY at all! You’re retyping all those subdirectory names!” Ah, but I’m not. Recall that a pagetree source is just another Pollen source, and you can have functions and macros in it as usual. So the index.ptree
source looks like this:
#lang pollen
◊index.html{
foreword.html
introduction.html
setup.html
acknowledgments.html
about-the-author.html
legal.html
how-to-pay.html
why-you-should-pay.html
◊tutorials-group{
◊(splice-subdir stacker)
◊(splice-subdir funstacker)
◊(splice-subdir stackerizer)
◊(splice-subdir bf)
◊(splice-subdir jsonic)
◊(splice-subdir jsonic-2)
◊(splice-subdir jsonic-3)
◊(splice-subdir wires)
◊(splice-subdir basic)
◊(splice-subdir basic-2)
◊(splice-subdir basic-3)
◊(splice-subdir-dev hdl)
}
}
···
Where splice-subdir
is a little macro that goes through and adds all the files from the subdirectory to the pagetree, and also prepends the subdirectory to the path. So DRY it hurts.
from pollen-users.
I literally ran into the same problem today. The code at the linked conversation runs in the pollen template file, not the pollen.rkt file, otherwise you can't get to the metas.
If you add the lozenges, you can output the defined variables in the template.
There's a little more info here: https://docs.racket-lang.org/pollen/pollen-command-syntax.html#%28part._.Inserting_metas%29 . On the page it shows a way to include it in a racket source file, but I couldn't get that to work. I tried using the current-metas, but when I do it doesn't have the 'here-path key. So I'm more or less in the same boat. :)
from pollen-users.
Thank you, @McSackeri
I think it would be possible to have this inside pollen.rkt, but that metas would need to be passed from the template as an argument. I will need to have pages in sub-directories for multiple page templates, so it would be more DRY to have the code once inside the .rkt file rather than in every template file that needs it. However for the timebeing that's not essential, as I just would like to get this working in the next two weeks for a presentation I'm making using this content. (Part of the job of this project is building slides for revealjs, by the way.)
Therefore I'm ploughing on with having the code inside template.html.p just to try to get it working, even though my eventual goal is to have it working inside pollen.rkt. I have got something to work, but it's still not functional.
◊(define here-path (hash-ref metas 'here-path))
◊(local-require racket/path)
◊(define here-path-relative (find-relative-path **(current-project-root) here-path)**)
◊(define here-path-pagenode (string->symbol (path->string here-path-relative)))
◊(define next-path-pagenode (next here-path-pagenode))
The results from the rendered html file:
- here-path V:\myAppFolder\content\temp1.html.pm.
- current-project-root V:\myAppFolder\content\
- here-path-relative temp1.html.pm
- here-path-pagenode temp1.html.pm
- next-path-pagenode
So it seems to be working down as far as next-path-pagenode, which just returns nothing at all.
For the record, (next here)
returns temp2.html, so there is actually a next page in the pagetree. Another note is that these two temp.html.pm files are in the project root, but the same results are returned from pages in subfolders, except that the ones in subfolders return nothing for (next here)
, so trying to get this working with files in the root folder first seemed like the logical thing to do.
from pollen-users.
Ok, so after down and back up the rabbit hole, I think I found an ugly, but workable hack. I'm actually not sure if we're trying to do the same thing, but our symptoms are very similar. It seems that the navigation for the pagetree really wants to work from one location on the site, not from multiple subfolders. So when I put subfolder names in the root index.ptree, here, (previous here), and (next here) return values the way you expect them. But the problem is if you're in a page rendered from a subfolder, they keep the subfolder name, so you can't actually use them to navigate because they try to take you to yet another subfolder of the same name (ie if you're in "folder/filename.html", (next here) will return "folder/filename2.html" and your link will look like "folder/folder/filename2.html").
But if you don't put them in your root directory pagetree, and instead put them in a separate pagetree in the subfolder, the navigation tags won't work. The function "here" will return "folder/filename.html", but (previous here) and (next here) return nothing.
Anyway after trying a number of things, this actually works pretty well in the template file:
◊(local-require racket/path)
◊(define heer (file-name-from-path (symbol->string here)))
Then you can replace "here" with "heer" like so:
<a href="◊|(previous heer)|">◊|(previous heer)|</a> <br/>
<a href="◊|(next heer)|">◊|(next heer)|</a> <br/>
Literally all I'm doing is extracting the file name without the folder from "here" and using it as a pagenode for the "previous", and "next" functions which gets them to see the correct nodes in the subfolder pagetree. There's probably a better way to do this, but I'm still a Racket/Pollen novice, and it's the best my brain can handle at this point. :)
from pollen-users.
PS. The splice-subdir
macro actually checks for the presence of another index.ptree
in each subdirectory and hoists it into the top-level index.ptree
by looking at its doc
export. That way, I get the benefit of index.ptree
in each subdirectory for ordering the pages, but all the navigation is computed from the top-level index.ptree
.
from pollen-users.
I am really grateful for the help on this. I am genuinely inspired and motivated to learn Racket properly so that I don't any longer feel feel that I'm just poking around with stuff I don't really understand.
This morning I methodically tried to work this out and found something related to using Pollen on Windows. What I discovered was, as far as I can tell, that pollen converts a forward slash to a backslash for here
, but for previous here
and other expressions, the forward slashes are not converted, the pagenode isn't found, and the expression returns nothing.
Here is how I discovered this, with a minimal working example. The ptree is this:
#lang pollen
1.html
◊2.html{
sub/3.html
sub/4.html
}
The relevant part of the template is this:
◊(define parent-page (parent here))
◊(define previous-page (previous here))
◊(define next-page (next here))
<div class="pollen-info">
<ul>
<li>The current page is called ◊|here|.</li>
<li>The previous is ◊|(previous here)|.</li>
<li>The next is ◊|(next here)|.</li>
</ul>
</div>
Everything works perfectly for 1.html and 2.html. In 2.html, the next page list item appears like so: sub/3.html.
Note the forward slash.
In 3.html, the current page list item is rendered sub\3.html
. Note the backslash.
When I define a new variable real-here
and use that in the template instead, previous and next work as expected.
(define real-here (regexp-replace* #rx"[\\]" (symbol->string here) "/"))
It was only later in the day that it struck me, I'm so used to using forward slashes to indicate directories on anything server-related that I remembered, I'm using a Windows server. Changed the forward slashes to backslashes in the pagetree, and it all works fine right out of the box, without the need for a new real-here
definition.
Finding this bug in my program has been a very fruitful learning journey for me, but it's cost a lot of hours and I wonder if there is a way to help other Windows users from running into this problem. Perhaps a small addendum at the 'flat.ptree' example (with facts/brennan) to use backslashes on Windows.
from pollen-users.
I concede I don’t work on Windows much — and I detest all filesystem programming, though files, we need ’em, right? — so I’m not averse to clarifications for Windows users. But yes, handling slash vs. backslash is part of the “simple, consistent convention for handling paths in your project” that you’d need to decide upfront.
As for the flat.ptree
file, you should do it however you want. My intuition is that because the pagetree represents an “output” view of the world, it should probably reflect the path conventions on output. So if the project targets HTML, it makes sense to use HTML-style forward slashes. And handle the conversion from a platform path to an HTML path elsewhere. (This would have the added benefit of making the project portable between platforms, since nothing is Windows-centric.)
As for this:
(define real-here (regexp-replace* #rx"[\\]" (symbol->string here) "/"))
We’ve all done it, but processing path-like things with regex patterns can go very wrong. Racket has a set of path-manipulation functions that take care of the underlying suffering housekeeping.
from pollen-users.
processing path-like things with regex patterns can go very wrong.
That's a very good point about not using the wrong tool for the job.
After a lot of fiddling with those path-manipulation functions, I decided to stick with backslashes, since that's what is working out of the box with next here
and friends. Also, backslashes is what I see returned with parameters like current directory, and so sticking with that feels more like going with the flow.
from pollen-users.
Related Issues (20)
- render index.ptree with subdirectories changes directory (though not project root) HOT 8
- Is parallel mode known to crash a lot? HOT 1
- decode-elements with decode-paragraphs inserts spurious <p> when nesting lists? HOT 2
- multiple text arguments? HOT 5
- serialising txexprs? HOT 2
- Beautiful Racket Racket docs HOT 1
- Classic tangle/weave support a la org/babel-mode HOT 2
- Add source tag to default block-tags HOT 3
- Importing text from other sources HOT 2
- One source file → multiple outputs of same type? HOT 6
- Having a hard time with maps HOT 4
- Metadata on pagenodes (?) / how to render link traversal HOT 5
- Filling templates multiple times, à la mail-merge -- maybe a non-use case? HOT 3
- Inserting html comment with pollen command HOT 4
- splitf-txexpr: how to use the resulting txexpr HOT 2
- Windows: Set Pollen environment variable HOT 2
- execute shell command via preprocessor?
- Mildy Dynamic Websites
- opinions sought: costs & benefits of switching to self-hosted Git server? HOT 17
- Could not find MANIFEST for package source HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pollen-users.