I'm very new to Vapor and backend logic in general. I'm building a simple web app with Leaf and I'm trying to read data from a psql database and display them in a html/css (leaf) page. The problem is that when I pass my parameters to the page, it doesn't load the css and the images.
This is the function in my controller
my project configuration:
App
├── Package.swift
├── Resources
│ ├── Views
│ │ └── index.leaf
├── Public
│ ├── images (images resources)
│ ├── styles (css resources)
└── Sources
├── App
├── Controllers
│ └── PoesiaController.swift
├── Models
└── Poesia.swift
final class PoesiaController {
func createView(_ req: Request) throws -> Future<View> {
let id: Int = try req.parameters.next(Int.self)
return Poesia.find(id, on: req).unwrap(or: NSError(domain: "errore", code: 1, userInfo: nil)).flatMap(to: View.self) { p in
return try req.view().render("index", ["title": p.title, "content":p.content])
}
}
}
and I created a route as
let poesieController = PoesiaController()
router.get("poesia", Int.parameter, use: poesieController.createView)
when I run the page has the correct data but no css or images are loaded.
my index.leaf file
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Long+Cang&display=swap" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<link rel="stylesheet" href="styles/poesie.css">
</head>
<body>
<!--Frontpage image with overlay-->
<div class="container">
<img class="frontpage" id= 'frontpage' src="images/alle-scoperte.jpg"/>
<div class="overlay"></div>
</div>
<!--Sticky Title with overlay-->
<div class="title">
<div class="sticky" style="background-image: url('images/alle-scoperte.jpg'); background-position: center bottom; background-size: cover;">
<span id="titleText">#(title)</span>
<img class="nav" src="images/icons/menu.png" onclick="openMenu()" />
<div class="menu">
<img src="images/icons/home.png">
<img src="images/icons/poesie.png">
<img src="images/icons/lib.png">
<img src="images/icons/collab.png">
<img src="images/icons/book.png">
<img src="images/icons/chem.png">
</div>
</div>
</div>
<!--Three Columns, left and right for author notes and center for text-->
<div class="row">
<div id="column_left" class="column">
<div id="note1" class="note">
<span class="left">Conoscere una persona significa aprirsi ad un mondo.</span>
</div>
<div id="note2" class="note">
<span class="left">Tutto racchiuso nell'unicità dei primi incontri.</span>
</div>
</div>
<div id="column_center" class="column">
<div class= "content">
<div class="sheet">
#(content)
</div>
<div class='hint'>
<div id = "rotate">
<img src="images/icons/rotate.png">
</div>
Ruota il dispositivo per vedere il commento.
</div>
</div>
</div>
<div id="column_right" class="column">
<div id="note3" class="note">
<span class="right">Una terra nuova da scoprire attraverso la curiosità ed il piacere.</span>
</div>
<div id="note4" class="note">
<span class="right">Commento</span>
</div>
</div>
</div>
<div class="footer">
©Luis Claudio Pantaleone | Designed and Developed by Simone Deriu | Credits
</div>
</body>
<script src="js/jquery-3.4.1.min.js"></script>
<script src="js/main.js"></script>
</html>
the strange thing is that if i create a route to display the page without variables, or outside the object mapping, it shows normally.
router.get("index") {req -> Future<View> in
return try req.view().render("index")
}
UPDATE: I find out that the problem is rendering a leaf page in call with parameters. If I try to render a page using a route without parameters it works but if I do the same thing inside a route with parameters it doesn't load css and images.
Your problem is due to you missing out the /
at the beginning of the href
in the <link>
tag. It should be:
<link rel="stylesheet" href="/styles/poesie.css">
Omitting the '/' means that the path is relative to the URL. This is why it works for your index page and not the others. Putting it in ensures it treats it as an absolute path.