django webpack loader setting to load css - django

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?

Related

How to include HTML partials using Vite?

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

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.

How can I pass a variable via jinja to a litelement?

I'm using flask to serve this html file. It is using jinja to display the provided data from flask. I can tell that the data is there, but I'm not sure how to pass it to my lit element.
<head>
<meta charset="utf-8">
<title>title</title>
<script type="module" src="{{ bundle }}"></script>
<script>
var data = {{ data|tojson }};
</script>
</head>
<body>
User: {{ data.user }}
<app-home .user="${data.user}" ></app-home>
</body>
</html>
The jinja code User: {{ data.user }}, works as expected.
But, in the litelement (AppHome), user is undefined.
I tried a few different variations on the formatting like .user="{{data.user}}", but I haven't been successful in passing the data to the litelement.
Edit to add lit code
import { html, LitElement, property, customElement } from 'lit-element/lit-element.js';
#customElement('app-home')
export class AppHome extends LitElement {
#property({type: String}) user?: string;
render() {
return html`
<p>user: ${this.user}</p>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'app-home': AppHome;
}
}
The litelement works as expected, and can even render the user if I fetch it separately.

Can't use vue.js from django

I introduced vuejs using webpack in django, but I can not use vue instances from django templates.
Looking at the chrome devtool, the transpiled js is loaded correctly, but shows {{message}}.
The following message is output on the console of chrome devtool.
TypeError: undefined is not an object (evaluating 'hasOwnProperty.call (it, key)')
ReferenceError: Can't find variable: Vue
This is my code.
main.js
import Vue from 'vue'
import App from './App.vue'
import vuetify from '#/plugins/vuetify' // path to vuetify export
window.Vue = require('vue');
Vue.config.productionTip = false
new Vue({
render: h => h(App),
vuetify,
}).$mount('#app')
html
{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Example</title>
</head>
<body>
{% verbatim %}
<div id="app">
{{ message }}
</div>
{% endverbatim %}
{% render_bundle 'main' %}
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</body>
</html>
log(django)
django | [09/Jan/2020 11:22:58] "GET /vue/ HTTP/1.1" 200 374
django | [09/Jan/2020 11:22:58] "GET /static/webpack_bundles/main-ccb1054f18bba9ee992d.js HTTP/1.1" 304 0
urls.py
from django.urls import path
from .views import signupfunc, loginfunc, listfunc, logoutfunc, vuefunc
urlpatterns = [
path('signup/', signupfunc, name='signup'),
path('login/', loginfunc, name='login'),
path('list/', listfunc, name='list'),
path('logout/', logoutfunc, name='logout'),
path('vue/', vuefunc, name='vue'),
]
vies.py
<snip>
def vuefunc(request):
return render(request, 'vue.html')
This might be a dumb question, but are you importing your main.js file from your template? It would look something like this:
<script src="{% static 'js/main.js' %}"></script>
Also, just as an aside, I use Vue with django and always list my own delimiter in the Vue code so I don't have to put {% verbatim %} tags around every variable. It looks something like this:
var app = new Vue({
el: '#app',
delimiters: ['${', '}'],
data: {
message: 'Hello Vue!'
}
})
and you can obviously pick whichever delimiters you want.

Django template is not rendering vuejs components even if vue js files are injected

I am trying to inject vuejs components inside my django's base template, but unfortunately, the components are not getting rendered. Even though necessary vuejs js files are there.
So, I am injecting the vuejs build's files app.js, manifest.js and vendor.js inside base.html (django template). I created a vuejs component named article-list in ArticleList.vue file.
The problem is inside django's template, I am not being able to access this component. It is rather rendered as html tag inside template. The files are given below:
base.html:
<body>
<header>
{% include 'backend/nav.html' %}
</header>
<div id="app">
{% block content %}
{# Use this block for loading CONTENT files from other html files which extend this base.html #}
{% endblock content %}
</div>
<footer>
{% include 'backend/footer.html' %}
</footer>
<script src="{% static 'dist/js/app.js' %}" async></script>
<script src="{% static 'dist/js/manifest.js' %}" async></script>
<script src="{% static 'dist/js/vendor.js' %}" async></script>
{% block js %}
{# Use this block for loading JS files from other html files which extend this base.html #}
{% endblock js %}
</body>
home.html:
{% extends "backend/base.html" %}
{% block title %}Home{% endblock title %}
{% block content %}
<h3>Vue Js component Below:</h3>
<article-list>
</article-list> {# NOT GETTING RENDERED#}
{% endblock content %}
App.vue:
<template>
<div>
hello world
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld'
import ArticleList from './components/blog/ArticleList'
export default {
components: {
HelloWorld,
ArticleList,
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
</style>
ArticleList.vue:
<template>
<div class="hello">
TEST from vue
</div>
</template>
<script>
export default {
name: 'article-list',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
Thanks in advance.
You need to add context processors in Django to add and compile VueJS bundle in static directory.
One way of doing this could be using webpack-loader for django and create corresponding bundles through webpack and then passing config to webpack-loader.