@caweb/cli 1.15.16 → 1.15.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -38,12 +38,13 @@ export default async function genScripts({
38
38
  "caweb": "caweb",
39
39
  "create-site": "caweb create-site",
40
40
  "serve": "caweb serve",
41
+ "serve:no-audit": "caweb serve --no-audit --no-jshint --no-a11y",
41
42
  "build": "caweb build",
42
43
  "convert-site": "caweb convert-site",
43
44
  "launch": "caweb launch",
44
45
  "launch:multi": "caweb launch --multisite",
45
46
  "launch:multi:subdomain": "caweb launch --multisite --subdomain",
46
- "launch:sync": "caweb launch --sync --update",
47
+ "launch:sync": "caweb launch --sync",
47
48
  "launch:update": "caweb launch --update",
48
49
  "stop": "caweb stop",
49
50
  "shutdown": "caweb destroy",
@@ -623,6 +623,13 @@ function generateShortcodes( mainContent, opts = {
623
623
  // all theses elements can go in other modules
624
624
  // they also need to be added to the allowedModules list
625
625
  case 'a':
626
+ // if the element first child is an image
627
+ if( content[0] && content[0].rawTagName === 'img' ) {
628
+ // add the anchors attributes to the image
629
+ content[0].rawAttrs = content[0].rawAttrs + ' ' + rawAttrs;
630
+ output += generateModuleShortcode('image', content[0] );
631
+ break;
632
+ }
626
633
  case 'b':
627
634
  case 'p':
628
635
  case 'ol':
@@ -809,17 +816,20 @@ function generateModuleShortcode(module, element ){
809
816
  let attrs = {};
810
817
  let moduleName = 'et_pb_' + module;
811
818
 
819
+ // commonly named attributes can be declared here to avoid repetition
820
+ let header, title, img;
821
+
812
822
  switch( module ) {
813
- case 'blurb': {
823
+ case 'blurb':
814
824
  /**
815
825
  * if blurb module is requested
816
826
  * we try and make the shortcode as if the element
817
827
  * was made with a Card Component
818
828
  */
819
829
 
820
- let header = element.querySelector('.card-header');
821
- let title = element.querySelector('.card-title');
822
- let img = element.children.filter( c => c.tagName.toLowerCase() === 'img' );
830
+ header = element.querySelector('.card-header');
831
+ title = element.querySelector('.card-title');
832
+ img = element.children.filter( c => c.tagName.toLowerCase() === 'img' );
823
833
 
824
834
  content = element.querySelector('.card-body');
825
835
 
@@ -887,14 +897,14 @@ function generateModuleShortcode(module, element ){
887
897
  }
888
898
  }
889
899
  break;
890
- }
891
- case 'ca_card': {
900
+
901
+ case 'ca_card':
892
902
  /**
893
903
  * if card module is requested
894
904
  */
895
- let header = element.querySelector('.card-header');
896
- let title = element.querySelector('.card-title');
897
- let img = element.children.filter( c => c.tagName.toLowerCase() === 'img' );
905
+ header = element.querySelector('.card-header');
906
+ title = element.querySelector('.card-title');
907
+ img = element.children.filter( c => c.tagName.toLowerCase() === 'img' );
898
908
  let layout = element.classList.toString().match(/card-(\w+)/g)[0].replace('card-', '');
899
909
 
900
910
  content = element.querySelector('.card-body');
@@ -962,8 +972,8 @@ function generateModuleShortcode(module, element ){
962
972
  }
963
973
  }
964
974
  break;
965
- }
966
- case 'heading': {
975
+
976
+ case 'heading':
967
977
 
968
978
  attrs = {
969
979
  title: element.innerHTML.trim(),
@@ -986,7 +996,12 @@ function generateModuleShortcode(module, element ){
986
996
  content = element.innerHTML.trim()
987
997
 
988
998
  break;
989
- }
999
+
1000
+ case 'image':
1001
+ let {src, href: url} = convertRawAttrs( element.rawAttrs )
1002
+ attrs = { src, url };
1003
+
1004
+ break;
990
1005
  }
991
1006
 
992
1007
  if( element.classList.length ){
@@ -2,28 +2,192 @@
2
2
  /**
3
3
  * External dependencies
4
4
  */
5
+ import path from 'path';
6
+ import fs from 'fs';
7
+ import SitemapWebpackPlugin from 'sitemap-webpack-plugin';
8
+
5
9
  import CAWebHTMLPlugin from "@caweb/html-webpack-plugin";
6
10
  import CAWebA11yPlugin from '@caweb/a11y-webpack-plugin';
7
11
  import CAWebCSSAuditPlugin from '@caweb/css-audit-webpack-plugin';
8
12
  import CAWebJSHintPlugin from '@caweb/jshint-webpack-plugin';
13
+ import { XMLParser } from 'fast-xml-parser';
14
+ import Handlebars from '@caweb/webpack/lib/handlebars.js';
9
15
 
10
- import { flagExists } from '@caweb/webpack/lib/args.js';
16
+ import { flagExists, getArgVal, flags } from '@caweb/webpack/lib/args.js';
11
17
 
12
- export default {
18
+ // this is the path to the current project directory
19
+ const appPath = process.cwd();
20
+
21
+ let templatePath = path.join(appPath, 'node_modules', '@caweb', 'template');
22
+
23
+ // we read the app caweb.json file if it exists
24
+ let caweb = fs.existsSync( path.join(appPath, 'caweb.json') ) ?
25
+ JSON.parse(fs.readFileSync(path.join(appPath, 'caweb.json')))
26
+ : {};
27
+
28
+ // argument variables
29
+ let template = getArgVal( 'template', path.join(templatePath, 'patterns', 'default.html') );
30
+
31
+ let scheme = getArgVal( 'scheme', 'oceanside' );
32
+
33
+ // Template patterns
34
+ let patterns = fs.readdirSync(path.join(templatePath, 'patterns'), { withFileTypes: true } )
35
+ .filter( dirent => dirent.isFile() && (dirent.name.endsWith('.html') ) )
36
+ .map( ( dirent ) => {
37
+
38
+ let fileTemplate = path.join( dirent.parentPath, dirent.name );
39
+ let filename = fileTemplate.replace(path.join(templatePath, 'patterns'), '').replace(/\\/g, '');
40
+
41
+ // we ignore the default and blank patterns since those are used as templates and not actual pages
42
+ // if there is no Google Search Id we ignore the search pattern since that is only used for the Search Results page
43
+ if (
44
+ ['default.html', 'blank.html'].includes( filename ) ||
45
+ (filename === 'serp.html' && ! caweb?.site?.google?.search)
46
+ ) {
47
+ return false;
48
+ }
49
+
50
+ return {
51
+ file: fileTemplate,
52
+ filename,
53
+ };
54
+ })
55
+ .filter( Boolean );
56
+
57
+ // Additional pages directory
58
+ let basePageDir = path.join(appPath, 'content', 'pages');
59
+
60
+ let additionalPages = ! fs.existsSync( basePageDir ) ? [] :
61
+ fs.readdirSync( basePageDir, { withFileTypes: true, recursive: true } )
62
+ .filter( dirent => dirent.isFile() && (dirent.name.endsWith('.html') || dirent.name.endsWith('.handlebars')) )
63
+ .map( ( dirent ) => {
64
+
65
+ let fileTemplate = path.join( dirent.parentPath, dirent.name );
66
+ let filename = fileTemplate.replace(basePageDir, '').replace(/\\/, '');
67
+
68
+ // if additionl pages match a pattern page we remove ours
69
+ let override = patterns.find( (p) => p.filename === filename );
70
+ if( override ){
71
+ patterns = patterns.filter( (p) => p.filename !== filename );
72
+ }
13
73
 
74
+ return {
75
+ file: fileTemplate,
76
+ filename,
77
+ template,
78
+ }
79
+ })
80
+
81
+ let customPages = [...patterns, ...additionalPages ].filter( Boolean );
82
+
83
+ export default {
84
+
14
85
  plugins: [
15
86
  // add custom plugins here
16
87
  // Used for Site Generation
17
- new CAWebHTMLPlugin(),
88
+ // when using the CAWebHTMLPlugin we dont have to pass the caweb.site data since that is automatically done by the plugin, we just need to pass the scheme so that it can be used in the templates
89
+ new CAWebHTMLPlugin({
90
+ template,
91
+ templateParameters: {
92
+ scheme,
93
+ },
94
+ }),
95
+
96
+ // Additional pages from content/pages directory
97
+ ...customPages.map( (page) => {
98
+ // replace .html, uppercase the first letter of each word
99
+ // this is to make sure the title is readable
100
+ // and not just a file name
101
+ let title = page.filename.replace('.html', '').replace(/\b\w/g, c => c.toUpperCase());
102
+ let content = fs.readFileSync( page.file, 'utf-8' );
103
+
104
+ let data = {
105
+ ...caweb.site,
106
+ scheme
107
+ };
108
+
109
+ let compiler = Handlebars.compile( content );
110
+ let compiledContent = compiler(data);
111
+
112
+ return new CAWebHTMLPlugin({
113
+ template: page.template ?? page.file,
114
+ filename: page.filename,
115
+ title,
116
+ templateParameters: {
117
+ scheme,
118
+ partial: compiledContent,
119
+ },
120
+ })
121
+ }) ,
122
+
123
+ // Sitemap Generation
124
+ ( ! flagExists('sitemap') || (flagExists('sitemap') && getArgVal('sitemap'))) && new SitemapWebpackPlugin.default({
125
+ base: caweb?.site?.url || 'http://localhost:9000',
126
+ paths: ['/build/', ...customPages.map( (page) => `/${page.filename}` )],
127
+ options: {
128
+ filename: 'sitemap.html',
129
+ skipgzip: true, // By default, both .xml and .xml.gz are generated
130
+ formatter: (config) => {
131
+ // we remove the build/ from the url since that is the output path and proxied
132
+ config = config.replace(/build\//g, '');
133
+
134
+ let parser = new XMLParser();
135
+ let xmlDoc = parser.parse(config, true);
136
+
137
+ // we map the urls to html links
138
+ let partial = xmlDoc.urlset.url ?
139
+ xmlDoc.urlset.url.map( ({loc}) => `<a href="${loc}" class="d-block">${loc}</a>` ).join('') : '';
140
+
141
+ let content = fs.readFileSync( template ).toString();
142
+
143
+ let data = {
144
+ ...caweb.site,
145
+ scheme,
146
+ logo: '/media/logo.png',
147
+ partial: `<div class="container"><div class="row"><div class="col-12"><h2>Sitemap</h2>${partial}</div></div></div>`,
148
+ };
149
+
150
+ let compiler = Handlebars.compile( content );
151
+ let compiledContent = compiler(data);
152
+
153
+ return compiledContent;
154
+ }
155
+ }
156
+ }),
157
+
158
+ // Custom plugin to rename the sitemap file from sitemap.html.xml to sitemap.html since the sitemap-webpack-plugin does not allow us to set the extension to .html
159
+ ( ! flagExists('sitemap') || (flagExists('sitemap') && getArgVal('sitemap'))) && {
160
+ apply: (compiler) => {
161
+ compiler.hooks.thisCompilation.tap('RenameSitemapWebpackPlugin',(compilation) => {
162
+ compilation.hooks.processAssets.tapAsync(
163
+ {
164
+ name: 'RenameSitemapWebpackPlugin',
165
+ stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE ,
166
+ },
167
+ (assets, callback) => {
168
+ Object.keys(compilation.assets).forEach((assetName) => {
169
+ if (assetName.endsWith('.html.xml')) {
170
+ const newName = assetName.replace('.xml', '');
171
+ compilation.assets[newName] = compilation.assets[assetName];
172
+ delete compilation.assets[assetName];
173
+ }
174
+ });
175
+ callback();
176
+ }
177
+ )
178
+
179
+ });
180
+ },
181
+ },
18
182
 
19
- // // IBM Accessibility
20
- ! flagExists('no-a11y') && new CAWebA11yPlugin(),
183
+ // IBM Accessibility
184
+ ( ! flagExists('a11y') || (flagExists('a11y') && getArgVal('a11y'))) && new CAWebA11yPlugin(),
21
185
 
22
- // // WP CSS Auditor
23
- ! flagExists( 'no-audit' ) && new CAWebCSSAuditPlugin(),
186
+ // WP CSS Auditor
187
+ ( ! flagExists('audit') || (flagExists('audit') && getArgVal('audit'))) && new CAWebCSSAuditPlugin(),
24
188
 
25
- // // JSHint
26
- ! flagExists( 'no-jshint' ) && new CAWebJSHintPlugin(),
189
+ // JSHint
190
+ ( ! flagExists('jshint') || (flagExists('jshint') && getArgVal('jshint'))) && new CAWebJSHintPlugin(),
27
191
 
28
192
  ].filter( Boolean ),
29
193
  }
package/lib/cli.js CHANGED
@@ -96,6 +96,7 @@ function addWebpackCmds(){
96
96
  .option( '--no-audit', 'Skips WordPress CSS-Audit.', false )
97
97
  .option( '--no-a11y', 'Skips IBM Accessibility Checker.', false )
98
98
  .option( '--no-jshint', 'Skips JSHint.', false )
99
+ .option( '--no-sitemap', 'Skips Sitemap generation.', false )
99
100
  .allowUnknownOption(true)
100
101
  .allowExcessArguments(true)
101
102
  .action(env.webpack)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caweb/cli",
3
- "version": "1.15.16",
3
+ "version": "1.15.18",
4
4
  "description": "CAWebPublishing Command Line Interface.",
5
5
  "exports": "./lib/env.js",
6
6
  "type": "module",
@@ -66,9 +66,9 @@
66
66
  "dependencies": {
67
67
  "@caweb/a11y-webpack-plugin": "^2.1.0",
68
68
  "@caweb/css-audit-webpack-plugin": "^2.1.0",
69
- "@caweb/html-webpack-plugin": "^2.1.3",
69
+ "@caweb/html-webpack-plugin": "^2.1.5",
70
70
  "@caweb/jshint-webpack-plugin": "^2.1.0",
71
- "@caweb/webpack": "^1.6.4",
71
+ "@caweb/webpack": "^1.6.6",
72
72
  "@inquirer/prompts": "^8.2.0",
73
73
  "@wordpress/create-block": "^4.82.0",
74
74
  "@wordpress/env": "^10.39.0",
@@ -80,6 +80,7 @@
80
80
  "crypto": "^1.0.1",
81
81
  "deepmerge": "^4.3.1",
82
82
  "docker-compose": "^1.3.1",
83
+ "fast-xml-parser": "^5.3.5",
83
84
  "fs-extra": "^11.3.3",
84
85
  "html-to-json-parser": "^2.0.1",
85
86
  "inquirer-select-pro": "^1.0.0-alpha.9",
@@ -88,6 +89,7 @@
88
89
  "ora": "^9.3.0",
89
90
  "resolve-bin": "^1.0.1",
90
91
  "rimraf": "^6.1.2",
92
+ "sitemap-webpack-plugin": "^1.1.1",
91
93
  "terminal-link": "^5.0.0"
92
94
  }
93
95
  }