thymeleaf parsing template issues, the path fails to get recognized - spring-boot

I have 2 Root Cause Issues/Errors
org.attoparser.ParseException: Error resolving template [components/folder-list], template might not exist or might not be accessible by any of the configured Template Resolvers (template: "inbox-page" - line 65, col 14)
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [components/folder-list], template might not exist or might not be accessible by any of the configured Template Resolvers (template: "inbox-page" - line 65, col 14)
The bug arised when I converted some .html code and attempted to extract it as a component.
I tried different paths from absolute path to package path; path fails to get recognized regardless.
templates/inbox-page.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Inbox</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We"
crossorigin="anonymous"
/>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj"
crossorigin="anonymous"
></script>
<style>
.container {
display: grid;
grid-template-areas:
"header header header"
"nav content content"
"footer footer footer";
grid-template-columns: 300px 1fr;
grid-template-rows: auto 1fr auto;
grid-gap: 10px;
height: 100vh;
}
header {
grid-area: header;
}
nav {
grid-area: nav;
margin-left: 0.5rem;
}
main {
grid-area: content;
}
footer {
grid-area: footer;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>Welcome, Name</h1>
</header>
<nav>
<div th:insert="components/folder-list :: folder-list (panelName = 'Folders', folders = ${defaultFolders})" ></div>
<div th:insert="components/folder-list :: folder-list (panelName = 'My folders', folders = ${userFolders})"></div>
</nav>
<main>
<p> Email LIST</p>
</main>
<footer>
<!-- Footer content -->
</footer>
</div>
</body>
</html>
templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Demo</title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width" />
<base href="/" />
</head>
<body>
<h1>Login</h1>
<div>
With GitHub: click here
</div>
</body>
</html>
components/folder-list.html
<!DOCTYPE html>
<html >
<head>
</head>
<body>
<div th:fragment="folder-list (panelName, folders)">
<div class="card" th:if="${folders}">
<div class="card-header" th:text="${panelName}">Folders</div>
<div class="card-body">
<div class="list-group">
<li
th:each="folder :: ${folders}"
class="list-group-item d-flex justify-content-between align-items-center"
>
<span th:text="${folder.label}">Folder</span>
<span class="badge bg-primary rounded-pill">15</span>
</li>
</div>
</div>
</body>
</html>
InboxApp.java DriverCode
package io.aharo.inbox;
import io.aharo.inbox.folders.Folder;
import io.aharo.inbox.folders.FolderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.cassandra.CqlSessionBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
import java.nio.file.Path;
#SpringBootApplication
#RestController
public class InboxApp
{
#Autowired
private FolderRepository folderRepository;
public static void main(String[] args) {
SpringApplication.run(InboxApp.class, args);
// System.out.println(folderRepository);
// FolderRepository fr = new FolderRepository("aharo", "idk", "red");
}
/**
* This is neccesary for the Spring Boot App to use the Astra secure bundle
* && connect to our database.
*/
#Bean
public CqlSessionBuilderCustomizer sessionBuilderCustomizer (DataStaxAstraProperties astraProperties)
{
Path bundle = astraProperties.getSecureConnectBundle().toPath();
return builder -> builder.withCloudSecureConnectBundle(bundle);
}
#PostConstruct
public void init()
{
folderRepository.save( new Folder("aharo","Inbox", "blue"));
folderRepository.save( new Folder("aharo","Sent", "green"));
folderRepository.save( new Folder("aharo","Important", "yellow "));
}
// #RequestMapping("/user")
// public String user(#AuthenticationPrincipal OAuth2User principal) {
// System.out.println(principal);
// return principal.getAttribute("name");
// }
}
Environment Tree
I am unable to show pictures but my projects work tree environment looks like this.
.
├── mvnw
├── mvnw.cmd
├── pom.xml
├── README.md
├── src
│ └── main
│ ├── java
│ │ └── io
│ │ └── aharo
│ │ └── inbox
│ │ ├── controllers
│ │ │ └── InboxController.java
│ │ ├── DataStaxAstraProperties.java
│ │ ├── folders
│ │ │ ├── Folder.java
│ │ │ ├── FolderRepository.java
│ │ │ └── FolderService.java
│ │ ├── InboxApp.java
│ │ └── SecurityAdapter.java
│ └── resources
│ ├── application.yml
│ ├── components
│ │ └── folder-list.html
│ ├── META-INF
│ │ └── additional-spring-configuration-metadata.json
│ ├── secure-connect.zip
│ └── templates
│ ├── inbox-page.html
│ └── index.html
└── target
├── classes
│ ├── application.yml
│ ├── components
│ │ └── folder-list.html
│ ├── io
│ │ └── aharo
│ │ └── inbox
│ │ ├── controllers
│ │ │ └── InboxController.class
│ │ ├── DataStaxAstraProperties.class
│ │ ├── folders
│ │ │ ├── Folder.class
│ │ │ ├── FolderRepository.class
│ │ │ └── FolderService.class
│ │ ├── InboxApp.class
│ │ └── SecurityAdapter.class
│ ├── META-INF
│ │ └── additional-spring-configuration-metadata.json
│ ├── secure-connect.zip
│ └── templates
│ ├── inbox-page.html
│ └── index.html
├── generated-sources
│ └── annotations
├── maven-status
│ └── maven-compiler-plugin
│ └── compile
│ └── default-compile
OLD CODE
templates/inbox-page.html old but works.
If we swap the new inbox-page.html with this old code, it will work but what I want is to convert it as a component.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Inbox</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We"
crossorigin="anonymous"
/>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj"
crossorigin="anonymous"
></script>
<style>
.container {
display: grid;
grid-template-areas:
"header header header"
"nav content content"
"footer footer footer";
grid-template-columns: 300px 1fr;
grid-template-rows: auto 1fr auto;
grid-gap: 10px;
height: 100vh;
}
header {
grid-area: header;
}
nav {
grid-area: nav;
margin-left: 0.5rem;
}
main {
grid-area: content;
}
footer {
grid-area: footer;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>Welcome, Name</h1>
</header>
<nav>
<div class="card">
<div class="card-header">defaultFolders</div>
<div class="card-body">
<ul class="list-group">
<li
th:each="folder : ${defaultFolders}"
class="list-group-item d-flex justify-content-between align-items-center"
>
TMP
<span th:text="${folder.label}"> Label</span>
<span class="badge bg-primary rounded-pill">69</span>
</li>
</ul>
</div>
<div class="card"
th:if="${userFolders}">
<div class="card-header">userFolders</div>
<div class="card-body">
<ul class="list-group">
<li
th:each="folder : ${defaultFolders}"
class="list-group-item d-flex justify-content-between align-items-center"
>
TMP
<span th:text="${folder.label}"> Label</span>
<span class="badge bg-primary rounded-pill">24</span>
</li>
</ul>
</div>
</nav>
<main>
<div class="card">
<div class="card-header">Inbox</div>
<div class="card-body">
<div class="list-group">
<a
href="#"
class="list-group-item list-group-item-action active"
aria-current="true"
>
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">LIST GROUP</h5>
<small></small>
</div>
<p class="mb-1"></p>
<small></small>
</a>
<a href="#" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">LIST GROUP</h5>
<small class="text-muted"></small>
</div>
<p class="mb-1"></p>
<small class="text-muted"></small>
</a>
<a href="#" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">LIST GROUP</h5>
<small class="text-muted"></small>
</div>
<p class="mb-1"></p>
<small class="text-muted"></small>
</a>
</div>
</div>
</div>
</main>
<footer>
<!-- Footer content -->
</footer>
</div>
</body>
</html>

Move your components folder inside of templates. Thymeleaf searches everything relative to templates.

Related

Golang fiber c.Render layout not excute right template

I'm trying to use one layout with different templates,
├── Main Folder
├── cmd
└── main.go
├── controllers
├── models
├── views
└── partials
└── layout.html
└── index.html
└── dashboard.html
└── login.html
└── public
└── sample.png
In my layout.html, I have
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<h1>Loaded from Layout</h1>
{{ template . }}
</body>
</html>
In my dashboard.html
{{ define "dashboard" }}
<h1>Dashboard</h1>
{{ end }}
In my login.html
{{ define "login" }}
<h1>Login</h1>
{{ end }}
When I'm render dashboard through controller its only load login.html, its take last html file always
// controller
func Dashboard(c *fiber.Ctx) error {
return c.Render("dashboard", fiber.Map{
"title": "Login | Selectify Admin",
}, "partials/layout")
}
In main file I have told where to find views
//main.go
// create a new HTML engine
template_engine := html.New(
"./views",
".html",
)
// create a new Fiber app
app := fiber.New(fiber.Config{
Views: template_engine, // set the views engine
ErrorHandler: func(c *fiber.Ctx, err error) error {
return utils.HandleError(c, err)
},
})
it's giving an error
"template: "partials/layout" is an incomplete or empty template"
How can I send or render correct html file using one layout??
Go version 1.19
fiver version 2
"github.com/gofiber/template/html"
Found the answer,
instead of template we gotta use {{embed}}, then it'll include right temlate which you pass from controller
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<h1>Loaded from Layout</h1>
{{ embed }}
</body>
</html>

Laravel webpack unable to locate Mix file

Trying to use versioning and i get this error .
Unable to locate Mix file: /core/public/css/app.css. (View: C:\laragon\www\project\core\resources\views\master.blade.php)
My webpack.mix.js file
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js').extract(['vue']);
mix.sass('resources/sass/app.scss', 'public/css');
if (mix.inProduction()) {
mix.version();
}
header
<link href="{{ mix('/core/public/css/app.css', '/core/public') }}" rel="preload" as="style"
onload="this.onload=null;this.rel='stylesheet'">
<script src="{{ mix('/core/public/js/manifest.js'), '/core/public'}}"></script>
<script src="{{ mix('/core/public/js/vendor.js'), '/core/public' }}"></script>
<script src="{{ mix('/core/public/js/app.js'), '/core/public' }}"></script>
mix-manifest.json output
{
"/js/app.js": "/js/app.js?id=170c03d22dcc6f5e5936",
"/css/app.css": "/css/app.css?id=3306ee8f312fb58dd115",
"/js/manifest.js": "/js/manifest.js?id=41f053ba9a94d81b39f8",
"/js/vendor.js": "/js/vendor.js?id=cf78339b219ecdecb320"
}
File structure inside project is
core
└───public
│ │ mix-manifest.json
│ │
│ └───js
│ │ app.js
│ │ manifest.js
│ │ vendor.js
│ |
| css
| | app.css
| |
|
|
|
|'''
└───webpack.mix.js
|...
Pointing to the javascript file like that
<script src="{{ mix('/js/app.js') }}"></script>
gives me an error
The Mix manifest does not exist. (View: C:\laragon\www\project\core\resources\views\master.blade.php) (View: C:\laragon\www\project\core\resources\views\master.blade.php)
Trying raw URL instead gives me this error
<script src="/css/app.css"></script>
GET https://project.test/css/app.css net::ERR_ABORTED 404 (Not Found)
The above file is located inside /core/public/css folder and it does not point correct.
This made it work
<link href="{{ mix('css/app.css', 'core/public') }}" rel="preload" as="style"
onload="this.onload=null;this.rel='stylesheet'">
<script src="{{ mix('js/app.js', 'core/public') }}" defer></script>
To explain, the second parameter points to where the mix-manifest.json file exists.
Your problem is that you are adding the root folder to your mix path... Do not do that, it is relative to your root/public...
You should have it like this:
<link href="{{ mix('/css/app.css') }}" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
<script src="{{ mix('/js/manifest.js') }}"></script>
<script src="{{ mix('/js/vendor.js') }}"></script>
<script src="{{ mix('/js/app.js') }}"></script>
Read more about it here

Error when creating 2 vue instances for 2 pages (in project laravel + vuejs)

I want to create 2 vue instances for 2 pages (one for client site and another for admin). But I got error:
[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
(found in )
My code is below:
Concept in folder /resources/js/
.
├── admin
│   ├── admin.js
│   ├── components
│   └── views
│   └── Admin.vue
├── bootstrap.js
├── site
│   ├── components
│   │   └── Product.vue
│   ├── routes.js
│   ├── site.js
│   └── views
│   └── Site.vue
└── views
└── App.vue
admin.js
require('./../bootstrap');
import Admin from './views/Admin.vue';
import VueRouter from 'vue-router';
// import router from './routes.js';
window.Vue = require('vue');
Vue.use(VueRouter);
const adminapp = new Vue({
el: '#adminapp',
components: { Admin }
});
site.js
require('./../bootstrap');
import App from './views/Site.vue';
import VueRouter from 'vue-router';
import router from './routes.js';
window.Vue = require('vue');
Vue.use(VueRouter);
const app = new Vue({
el: '#app',
components: { App },
router
});
admin.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>Admin</title>
</head>
<body>
<div id="adminapp">
<adminapp></adminapp>
</div>
<script src="{{ asset('/js/admin.js') }}"></script>
</body>
</html>
index.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>Site</title>
</head>
<body>
<app id="app"></app>
<script src="{{ asset('/js/site.js') }}"></script>
</body>
</html>
Does anyone know this problem?

golang renderer.HTML not picking javascript file from inside the template

Trying to publish a login page using "github.com/thedevsaddam/renderer" package renderer . Not able to call the .js file from inside the template. When tried inlining javascript it worked fine, but not able to load the .js file.
my file structure is
Project
|
+-main.go
|
+-handlers
| |
| +- routes.go
| |
| +- login.go
+-views
| |
| +- _login.html
| +- login.js
main.go
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
"github.com/higuestssg/handlers"
)
func main() {
router := mux.NewRouter().StrictSlash(true)
// This will serve files under http://localhost:8000/static/<filename>
router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("views/"))))
portalRouter := router.PathPrefix("/portal").Subrouter()
handlers.HandleRoutes(portalRouter)
fmt.Println("listening at localhost:10001")
log.Fatal(http.ListenAndServe(":10001", router))
}
routes.go
package handlers
import (
//"net/http"
"github.com/gorilla/mux"
)
func HandleRoutes(r *mux.Router){
r.HandleFunc("/login", loginHandler)
r.HandleFunc("/healthTest", healthTestHandler)
}
login.go
package handlers
import (
"fmt"
"net/http"
//"github.com/gorilla/mux"
"github.com/thedevsaddam/renderer"
)
var rnd *renderer.Render
func init() {
opts := renderer.Options{
ParseGlobPattern: "./views/*.html",
}
rnd = renderer.New(opts)
}
// loginHandler renders login page
func loginHandler(w http.ResponseWriter, r *http.Request) {
data := struct {
Val1 string
Val2 string
}{
"test100",
"test2",
}
fmt.Println("login page hit")
rnd.HTML(w, http.StatusOK, "_login", data)
}
_login.html
{{ define "_login" }}
<!--
https://medium.com/#thedevsaddam/easy-way-to-render-html-in-go-34575f858026
-->
<!DOCTYPE html>
<html lang="en">
<!-- Bootstrap import CSS-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<body>
<div class="container">
<div class="starter-template jumbotron text-center">
<h1>HI GUEST</h1>
<div class="col-sm-4">
<p class="lead">Welcome to <strong>HI_GUEST --ssg</strong> page</p>
</div>
</div>
</div><!-- /.container -->
<div class="row">
<div class="col-sm-4"><p class="lead" id="idtest1">Test1</p></div>
<div class="col-sm-4"><p class="lead">Test2</p></div>
<div class="col-sm-4"><p class="lead"><button type="button" class="btn btn-info btn-lg" name="btn_ip" id="btn_id" onclick="myFunction()">{{.Val1}}</button></p></div>
</div>
</body>
<script type='text/javascript' src='login.js'></script>
</html>
{{ end }}
login.js
function myFunction()
{
alert("Hello");
}
$(document).ready(function () {
alert("Hello");
});
When checked in chrome using viewSource, when clicked on login.js its showing 404 not found
updated _login.html , its working fine with #mkopriva suggestion
{{ define "_login" }}
<!--
https://medium.com/#thedevsaddam/easy-way-to-render-html-in-go-34575f858026
-->
<!DOCTYPE html>
<html lang="en">
<!-- Bootstrap import CSS-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<body>
<div class="container">
<div class="starter-template jumbotron text-center">
<h1>HI GUEST</h1>
<div class="col-sm-4">
<p class="lead">Welcome to <strong>HI_GUEST --ssg</strong> page</p>
</div>
</div>
</div><!-- /.container -->
<div class="row">
<div class="col-sm-4"><p class="lead" id="idtest1">Test1</p></div>
<div class="col-sm-4"><p class="lead">Test2</p></div>
<div class="col-sm-4"><p class="lead"><button type="button" class="btn btn-info btn-lg" name="btn_ip" id="btn_id" onclick="myFunction()">{{.Val1}}</button></p></div>
</div>
</body>
<script type='text/javascript' src='/static/login.js'></script>
</html>
{{ end }}

How to fix "Uncaught ReferenceError: Vue is not defined at vuetemplatetest.2.html:19"

I try to setup laravel with bootstrap-vue.
npm list --depth 0
/home/<thatsme>/LARAPP/laravel
├── axios#0.18.0
├── bootstrap#4.3.1
├── bootstrap-vue#2.0.0-rc.16
├── cross-env#5.2.0
├── jquery#3.3.1
├── laravel-mix#4.0.15
├── lodash#4.17.11
├── popper.js#1.14.7
├── resolve-url-loader#2.3.2
├── sass#1.17.3
├── sass-loader#7.1.0
├── vue#2.6.10
├── vue-router#3.0.2
└── vue-template-compiler#2.6.10
shows me, that is okay. The intention is to work without the online links.
When i try a test with simple html, i got the error described in topic theme:
<!DOCTYPE html>
<html lang="de">
<head>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>eijo</title>
</head>
<body>
<div id='app'>
<b-table striped hover :items="items" :fields="fields"> </b-table>
</div>
<script>
window.app = new Vue({
el: '#app',
data: { fields: ['first_name', 'last_name', 'age'],
items: [
{ isActive: true, age: 40, first_name: 'Dickerson', last_name: 'Macdonald' },
{ isActive: false, age: 21, first_name: 'Walter', last_name: 'Shaw' },
{ isActive: false, age: 89, first_name: 'Geneva', last_name: 'Wilson' },
{ isActive: true, age: 38, first_name: 'Jami', last_name: 'Carney' }
]
}
}
Edit: in mit app.js is that:
import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue)
// app.js
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Add <script src="https://cdn.jsdelivr.net/npm/vue"></script> at top to your script.
[Edit:]
Saved the problem:
div id="app" class="container"
that was missing in my layout.blade.php

Resources