Search code examples
swiftvaporleaf

Leaf & Vapor 3 - Can't load css and images on view


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&agrave; 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&agrave; ed il piacere.</span>
          </div>
          <div id="note4" class="note">
              <span class="right">Commento</span>
          </div>
      </div>
    </div>

    <div class="footer">
        &copy;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.


Solution

  • 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.