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>
Related
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.
the html/template module has a define/template feature that im trying to use to make it easier to change only one file that contains the global base of my website but its not working as intended.
base.html:
{{define "base"}}
<!DOCTYPE html>
<html lang="en">
<body>
{{template "content"}}
</body>
</html>
{{end}}
index.html:
{{template "base"}}
{{define "content"}}
I'm page 1
{{end}}
blog.html:
{{template "base"}}
{{define "content"}}
I'm page 2
{{end}}
I expect to get I'm page 1 when i call index.html and I'm page 2 when i call blog.html but with both files i get I'm page 1 as the output. (i don't know what a dot at the end of template does but all combinations of that don't work aswell).
You cannot redefine and replace templates like that. Do the reverse: define index.html and blog.html as page1 and page2 respectively, import common header.html and footer.html into those.
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?
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
I try to render my page in martini
layout.html
<!DOCTYPE html>
<html lang="en">
<head>...</head>
<header>...</header>
{{ yield }}
<footer>...</footer>
</html>
index.html
<main>
<h1>Hello</h1>
</main>
Render options:
m.Use(render.Renderer(render.Options{
Directory: "templates",
Layout: "layout",
Extensions: []string{".tmpl", ".html"},
Delims: render.Delims{"{[{", "}]}"},
Charset: "UTF-8",
IndentJSON: true,
}))
try show page:
rnd.HTML(200, "edit", nil)
run app and see my page:
All code from layout.html is processed normaly, but the {{ yield }} string stays without difference.
You set your delimiters to "{[{" and "}]}", but then uses "{{" and "}}".
Either use Delims: render.Delims{"{{", "}}"}, or change your template to use {[{ yield }]}