Gulp: How to compile multiple .pug files into several index.html files inside folders - gulp

I'm learning to use gulp and I decided to use pug for writing all my html.
The thing is that have this folder structure:
src/pug
├── base
│   ├── mixins.pug
│   └── variables.pug
├── components
│   ├── footer.pug
│   ├── header.pug
│   ├── head.pug
│   └── template.pug
├── index.pug
└── views
└── about.pug
And I want gulp to ignore all files that are not index.html and all my files inside the views folder.
I'm doing that using this configuration:
function compilePug() {
return src(['./src/pug/index.pug','./src/pug/views/*.pug'], {base: './src/pug/'})
.pipe(pug().on("error", console.log))
.pipe(
pug({
// Your options in here.
})
)
.pipe(dest('./dist/'));
};
The thing is, that's creating and output like this dist/views/about.html.
But I rather generate something like this dist/about/index.html.That way I can navigate between multiple pages without having a route with the .html extension at the end.
Is that possible?

I've written an npm module that does this: gulp-url-builder.
First, move your index.pug into your views directory. Everything you want to render as a page should go in there. Don't forget to adjust any extends path to your template.
src/pug
├── base
│ ├── mixins.pug
│ └── variables.pug
├── components
│ ├── footer.pug
│ ├── header.pug
│ ├── head.pug
│ └── template.pug
└── views
├── about.pug
└── index.pug
After you've installed in required the url builder module in your gulpfile, you can modify your compilePug() function to look something like this:
const { src, dest, series, parallel, watch } = require('gulp')
const pug = require('gulp-pug')
const urlBuilder = require('gulp-url-builder')
function compilePug() {
return src([
'./src/pug/views/*.pug'
]).pipe( pug() )
.pipe( urlBuilder() )
.pipe( dest('dist') )
}
This will output html files based on this pattern (note that underscores can be used for nested pages):
src/pug/views/index.pug --> dist/index.html
src/pug/views/about.pug --> dist/about/index.html
src/pug/views/foo-bar.pug --> dist/foo-bar/index.html
src/pug/views/blog.pug --> dist/blog/index.html
src/pug/views/blog_my-post.pug --> dist/blog/my-post/index.html

Related

Why is my image specified by img src not shown on my webpage?

I'm setting up pages on my personal website(hugo academics by wowchemy) and here is the structure of one of the folders I have:
.
├── ABF.md
├── EXE.md
├── Figures
│ ├── sampling.gif
│ └── sampling_compressed.gif
├── HREMD.md
├── MetaD.md
├── REUS.md
├── TREMD.md
├── US.md
├── _index.md
├── alchemical_MetaD.md
├── appendix.md
├── intro.md
└── test.gif
In _index.md, I have the following lines to read in a GIF file:
<center>
<img src="Figures/sampling_compressed.gif">
</center>
In intro.md, which is in the same folder as _index.md, I also have the same lines to read in the same GIF file. However, in localhost, the GIF file is shown in the page made by _index.md, but not the one built by intro.md. How can I solve the problem and why is this happening? Thanks in advance!
Your assumptions about the output structure are wrong. Hugo builds _index.md in the root of you folder, while the intro.md file (when processed with pretty URL's) is built in a subfolder: intro/index.html.
That being said... I tested your setup and an image in a Section directory (which is a directory with an _index.md file) is not processed by default. I would solve this by moving the image to the static directory so you can reference it from any file in the same way (with an absolute path), especially because this image does not belong to just one page.
If it WERE to be used by just one page, you could have turned the intro.md into intro/index.md and make that directory a Page bundle in which you could put your image and reference it by using the resources variable.

Vue // How to point to assets folder from js method?

I have a vue project generated by vue-cli v3 and I'm trying to provide custom markers for markerclustererplus v3, but it won't work!
I've placed "m" folder containing all m{1-5}.png images and provided imagePath option to MarkerClusterer imagePath: "/assets/m/m" but all I get is icon representing failed image loading. Icons have a path that seems to be correct, http://localhost:8080/assets/m/m2.png
So far I've tried to move "m" folder to public and components folder, but it doesn't work either. It also doesn't help if I open http://localhost:8080/assets/m folder or files in it from the browser address bar. I also do not see any images at the source tab of the browser.
UPDATE:
According to markerclustererplus documentation imagePath property is a string which is:
The full URL of the root name of the group of image files to use for cluster icons. The complete file name is of the form imagePathn.imageExtension where n is the image file number (1, 2, etc.). The default value is MarkerClusterer.IMAGE_PATH.
So I can't just use require('/folder_path/'), because I'm not calling exact .png that is needed for certain Cluster type and I can't pass Array of images to imagePath property, because it's a string.
Here's my src directory tree:
.
├── App.vue
├── api.js
├── assets
│   ├── logo.png
│   └── m
│   ├── m1.png
│   ├── m2.png
│   ├── m3.png
│   ├── m4.png
│   └── m5.png
├── components
│   ├── google-map.vue
│   └── side-bar.vue
├── dummyData.js
└── main.js
I'm passing imagePath: "/assets/m/m" option to MarkerClusterer in google-map.vue file, it results in <img src="/assets/m/m2.png"> element in browser.
To refer file from assets folder use #. Your image path, should look like this:
<img src="#/assets/m/m2.png">
The way that worked for me is to put the images in a folder in the /public directory, then set the imagePath to that folder. So you'd have:
public
map-cluster-images
m1.png
m2.png
m3.png
.....
And then when you initiate the MarkerClusterer:
imagePath: '/map-cluster-images/m'

How to get specific folder and copy its content to another one with gulp

Here is what I need to do: for example, I have such directory structure:
├── libs
│ ├── folder1
│ ├── font
│ ├── font_name_1
│ ├── folder2
│ ├── fonts
│ ├── font_name_2
│ ├── font_name_3
Is there some possibility to get font/fonts folders content (just content, without parent directories) and move it to another folder?
Something like this:
var build = gulp.src(['app/libs/**/font/**/*.*', 'app/libs/**/fonts/**/*.*'])
.pipe(gulp.dest('dist/fonts')) but I need to grab only those directories, that are inside of font or fonts directories
Result structure that I need to get:
├── fonts
│ ├── font_name_1
│ ├── font_name_2
│ ├── font_name_3

HTML import: CustomTag not registered

I'm trying to create a custom element from polymer-element, but I cannot make the #CustomTag work. My dart file (my_element.dart) looks like this:
#HtmlImport('my_element.html')
library projects.projectFolder.layout;
import 'package:polymer/polymer.dart';
import 'dart:html';
#CustomTag('my-element')
class MyElement extends PolymerElement {
#published String caption;
MyElement.created() : super.created();
}
My html file (my_element.html) looks like this:
<link rel="import" href="../../../../packages/polymer/polymer.html">
<polymer-element name="my-element">
<template>
<link rel="stylesheet" href="my_element.css">
<core-toolbar>
<h1>{{ caption }}</h1>
</core-toolbar>
</template>
<script type="application/dart" src="../my_element.dart"></script>
</polymer-element>
The thing is that the Chrome console keeps on printing the following error:
No elements registered in a while, but still waiting on 1 elements to be registered. Check that you have a class with an #CustomTag annotation for each of the following tags: 'my-element'.
It's curious, because I have declared the custom tag as it should be. It looks like it hasn't read the .dart file when it reaches the .html.
The .html file is called from another parent .html file. I think that the order in which the files are called could be the problem, but then again if Dart is compiled before running, it shouldn't care.
I have tried several solutions but none of them have worked. The only one that worked is pretty dirty one, which is importing the my_element.dart file straight from the main my_app.dart file. I guess it shouldn't be done that way because that would mean to import every single my_element.dart file in the same main my_app.dart.
EDIT (add index.html, pubspec.yml)
My index.html file looks like following:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>My app</title>
</head>
<body unresolved fullbleed>
<my-app></my-app>
<script type="application/dart">
import 'package:polymer/polymer.dart';
import 'package:project/my_app.dart';
main() => initPolymer();
</script>
</body>
</html>
my_app is another custom element, which is the main element where all the others go. In other words, it is like the main controller for the app. This element has a .dart and .html file as well, which will call other elements like my-element.
As you can see, my main() function is very simple, since it only init Polymer (see index.html).
My pubspec.yml looks like following:
name: project
version: 0.0.1
description: Some project.
author: Tomas
homepage: https://github.com/*******
environment:
sdk: '>=1.10.0 <2.0.0'
dependencies:
polymer: '^0.16.0'
core_elements: '^0.7.1'
paper_elements: '^0.7.1'
route_hierarchical: "^0.6.1"
transformers:
- polymer:
entry_points: web/index.html
- $dart2js:
$include: "**/*.polymer.bootstrap.dart"
My directory looks like this (I just show a fraction of it, the important one I hope):
.
├── README.md
├── build
│   └── web
│   ├── index.html
│   ├── index.html.polymer.bootstrap.dart.js
│   └── packages
├── lib
│   ├── my_app.dart
│   └── src
│   ├── elements
│   ├── layout
│   │   ├── my_element.css
│   │   ├── my_element.dart
│   │   └── my_element.html
│   ├── my_app.css
│   ├── my_app.html
│   └── modules
│   └── module.dart
│   ├── my_app.css
├── pubspec.lock
├── pubspec.yaml
└── web
│ ├── index.html
│ └── packages -> ../packages
│   ├── my_app.html
│   └── modules
│   └── module.dart
I hope that this edit doesn't confuse more than it should. I'm just looking to know which is the correct folder structure and import form of a Dart app.
In short terms: how should the tree look like when programming a big application in dart, and where should I do the imports? I have look at every documentation I could, including some tutorials, but all of them talk about very simple examples where the big part of the code is in the web folder, which I wouldn't want.
EDIT (summarize and rephrase, add my_app.html and my_app.dart)
In fewer words:
I've a custom element defined by my_element.html and my_element.dart (defined above in this answer) and I want to import it into another my_app element using only the html. I.e. not by importing my_element.dart in my_app.dart, but by only importing my_element.html using a link tag in my_app.html:
<link rel="import" href="../../../packages/polymer/polymer.html">
<link rel="import" href="layout/my_element.html">
<polymer-element name="my-app">
<template>
<core-scaffold id="scaffold">
<my-element tool flex></my-element>
<main fit></main>
</core-scaffold>
</template>
<script type="application/dart" src="../my_app.dart"></script>
</polymer-element>
my_app.dart:
#HtmlImport('src/my_app.html')
import 'package:polymer/polymer.dart';
import 'package:core_elements/core_scaffold.dart';
#CustomTag('my-app')
class MyApp extends PolymerElement {
MyApp.created() : super.created();
}
Shouldn't the <script type="application/dart" src="../my_element.dart"></script> be enough to tell the compiler to load that dart file for registering the element tag by following the transitive dependence defined by the html import?
You need to import all your custom component Dart classes in your my_app.dart. Typically you'd create a single Dart file to import, which would export each entry so that your my_app.dart stays clean.

Jekyll multidirectory website

I'm moving my website to Jekyll since Wordpress is way too bloated and far from easy to use for a simple blog+portfolio. I am then facing a problem which I could not solve looking at the documentation (and even the examples, since they are very very simple).
I want to have a site with a landing page at / (ok), a blog on the directory /blog/ and the posts at /blog/post-title/ (ok, I think) and a portfolio with my jobs at /portfolio/ with jobs at /portfolio/job-title/, but I cannot create this last directory.
I tried creating a _jobs dir inside the portfolio dir, and then looping through it with
{% for job in site.jobs %}
...html...
{% endfor %}
Since the blog example uses this same syntax, but with posts instead of jobs. How should I do to access this portfolio/_jobs directory and loop through the files?
The tree of the Jekyll folder is as follows:
.
├── blog
│   ├── index.html
│   └── _posts
│   ├── 2013-02-19-hello-world.markdown
│   └── 2014-03-01-welcome-to-jekyll.markdown
├── _config.yml
├── css
│   ├── main.css
│   └── syntax.css
├── _includes
│   ├── footer.html
│   ├── header.html
│   └── sidebar.html
├── _layouts
│   ├── default.html
│   ├── job.html
│   └── post.html
├── portfolio
│   ├── index.html
│   └── _jobs
│   └── jekyll-portfolio.markdown
Jekyll does not support this as simply as in your example yet, it is coming in 2.0 however.
You could add a key/value pair to the YAML header of the child pages to signify that it should appear on the main portfolio index page. I have a similar setup that I use to define what pages should appear in the main navigation for my site.
The URL customisation for the portfolio pages can only be achieved by using the permalink setting in the YAML header of each child page.
portfolio/jobs/jekyll-portfolio.markdown etc
---
group: jobs
---
portfolio/index.html
<ul>
{% for node in site.pages %}
{% if 'jobs' == node.group %}
<li>{{node.title}}</li>
{% endif %}
{% endfor %}
</ul>
You may be able to avoid requiring the group attribute if you changed the if condition to do substring matching of the URL, but this solution is easier to understand.