ticket #3 - Added learning cartridge with all complete examples

This commit is contained in:
Max Gialanella 2021-12-22 11:09:55 -07:00
parent 8f15cd15df
commit 3f354195f2
33 changed files with 783 additions and 0 deletions

View File

@ -0,0 +1,57 @@
'use strict';
var server = require('server');
var cyborgForm = server.forms.getForm('cyborgregistrationform');
var Logger = require('dw/system/Logger');
var log = Logger.getLogger('DevTest','Cyborg');
server.get('Start', function (req, res, next) {
cyborgForm.clear();
log.info('Form loaded.');
res.render('cyborgTracker/registrationform', {
cyborgForm: cyborgForm,
disabled: false
});
next();
});
server.post('HandleForm', function (req, res, next) {
var storageService = require('~/cartridge/scripts/storageService');
var Transaction = require('dw/system/Transaction');
var message = '';
log.info('Cyborg form handler loaded.');
Transaction.begin();
try {
var co = storageService.storeCyborgForm(cyborgForm);
Transaction.commit();
message = 'Form Saved';
log.info('Cyborg form saved');
}
catch (e){
Transaction.rollback();
message = 'Failed to save';
log.warn('Cyborg form failed to save ' + e);
}
res.render('cyborgTracker/registrationform', {
cyborgForm: cyborgForm,
message: message,
disabled: true
});
next();
});
module.exports = server.exports();

View File

@ -0,0 +1,43 @@
'use strict';
var server = require('server');
var cache = require('*/cartridge/scripts/middleware/cache');
var ProductFactory = require('*/cartridge/scripts/factories/product');
var StoreMgr = require('dw/catalog/StoreMgr');
var Logger = require('dw/system/Logger');
var log = Logger.getLogger('DevTest','Cyborg');
server.get('Start',
cache.applyShortPromotionSensitiveCache,
function (req, res, next) {
var params = {'pid':'sony-kdl-55xbr8M'};
var productModel = ProductFactory.get(params);
var storeModel = StoreMgr.getStore('store1');
var viewData = {
'productModel': productModel,
'storeModel': storeModel
};
log.debug('Loaded demo page');
res.render('demo', viewData);
next();
});
server.get('Designer', function (req, res, next) {
let PageMgr = require('dw/experience/PageMgr');
let page = PageMgr.getPage('testpage');
log.warn('Loaded page designer page');
res.print(PageMgr.renderPage(page.ID, 'testpage'));
next();
});
module.exports = server.exports();

View File

@ -0,0 +1,22 @@
'use strict';
var server = require('server');
server.get('Start', function (req, res, next) {
res.print('Greetings Planet');
next();
});
server.get('Showme', function (req, res, next) {
// Use template hello.isml
// Pass data to pdict using name param1
res.render('hello', { 'param1':'This will render.' });
next();
});
module.exports = server.exports();

View File

@ -0,0 +1,44 @@
'use strict';
var server = require('server');
//Use super module to extend existing home route
server.extend(module.superModule);
//import userLoggedIn middleware
var userLoggedIn = require('*/cartridge/scripts/middleware/userLoggedIn');
//Use prepend to check for logged in user
server.prepend('Show', userLoggedIn.validateLoggedIn, function (req, res, next) {
var viewData = res.getViewData();
viewData.detailText = 'Please log in'; //One method to set view data
if (req.currentCustomer.profile) {
viewData.detailText = 'Welcome ' + customer.getProfile().getFirstName();
}
next();
});
//Use append to check for promotion
server.append('Show', function (req, res, next) {
var promoText = 'There are no Promotions at this time';
//read query string to check for fromotions
if (req.querystring.promo == 1) {
promoText = 'All Electronics are 98% off! Practically free!';
}
if (req.querystring.promo == 2) {
promoText = 'Overnight shipping is free!';
}
res.setViewData(
{ promoText: promoText } //Another way to set view data
);
next();
});
module.exports = server.exports();

View File

@ -0,0 +1,79 @@
'use strict';
var server = require('server');
var csrfProtection = require('*/cartridge/scripts/middleware/csrf');
var userLoggedIn = require('*/cartridge/scripts/middleware/userLoggedIn');
var consentTracking = require('*/cartridge/scripts/middleware/consentTracking');
var Logger = require('dw/system/Logger');
var log = Logger.getLogger('DevTest','Notifications');
server.get('Start',
server.middleware.https,
userLoggedIn.validateLoggedIn,
consentTracking.consent,
csrfProtection.generateToken,
function (req, res, next) {
var notificationsForm = server.forms.getForm('notifications');
notificationsForm.clear();
if(customer.profile.custom.notificationSales){
notificationsForm.notificationSales.checked = 'checked';
}
if(customer.profile.custom.notificationNew){
notificationsForm.notificationNew.checked = 'checked';
}
if(customer.profile.custom.notificationStock){
notificationsForm.notificationStock.checked = 'checked';
}
res.render('notificationsform', {
notificationsForm: notificationsForm
});
log.debug('Rendered Notifications Form');
next();
});
server.post('HandleForm',
server.middleware.https,
csrfProtection.validateRequest,
function (req, res, next) {
var notificationsForm = server.forms.getForm('notifications');
var URLUtils = require('dw/web/URLUtils');
var Transaction = require('dw/system/Transaction');
Transaction.begin();
try {
customer.profile.custom.notificationSales = notificationsForm.notificationSales.value
customer.profile.custom.notificationNew = notificationsForm.notificationNew.value
customer.profile.custom.notificationStock = notificationsForm.notificationStock.value
Transaction.commit();
log.error('Saved notifications');
var HookMgr = require('dw/system/HookMgr');
var userEmail = customer.getProfile().getEmail();
HookMgr.callHook('app.notification.email', 'sendNotificationsChange', userEmail);
} catch (error) {
Transaction.rollback();
log.error(error);
}
// res.redirect( URLUtils.url('Notifications') ); //For testing
res.redirect( URLUtils.url('Account-Show') );
next();
})
module.exports = server.exports();

View File

@ -0,0 +1,19 @@
'use strict';
var server = require('server');
//Basket Manager will get all the users basket information
var BasketMgr = require('dw/order/BasketMgr');
server.get('List', function (req, res, next) {
var viewData = {
'basket': BasketMgr.getCurrentOrNewBasket()
};
res.render('simplebasket', viewData);
next();
});
module.exports = server.exports();

View File

@ -0,0 +1,22 @@
'use strict';
var Template = require('dw/util/Template');
var HashMap = require('dw/util/HashMap');
/**
* Render logic for storefront.imageAndText component.
* @param {dw.experience.ComponentScriptContext} context The Component script context object.
* @param {dw.util.Map} [modelIn] Additional model values created by another cartridge.
*
* @returns {string} The markup to be displayed
*/
module.exports.render = function (context, modelIn) {
var model = modelIn || new HashMap();
var content = context.content;
model.title = content.title ? content.title : null;
model.comment = content.comment ? content.comment : null;
model.name = content.name ? content.name : null;
return new Template('experience/components/commerce_assets/feedback').render(model).text;
};

View File

@ -0,0 +1,36 @@
{
"name": "Feedback",
"description": "Hardcoded customer feedback",
"group": "Custom",
"attribute_definition_groups": [
{
"id": "feedback_content",
"name": "Feedback Content",
"description": "Enter feedback below, all fields required",
"attribute_definitions": [
{
"id": "title",
"name": "Title",
"description": "title of feedback",
"type": "string",
"required": true
},
{
"id": "comment",
"name": "Comment",
"description": "Text body of feedback",
"type": "markup",
"required": true
},
{
"id": "name",
"name": "Username",
"description": "User who submitted this feebback",
"type": "string",
"required": true
}
]
}
],
"region_definitions": []
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<form>
<field formid="humanname" label="Human Name" type="string" mandatory="true" max-length="50"/>
<field formid="cyborgname" label="Cyborg Name" type="string" mandatory="true" max-length="50"/>
<field formid="email" label="label.input.email.profile" type="string" mandatory="true"
regexp="^[\w-\.]{1,}\@([\da-zA-Z-]{1,}\.){1,}[\da-zA-Z-]{2,6}$"
parse-error="error.message.parse.email.profile.form"
value-error="error.message.parse.email.profile.form"
max-length="50"/>
<field formid="mostlyhuman" label="Mostly Human" type="boolean" />
<action formid="subscribe" valid-form="true"/>
</form>

View File

@ -0,0 +1,7 @@
<?xml version="1.0"?>
<form>
<field formid="notificationSales" label="label.notification.sales" type="boolean" />
<field formid="notificationNew" label="label.notification.new" type="boolean" />
<field formid="notificationStock" label="label.notification.stock" type="boolean" />
<action formid="apply" label="button.notification.submit" valid-form="true"/>
</form>

View File

@ -0,0 +1,9 @@
'use strict';
module.exports = function (object, productApi) {
var inventoryRecord = productApi.availabilityModel.inventoryRecord;
Object.defineProperty(object, 'stockInformation', {
enumerable: true,
value: inventoryRecord==null ? 0 :parseInt(inventoryRecord.ATS,10)
});
};

View File

@ -0,0 +1,23 @@
'use strict';
var base = module.superModule;
//Load our stock information decorator
var stockInformation = require('*/cartridge/models/product/decorators/stockInformation');
/**
* Decorate product with product line item information
* @param {Object} product - Product Model to be decorated
* @param {dw.catalog.Product} apiProduct - Product information returned by the script API
* @param {Object} options - Options passed in from the factory
* @returns {Object} - Decorated product model
*/
function fullProduct(product, apiProduct, options) {
//Call base, pass all the same paramters
base.call(this, product, apiProduct, options);
//use decorator to lead invintory from product api
stockInformation(product,apiProduct);
return product;
}
module.exports = fullProduct;

View File

@ -0,0 +1,12 @@
'use strict';
var base = module.superModule;
function store(storeObject) {
base.call(this, storeObject);
this.email = storeObject.email;
}
store.prototype = Object.create(base.prototype);
module.exports = store;

View File

@ -0,0 +1,23 @@
'use strict';
function sendNotificationsChange(emailAddress) {
var Mail = require('dw/net/Mail');
var Site = require('dw/system/Site');
var Template = require('dw/util/Template');
var HashMap = require('dw/util/HashMap');
var context = new HashMap();
var email = new Mail();
var template = new Template('notificationchangeemail');
email.addTo(emailAddress);
email.setFrom(Site.current.getCustomPreferenceValue('customerServiceEmail') || 'no-reply@salesforce.com');
email.setSubject('Notification Settings Changed');
email.setContent(template.render(context).text, 'text/html', 'UTF-8');
email.send();
}
module.exports = {
sendNotificationsChange: sendNotificationsChange
};

View File

@ -0,0 +1,17 @@
'use strict';
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
function storeCyborgForm(cyborgForm) {
var CustomObject = CustomObjectMgr.createCustomObject('Cyborgtracker', cyborgForm.email.value);
CustomObject.custom.cyborgname = cyborgForm.cyborgname.value;
CustomObject.custom.humanname = cyborgForm.humanname.value;
CustomObject.custom.email = cyborgForm.email.value;
CustomObject.custom.mostlyhuman = cyborgForm.mostlyhuman.value;
return CustomObject;
}
module.exports = {storeCyborgForm: storeCyborgForm};

View File

@ -0,0 +1,26 @@
<isdecorate template="common/layout/page">
<isif condition="${pdict.reportingURLs && pdict.reportingURLs.length}">
<isinclude template="reporting/reportingUrls" />
</isif>
<isscript>
var assets = require('*/cartridge/scripts/assets.js');
assets.addCss('/css/account/dashboard.css');
</isscript>
<div class="hero slant-down account-image">
<h1 class="page-title">${Resource.msg('page.heading.dashboard','account',null)}</h1>
</div>
<div class="container">
<!---Breadcrumbs--->
<isinclude template="components/breadcrumbs/pageBreadcrumbs"/>
<iscomment> custom notifications form </iscomment>
<isinclude url="${ URLUtils.url('Notifications') }" />
<isinclude template="account/dashboardProfileCards"/>
</div>
</isdecorate>

View File

@ -0,0 +1,74 @@
<isdecorate template="common/layout/page">
<isif condition="${pdict.message && pdict.message != ''}">
<div class="container mt-3 mb-3">
<h3 class="primary-text">${pdict.message}</h3>
</div>
</isif>
<div class="container mt-3 mb-3">
<form action="${URLUtils.url('Cyborg-HandleForm')}" method="POST">
<div class="form-row">
<iscomment> human name </iscomment>
<div class="col form-group">
<label for="humanname">
${ pdict.cyborgForm.humanname.label }
</label>
<input class="form-control" type="text" id="humanname"
<isprint value="${pdict.cyborgForm.humanname.attributes}" encoding="off" />
<isprint value="${pdict.disabled ? 'disabled':''}" encoding="off" />
/>
</div>
<iscomment> cyborg name </iscomment>
<div class="col form-group">
<label for="cyborgname">
${pdict.cyborgForm.cyborgname.label}
</label>
<input class="form-control" type="text" id="cyborgname"
<isprint value="${pdict.cyborgForm.cyborgname.attributes}" encoding="off" />
<isprint value="${pdict.disabled ? 'disabled':''}" encoding="off" />
/>
</div>
<iscomment> email </iscomment>
<div class="col form-group">
<label for="email">
${pdict.cyborgForm.email.label}
</label>
<input class="form-control" type="text" id="email"
<isprint value="${pdict.cyborgForm.email.attributes}" encoding="off" />
<isprint value="${pdict.disabled ? 'disabled':''}" encoding="off" />
/>
</div>
</div>
<iscomment> mostly human </iscomment>
<div class="form-row">
<div class="form-check form-check-inline">
<input type="checkbox" id="mostlyhuman"
<isprint value="${pdict.cyborgForm.mostlyhuman.attributes}" encoding="off" />
<isprint value="${pdict.disabled ? 'disabled':''}" encoding="off" />
/>
<label class="form-check-label" for="mostlyhuman">${pdict.cyborgForm.mostlyhuman.label}
</label>
</div>
</div>
<isif condition="${pdict.disabled}">
<a href="${ URLUtils.url('Cyborg') }">Back to Edit</a>
<iselse/>
<iscomment> submit button </iscomment>
<div class="form-row">
<button type="submit" class="btn btn-primary">
${Resource.msg('button.submit.promo.code','cart', null)}
</button>
</div>
</isif>
</form>
</div>
</isdecorate>

View File

@ -0,0 +1,37 @@
<isdecorate template="common/layout/page">
<div class="container mt-5 mb-5">
<div class="card">
<div class="card-body">
<isslot id="demo-slot" description="Demo Slot" context="global" />
</div>
</div>
</div>
<div class="container mt-5 mb-5">
<h3 class="text-primary">
${ Resource.msg('label.title','demo', 'demo title') }
</h3>
<h1>
${pdict.storeModel.name}
</h1>
<h2>
${pdict.storeModel.email} - ${pdict.storeModel.postalCode}
</h2>
<h3 class="text-primary mt-5">
${ Resource.msg('label.featured','demo', 'demo featured') }
</h3>
<h1>
${pdict.productModel.productName}
</h1>
<h2>
${ Resource.msg('label.stock','demo', 'demo stock') }:
${pdict.productModel.stockInformation}
</h2>
</div>
<isinclude url="${URLUtils.url('SimpleBasket-List')}" />
<isinclude template="demoinclude" />
</isdecorate>

View File

@ -0,0 +1,3 @@
<div class="container">
New Demos coming soon
</div>

View File

@ -0,0 +1,13 @@
<div class="card" style="width: 25rem;">
<div class="card-body">
<h5 class="card-title">
<isprint value="${pdict.title}" />
</h5>
<p class="card-text">
<isprint value="${pdict.comment}" encoding="off" />
</p>
<h6 class="card-subtitle mb-2 text-muted">
- <isprint value="${pdict.name}" />
</h6>
</div>
</div>

View File

@ -0,0 +1,5 @@
<html>
<body>
<h1>${pdict.param1}</h1>
</body>
</html>

View File

@ -0,0 +1,50 @@
<isdecorate template="common/layout/page">
<isscript>
var assets = require('*/cartridge/scripts/assets.js');
assets.addJs('/js/productTile.js');
assets.addCss('/css/homePage.css');
</isscript>
<div class="container mt-4 mb-4">
<h1>${pdict.detailText}</h1>
<h2 class="text-primary">${pdict.promoText}</h2>
</div>
<!-- +1.888.555.0199 --><!--This phone is a requirement to support existing Gomez monitor of SiteGenesis. Demadware customers can remove this.-->
<div class="home-main homepage">
<isslot id="home-main-m" description="Main home page slot." context="global" />
</div>
<div class="container home-categories homepage">
<div class="row home-main-categories no-gutters">
<isslot id="home-categories-m" description="Categories slots on the home page." context="global" />
</div>
</div>
<div class="container home-product-tiles homepage">
<div class="hp-product-grid" itemtype="http://schema.org/SomeProducts" itemid="#product">
<isslot id="home-products-m" description="Product tiles on the home page." context="global" />
</div>
</div>
<div class="homepage shop-the-style">
<isslot id="home-product-set-m" description="Link to a Product Set." context="global" />
</div>
<div class="home-email-signup">
<div class="container">
<form role="form">
<div class="row">
<div class="col-sm-5">
<div class="input-group">
<input type="text" class="form-control" name="hpEmailSignUp" placeholder="${Resource.msg('placeholdertext.form.emailsignup', 'homePage', null)}" aria-label="${Resource.msg('placeholdertext.form.emailsignup', 'homePage', null)}">
<span class="input-group-append">
<button type="submit" class="btn btn-primary subscribe-email" data-href="${URLUtils.url('EmailSubscribe-Subscribe')}">${Resource.msg('button.form.emailsignup', 'homePage', null)} </button>
</span>
</div>
</div>
<div class="col-sm-7 email-description">${Resource.msg('description.form.emailsignup', 'homePage', null)}</div>
</div>
</form>
</div>
</div>
</isdecorate>

View File

@ -0,0 +1,3 @@
<p>
Your Notification settings have been changed.
</p>

View File

@ -0,0 +1,57 @@
<div class="container mt-3 mb-3">
<h4 class="text-primary">${ Resource.msg('title.notifications','forms', null) }</h4>
<form action="${ URLUtils.url('Notifications-HandleForm') }" method="POST">
<div class="form-group">
<iscomment> checkbox </iscomment>
<div class="form-row">
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" id="notificationSales"
<isprint value="${pdict.notificationsForm.notificationSales.attributes}" encoding="off" />
/>
<label class="form-check-label" for="notificationSales">
${pdict.notificationsForm.notificationSales.label}
</label>
</div>
</div>
<iscomment> checkbox </iscomment>
<div class="form-row">
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" id="notificationNew"
<isprint value="${pdict.notificationsForm.notificationNew.attributes}" encoding="off" />
/>
<label class="form-check-label" for="notificationNew">
${pdict.notificationsForm.notificationNew.label}
</label>
</div>
</div>
<iscomment> checkbox </iscomment>
<div class="form-row">
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" id="notificationStock"
<isprint value="${pdict.notificationsForm.notificationStock.attributes}" encoding="off" />
/>
<label class="form-check-label" for="notificationStock">
${pdict.notificationsForm.notificationStock.label}
</label>
</div>
</div>
</div>
<iscomment> submit button </iscomment>
<div class="form-row">
<button type="submit" class="btn btn-primary">
${Resource.msg('button.submit.promo.code','cart', null)}
</button>
</div>
<iscomment> CSRF protection </iscomment>
<input type="hidden" name="${pdict.csrf.tokenName}" value="${pdict.csrf.token}" />
</form>
</div>

View File

@ -0,0 +1,9 @@
<iscomment> total stock </iscomment>
<p class="text-primary mt-3">
Total Stock: ${pdict.product.stockInformation}
</p>
<!-- Availability -->
<div class="availability row product-availability" data-ready-to-order="${product.readyToOrder}" data-available="${product.available}">
<isinclude template="product/components/availability" />
</div>

View File

@ -0,0 +1,18 @@
<div class="container">
<isif condition="${pdict.basket.allProductLineItems.length > 0}">
<ul class="list-group">
<iscomment>Assign product line item to variable product</iscomment>
<isloop items="${pdict.basket.allProductLineItems}" var="product">
<li class="list-group-item">
${product.productName} - ${product.price}
</li>
</isloop>
</ul>
<iselse/>
Your Basket is empty.
</isif>
</div>

View File

@ -0,0 +1,35 @@
<div class="store-details" data-store-id="${store.ID}">
<div class="store-name">${store.name}</div>
<address>
<a class="store-map" target='_blank' href="https://maps.google.com/?daddr=${store.latitude},${store.longitude}">
${store.address1}
<isif condition="${store.address2}">
${store.address2}
</isif>
<isif condition="${store.city}">
${store.city},
</isif>
<isif condition="${store.stateCode}">
${store.stateCode}
</isif>
${store.postalCode}
</a>
<div class="store-hours">
<isif condition="${store.storeHours}">
<isprint value="${store.storeHours}" encoding="off"/>
</isif>
<isif condition="${store.email}">
<p>
<i class="fa fa-envelope" aria-hidden="true"></i>
<a href="mailto:${store.email}">${store.email}</a>
</p>
</isif>
</div>
<p>
<isif condition="${store.phone}">
<i class="fa fa-phone" aria-hidden="true"></i>
<span><a class="storelocator-phone" href="tel:${store.phone}">${store.phone}</a></span>
</isif>
</p>
</address>
</div>

View File

@ -0,0 +1,3 @@
label.title=(En)You are Shopping at
label.featured=(En)Featured Product
label.stock=(En)Total Stock

View File

@ -0,0 +1,3 @@
label.title=(日本語) You are Shopping at
label.featured=(日本語) Featured Product
label.stock=(日本語) total stock

View File

@ -0,0 +1,6 @@
## Notification preferences, extends profile ##
title.notifications=Store Notification Settings
label.notification.sales=Recieve email notifications about upcoming sales
label.notification.new=Recieve email notifications about new products
label.notification.stock=Recieve email notifications about back in stock products
button.notification.submit=Save notification preferences

View File

@ -0,0 +1,4 @@
## cartridge.properties for cartridge the_learning_cartridge
#Thu Jun 09 11:30:40 EDT 2016
demandware.cartridges.the_learning_cartridge.multipleLanguageStorefront=true
demandware.cartridges.the_learning_cartridge.id=the_learning_cartridge

View File

@ -0,0 +1,8 @@
{
"hooks": [
{
"name": "app.notification.email",
"script": "./cartridge/scripts/hooks/notificationChangeEmail"
}
]
}

View File

@ -0,0 +1,4 @@
{
"hooks": "./hooks.json"
}