How to include HTML partials using Vite? - templates

Is it possible to include snippets of shared HTML using Vite (vanilla)? I'm looking for a way to have the HTML prerendered without injecting via JS.
Something like:
<html>
<head>
{ include 'meta-tags' }
</head>
<body>
{ include 'nav' }
<h1>Hello World</h1>
<body>
</html>

vite-plugin-handlebars was the solution I was looking for. Partials were super easy to set up with this package:
Setup:
// vite.config.js
import { resolve } from 'path';
import handlebars from 'vite-plugin-handlebars';
export default {
plugins: [
handlebars({
partialDirectory: resolve(__dirname, 'partials'),
}),
],
};
File where you want to include partial:
<!-- index.html -->
{{> header }}
<h1>The Main Page</h1>
Rendered output:
<header>My Website</header>
<h1>The Main Page</h1>

You could use the vite-plugin-html that enables EJS templates in index.html:
// vite.config.js
import { defineConfig } from 'vite'
import { createHtmlPlugin } from 'vite-plugin-html'
export default defineConfig({
plugins: [
createHtmlPlugin({
entry: 'main.js',
/**
* Data that needs to be injected into the index.html ejs template
*/
inject: {
data: {
metaTags: `<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />`,
nav: `<nav>
Google |
Apple
</nav>`,
},
},
}),
],
})
<!-- index.html -->
<html>
<head>
<%- metaTags %>
</head>
<body>
<%- nav %>
<h1>Hello World</h1>
<body>
</html>
demo

Related

Django Rest API complain about swagger version

We are using DJango rest framework to make api. We added swagger page, but its complain about swagger version.
Unable to render this definition
The provided definition does not specify a valid version field.
Please indicate a valid Swagger or OpenAPI version field. Supported version fields are swagger: "2.0" and those that match openapi: 3.0.n (for example, openapi: 3.0.0).
I was following documentation https://www.django-rest-framework.org/topics/documenting-your-api/#a-minimal-example-with-swagger-ui
Below are files.
urls.py
from django.urls import path
urlpatterns = [
...
...
path("openapi", get_schema_view(
title="My api",
description="API for me",
version="1.0.0"
), name="openapi-schema"),
path('swagger-ui/', TemplateView.as_view(
template_name='swagger-ui.html',
extra_context={'schema_url':'openapi-schema'}
), name='swagger-ui')
]
templates/swagger-ui.html
<!DOCTYPE html>
<html>
<head>
<title>Swagger</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="//unpkg.com/swagger-ui-dist#3/swagger-ui.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="//unpkg.com/swagger-ui-dist#3/swagger-ui-bundle.js"></script>
<script>
const ui = SwaggerUIBundle({
url: "{% url schema_url %}",
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
layout: "BaseLayout",
requestInterceptor: (request) => {
request.headers['X-CSRFToken'] = "{{ csrf_token }}"
return request;
}
})
</script>
</body>
</html>
I think, its complaining about version: 1.0.0 mentioned in openapi schema view. But need to sure, if something else is not causing this issue.

How to render Vue with Django

I'm working on a small application using Vue.js and Django on Digitalocean, so I have installed Django Webpack loader and the tracker also, now I have executed my Django server and my vue.js also using npm run serve and when I access to my webpage localhost:8000 I see only a blank page since everything is installed correctly, This is my HTML page ( when I inspect on chrome browser )
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="http://0.0.0.0:8080/js/app.js"></script>
</body>
</html>
PS : i think the problem is in app.js ( because i follow the link and i get an error )
This site can’t be reachedThe webpage at http://0.0.0.0:8080/js/app.js might be temporarily down or it may have moved permanently to a new web address.
ERR_ADDRESS_INVALID
you should config your vue application first creating vue.config.js file.
vue.config.js:
const BundleTracker = require("webpack-bundle-tracker");
module.exports = {
// on Windows you might want to set publicPath: "http://127.0.0.1:8080/"
publicPath: "http://0.0.0.0:8080/",
outputDir: "./dist/",
chainWebpack: (config) => {
config
.plugin("BundleTracker")
.use(BundleTracker, [{ filename: "./webpack-stats.json" }]);
config.output.filename("bundle.js");
config.optimization.splitChunks(false);
config.resolve.alias.set("__STATIC__", "static");
config.devServer
// the first 3 lines of the following code have been added to the configuration
.public("http://127.0.0.1:8080")
.host("127.0.0.1")
.port(8080)
.hotOnly(true)
.watchOptions({ poll: 1000 })
.https(false)
.disableHostCheck(true)
.headers({ "Access-Control-Allow-Origin": ["*"] });
}
// uncomment before executing 'npm run build'
// css: {
// extract: {
// filename: 'bundle.css',
// chunkFilename: 'bundle.css',
// },
// }
};
Then load render_bundle from webpack_loader. Your django template will be like:
{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- This part is in the screenshot at the bottom! -->
<h1>Vue JS</h1>
<div id="app"></div>
{% render_bundle 'app' %}
</body>
</html>
Make Sure you are using webpack-bundle-tracker of version #0.4.3
You can follow this link for step by step tutorial.

Django frontend app not loading React Component

i am following tranversy Media Django-React tutorial. After the server is running ok, but the components in my App.js file are not displayed in the index.html. Kindly help on what could be wrong, all.
This is my project tree:
see the image
Then my app.js
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
class App extends Component {
render() {
return <h1>React App</h1>
}
}
ReactDOM.render(<App />, document.getElementById("app"));
My index.html
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://bootswatch.com/4/cosmo/bootstrap.min.css">
<title>Lead Manager</title>
{%load static%}
</head>
<body>
<h1></h1>
<div id="app"></div>
<script>src="{%static "frontend/main.js"%}"</script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
index.js
import App from './components/App';
webpack.config.js
module.exports = {
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader:"babel-loader"
}
}]
}
}
The backend is working fine using the api.
Change this
<script>src="{%static "frontend/main.js"%}"</script>
to this
<script src="{%static "frontend/main.js"%}"></script>

django webpack loader setting to load css

It works when I set up like below. I am using django-webpack-loader
index.html
{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Jayground</title>
{% render_bundle 'main' 'css' %}
</head>
<body>
<div id="react-app"></div>
{% render_bundle 'main' 'js' %}
</body>
</html>
Header.js
import styles from './header.css';
export default class Header extends React.Component {
render(){
<div className="header">
hello
</div>
}
}
webpack.config.js (I made styles.css separately and then load css file in html separately so that className="header" works.)
config.plugins = config.plugins.concat([
new ExtractTextPlugin('styles.css'),
]);
config.module.rules.push(
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: 'css-loader'
})
}
)
According to what I understood, code below should work too. If I don't separate css file by using ExtractTextWebpackPlugin, bundle js file have css information in it like this.
exports.push([module.i, ".header {\r\n background-color: blue;\r\n}\r\n\r\n.extra {\r\n\tfont-size: 50;\r\n}", ""]);
css should be loaded properly.
Header.js
import styles from './header.css';
export default class Header extends React.Component {
render(){
<div className={styles.header}>
hello
</div>
}
}
webpack.config.js
config.module.rules.push(
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
)
Do I miss something to work properly?

Grails template inheritance

I'm trying to mimic template inheritance as found in Django with a Grails app. I want to be able to define a '_header.gsp' which includes all the shared resources across the app:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>${title}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
%{--Shared Styles--}%
<link rel="stylesheet" href="${resource(dir: 'app/shared/css/bootstrap', file: 'bootstrap.min.css')}" type="text/css">
%{--Shared Libraries--}%
<script src="${resource(dir: 'lib/jquery', file: 'jquery.js')}"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
%{--View-specific styles--}%
<g:each var="style" in="${styles}">
<link rel="stylesheet" href="${style}" type="text/css">
</g:each>
%{--View-specific scripts--}%
<g:each var="include" in="${includes}">
<script src="${include}" type="text/javascript"></script>
</g:each>
For each specific view template I will include this _header.gsp with a dictionary to fill in the view-specific requirements:
<g:render template="/header"
model="[
title:'Alerts',
styles:[
'${resource(dir: "app/stuff/css", file: "other.css")}',
'${resource(dir: "app/stuff/css", file: "second.css")}'
],
includes:[
'${resource(dir: "app/stuff/src/main/js/", file: "app.js")}',
'${resource(dir: "app/stuff/src/main/js/", file: "filters.js")}'
]
]" />
This is not working, and I'm sure my syntax is wrong somewhere. Can you define a '$resource(dir)' path inside of a g:each like I have? Perhaps I need to use g:link? Can this be done with Grails?
It sounds like you just need to use the resources tag. Define your 'resources' in ApplicationResources.groovy. Then, in your layout include the r:layoutResources tag, and finally, in the gsp specify the resource modules you want to include on that page.
In ApplicationResources.groovy
modules = {
application {
dependsOn 'jquery'
resource url: 'css/other.css'
resource url: 'css/second.css'
resource url: 'js/bootstrap.js'
}
charting {
//Charting is dependent on the 'application' resource module above,
// so it will include everything from the application and the
// charting css and js.
dependsOn 'application'
resource url: 'css/chart.css'
resource url: 'js/pie-chart.js'
}
reports {
//Completely separate so there is no dependsOn.
// Like 'application' module, it will only include the resources below.
resource url: 'css/pdf.css'
resource url: 'js/interactive-report.js'
}
}
In the /grails-app/layouts/main.gsp
<head>
...
<r:layoutResources />
</head>
<body>
...
<r:layoutResources />
</body>
In the /grails-app/views/someDomain/
list.gsp
<head>
...
<r:require modules="application" />
</head>
<body>
...
</body>
report.gsp
<head>
...
<r:require modules="reports" />
</head>
<body>
...
</body>
charts.gsp
<head>
...
<r:require modules="charting" />
</head>
<body>
...
</body>