asjs-express 1.5.0 → 1.6.0
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.
package/package.json
CHANGED
|
@@ -4,15 +4,12 @@ const { setupAsjs } = require('asjs-express');
|
|
|
4
4
|
const app = express();
|
|
5
5
|
const port = process.env.PORT || __PORT__;
|
|
6
6
|
|
|
7
|
-
app.use(express.urlencoded({ extended: false }));
|
|
8
|
-
|
|
9
7
|
const asjs = setupAsjs(app, {
|
|
10
8
|
rootDir: __dirname,
|
|
11
9
|
defaultLayout: 'layouts/main',
|
|
12
10
|
navItems: [
|
|
13
11
|
{ href: '/', label: 'Home', activeMode: 'exact' },
|
|
14
|
-
{ href: '/about', label: 'About', activeMode: 'exact' }
|
|
15
|
-
{ href: '/contact', label: 'Contact', activeMode: 'exact' }
|
|
12
|
+
{ href: '/about', label: 'About', activeMode: 'exact' }
|
|
16
13
|
],
|
|
17
14
|
brand: {
|
|
18
15
|
href: '/',
|
|
@@ -25,32 +22,30 @@ const asjs = setupAsjs(app, {
|
|
|
25
22
|
loadingBar: true
|
|
26
23
|
});
|
|
27
24
|
|
|
28
|
-
// Home
|
|
29
25
|
app.get('/', asjs.page('home', {
|
|
30
26
|
title: '__APP_TITLE__',
|
|
31
27
|
headline: 'Welcome to __APP_TITLE__',
|
|
32
|
-
description: 'A
|
|
28
|
+
description: 'A starter built with ASJS and Express. SPA navigation, smooth transitions, and server-rendered pages are ready out of the box.',
|
|
33
29
|
features: [
|
|
34
30
|
{
|
|
35
31
|
label: 'SPA Navigation',
|
|
36
|
-
text: 'Pages swap without a full reload. The header and layout stay in place while only the content
|
|
32
|
+
text: 'Pages swap without a full reload. The header and layout stay in place while only the content changes.'
|
|
37
33
|
},
|
|
38
34
|
{
|
|
39
35
|
label: 'Server Rendering',
|
|
40
|
-
text: 'Each page is fully rendered on the server. Route data is prepared in the callback
|
|
36
|
+
text: 'Each page is fully rendered on the server before it reaches the browser. Route data is prepared in the callback.'
|
|
41
37
|
},
|
|
42
38
|
{
|
|
43
|
-
label: '
|
|
44
|
-
text: '
|
|
39
|
+
label: 'Zero Build Step',
|
|
40
|
+
text: 'No bundler, no compiler. Write EJS-style templates and run with Node. It just works.'
|
|
45
41
|
}
|
|
46
42
|
]
|
|
47
43
|
}));
|
|
48
44
|
|
|
49
|
-
// About
|
|
50
45
|
app.get('/about', asjs.page('about', {
|
|
51
46
|
title: 'About — __APP_TITLE__',
|
|
52
|
-
headline: 'About
|
|
53
|
-
description: '
|
|
47
|
+
headline: 'About __APP_TITLE__',
|
|
48
|
+
description: 'Built with ASJS on top of Express. Layouts, async page models, client-side transitions, and a loading bar — without a front-end build step.',
|
|
54
49
|
facts: [
|
|
55
50
|
{ label: 'Engine', value: 'ASJS __ASJS_VERSION__' },
|
|
56
51
|
{ label: 'Framework', value: 'Express' },
|
|
@@ -66,66 +61,8 @@ app.get('/about', asjs.page('about', {
|
|
|
66
61
|
]
|
|
67
62
|
}));
|
|
68
63
|
|
|
69
|
-
// Contact — GET
|
|
70
|
-
const contactInitialState = {
|
|
71
|
-
title: 'Contact — __APP_TITLE__',
|
|
72
|
-
headline: 'Get in touch',
|
|
73
|
-
description: 'Send a message using the form below. This form is handled on the server and returns a validation state or a success state.',
|
|
74
|
-
formValues: { name: '', email: '', message: '' },
|
|
75
|
-
formErrors: {},
|
|
76
|
-
submitted: false
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
app.get('/contact', asjs.page('contact', contactInitialState));
|
|
80
|
-
|
|
81
|
-
// Contact — POST
|
|
82
|
-
app.post('/contact', asjs.createPageRoute('contact', {}, async (req) => {
|
|
83
|
-
const formValues = asjs.normalizeFields(req.body, ['name', 'email', 'message']);
|
|
84
|
-
const formErrors = asjs.validateFields(formValues, {
|
|
85
|
-
name: {
|
|
86
|
-
required: 'Please enter your name.'
|
|
87
|
-
},
|
|
88
|
-
email: {
|
|
89
|
-
required: 'Please enter your email address.',
|
|
90
|
-
pattern: {
|
|
91
|
-
value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
|
|
92
|
-
message: 'Please enter a valid email address.'
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
message: {
|
|
96
|
-
required: 'Please write a message.',
|
|
97
|
-
minLength: {
|
|
98
|
-
value: 10,
|
|
99
|
-
message: 'Please write at least 10 characters.'
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
if (asjs.hasValidationErrors(formErrors)) {
|
|
105
|
-
return {
|
|
106
|
-
status: 422,
|
|
107
|
-
title: 'Contact — __APP_TITLE__',
|
|
108
|
-
headline: 'Get in touch',
|
|
109
|
-
description: 'A few fields need attention before the form can be sent.',
|
|
110
|
-
formValues,
|
|
111
|
-
formErrors,
|
|
112
|
-
submitted: false
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return {
|
|
117
|
-
title: 'Message sent — __APP_TITLE__',
|
|
118
|
-
headline: 'Message received',
|
|
119
|
-
description: 'Your message has been received. This is a starter demo — no real email was sent.',
|
|
120
|
-
formValues: contactInitialState.formValues,
|
|
121
|
-
formErrors: {},
|
|
122
|
-
submitted: true,
|
|
123
|
-
sentValues: formValues
|
|
124
|
-
};
|
|
125
|
-
}));
|
|
126
|
-
|
|
127
64
|
app.use(asjs.errors());
|
|
128
65
|
|
|
129
66
|
app.listen(port, () => {
|
|
130
|
-
console.log('__APP_TITLE__
|
|
67
|
+
console.log('__APP_TITLE__ running at http://localhost:' + port);
|
|
131
68
|
});
|
|
@@ -23,6 +23,5 @@
|
|
|
23
23
|
</ul>
|
|
24
24
|
<div class="hero-actions" style="margin-top: 24px;">
|
|
25
25
|
<a href="/" class="button button-primary" data-asjs-transition="fade">Back to home</a>
|
|
26
|
-
<a href="/contact" class="button button-secondary" data-asjs-transition="fade">Contact</a>
|
|
27
26
|
</div>
|
|
28
|
-
</div>
|
|
27
|
+
</div>
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
<% if (locals.submitted) { %>
|
|
2
|
-
<div class="section-card status-panel--success" style="margin-top: 0;">
|
|
3
|
-
<span class="section-label" style="background: #dcfce7; color: #15803d;">Sent</span>
|
|
4
|
-
<h2 style="margin-top: 14px; letter-spacing: -0.04em;"><%= headline %></h2>
|
|
5
|
-
<p><%= description %></p>
|
|
6
|
-
<div class="render-summary-grid" style="margin-top: 20px;">
|
|
7
|
-
<div class="render-item">
|
|
8
|
-
<span>Name</span>
|
|
9
|
-
<strong><%= sentValues.name %></strong>
|
|
10
|
-
</div>
|
|
11
|
-
<div class="render-item">
|
|
12
|
-
<span>Email</span>
|
|
13
|
-
<strong><%= sentValues.email %></strong>
|
|
14
|
-
</div>
|
|
15
|
-
</div>
|
|
16
|
-
<div class="hero-actions" style="margin-top: 24px;">
|
|
17
|
-
<a href="/" class="button button-primary" data-asjs-transition="fade">Back to home</a>
|
|
18
|
-
<a href="/contact" class="button button-secondary" data-asjs-transition="fade">Send another</a>
|
|
19
|
-
</div>
|
|
20
|
-
</div>
|
|
21
|
-
<% } else { %>
|
|
22
|
-
<div class="page-intro">
|
|
23
|
-
<span class="section-label">Contact</span>
|
|
24
|
-
<h1><%= headline %></h1>
|
|
25
|
-
<p><%= description %></p>
|
|
26
|
-
</div>
|
|
27
|
-
|
|
28
|
-
<div class="section-card form-panel">
|
|
29
|
-
<form class="webas-form" method="POST" action="/contact">
|
|
30
|
-
<div class="field-grid">
|
|
31
|
-
<div class="field-group">
|
|
32
|
-
<span>Name</span>
|
|
33
|
-
<input type="text" name="name" value="<%= formValues.name %>" placeholder="Your name" autocomplete="name">
|
|
34
|
-
<% if (formErrors.name) { %><span class="field-error"><%= formErrors.name %></span><% } %>
|
|
35
|
-
</div>
|
|
36
|
-
<div class="field-group">
|
|
37
|
-
<span>Email</span>
|
|
38
|
-
<input type="email" name="email" value="<%= formValues.email %>" placeholder="you@example.com" autocomplete="email">
|
|
39
|
-
<% if (formErrors.email) { %><span class="field-error"><%= formErrors.email %></span><% } %>
|
|
40
|
-
</div>
|
|
41
|
-
</div>
|
|
42
|
-
<div class="field-group">
|
|
43
|
-
<span>Message</span>
|
|
44
|
-
<textarea name="message" placeholder="Your message (at least 10 characters)"><%= formValues.message %></textarea>
|
|
45
|
-
<% if (formErrors.message) { %><span class="field-error"><%= formErrors.message %></span><% } %>
|
|
46
|
-
</div>
|
|
47
|
-
<div class="form-actions">
|
|
48
|
-
<button type="submit" class="button button-primary">Send message</button>
|
|
49
|
-
<span>The form is validated on the server before the page re-renders.</span>
|
|
50
|
-
</div>
|
|
51
|
-
</form>
|
|
52
|
-
</div>
|
|
53
|
-
<% } %>
|