title
Keystone JS Tutorial - A Node.js CMS

description
In this video we will look at the Node.js CMS, Keystone.js. We will generate an application and then add a products/store section to the app. CODE - https://github.com/bradtraversy/acme_keystone FULL COURSES - http://www.traversymedia.com/eduonix-courses/ We spend huge amounts of time making these videos available for free. Any donation is greatly appreciated https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=KLVYJVNUJ5NV4

detail
{'title': 'Keystone JS Tutorial - A Node.js CMS', 'heatmap': [{'end': 201.896, 'start': 138.843, 'weight': 0.943}, {'end': 337.13, 'start': 277.435, 'weight': 0.861}, {'end': 1511.09, 'start': 1283.439, 'weight': 0.74}, {'end': 2214.244, 'start': 2175.896, 'weight': 0.721}, {'end': 2578.81, 'start': 2541.606, 'weight': 0.71}], 'summary': 'This tutorial on keystone.js provides an introduction to the node.js cms, demonstrating the addition of product sections and integration with contact forms, setup with node.js and bootstrap, troubleshooting email configuration, model creation, view controllers, and customizing the homepage for enhanced user experience.', 'chapters': [{'end': 86.681, 'segs': [{'end': 33.446, 'src': 'embed', 'start': 0.891, 'weight': 1, 'content': [{'end': 1.531, 'text': "hey, what's going on?", 'start': 0.891, 'duration': 0.64}, {'end': 5.333, 'text': "guys? in this video we're going to be diving into Keystone.js.", 'start': 1.531, 'duration': 3.802}, {'end': 10.696, 'text': "so I've been getting a lot of requests for this, and they try to fulfill as many requests as I can.", 'start': 5.333, 'duration': 5.363}, {'end': 13.377, 'text': "plus, it's something that I've been wanting to get into.", 'start': 10.696, 'duration': 2.681}, {'end': 21.741, 'text': 'so Keystone is a content management system and web application platform built on node.js, and it uses Express and MongoDB.', 'start': 13.377, 'duration': 8.364}, {'end': 28.542, 'text': 'So it uses a Yeoman generator that we can use for rapid development and prototyping.', 'start': 23.058, 'duration': 5.484}, {'end': 33.446, 'text': 'And it can give us things like a blog, a photo gallery, a contact form.', 'start': 29.183, 'duration': 4.263}], 'summary': 'Introduction to keystone.js, a content management system and web application platform built on node.js, using express and mongodb, with a yeoman generator for rapid development and prototyping.', 'duration': 32.555, 'max_score': 0.891, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g891.jpg'}, {'end': 89.562, 'src': 'embed', 'start': 63.188, 'weight': 0, 'content': [{'end': 69.472, 'text': "But what we'll do is we'll add a product section to the admin side so that we can manage products.", 'start': 63.188, 'duration': 6.284}, {'end': 73.755, 'text': "We'll be able to add images, a description, quantities, things like that.", 'start': 69.912, 'duration': 3.843}, {'end': 83.399, 'text': "We'll be able to display them on the front end on a list page, and we'll be able to also create a details page with a link to the contact form,", 'start': 74.535, 'duration': 8.864}, {'end': 86.681, 'text': "and then we'll add a product inquiry option on the contact form.", 'start': 83.399, 'duration': 3.282}, {'end': 89.562, 'text': 'All right, so hopefully you enjoy this.', 'start': 87.361, 'duration': 2.201}], 'summary': 'Add product section to admin side to manage products with images, description, quantities. display on list page and create details page with contact form link. also, add product inquiry option on contact form.', 'duration': 26.374, 'max_score': 63.188, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g63188.jpg'}], 'start': 0.891, 'title': 'Introducing keystone.js', 'summary': 'Provides an introduction to keystone.js, a node.js-based content management system and web application platform, and demonstrates product section addition to the admin side for managing products and integrating with the contact form.', 'chapters': [{'end': 86.681, 'start': 0.891, 'title': 'Introduction to keystone.js', 'summary': "Introduces keystone.js, a content management system and web application platform built on node.js, using express and mongodb, and demonstrates how to add a product section to the application's admin side for managing products and integrating with the contact form.", 'duration': 85.79, 'highlights': ['Keystone.js is a content management system and web application platform built on node.js, using Express and MongoDB, with a Yeoman generator for rapid development and prototyping.', 'Demonstrating how to add a product section to the admin side, enabling management of products including adding images, descriptions, quantities, and displaying them on the front end with a link to the contact form.']}], 'duration': 85.79, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g891.jpg', 'highlights': ['Keystone.js is a content management system and web application platform built on node.js, using Express and MongoDB, with a Yeoman generator for rapid development and prototyping.', 'Demonstrating how to add a product section to the admin side, enabling management of products including adding images, descriptions, quantities, and displaying them on the front end with a link to the contact form.']}, {'end': 562.427, 'segs': [{'end': 201.896, 'src': 'heatmap', 'start': 87.361, 'weight': 4, 'content': [{'end': 89.562, 'text': 'All right, so hopefully you enjoy this.', 'start': 87.361, 'duration': 2.201}, {'end': 93.324, 'text': 'I think Keystone is one of the best Node.js platforms out right now.', 'start': 89.862, 'duration': 3.462}, {'end': 98.106, 'text': "It's very expandable and easy to work with, so let's go ahead and get started.", 'start': 94.044, 'duration': 4.062}, {'end': 106.68, 'text': 'So the very first thing you want to do before we start is get Node.js installed on your system and get MongoDB installed locally.', 'start': 99.11, 'duration': 7.57}, {'end': 111.446, 'text': "So I have videos showing you how to do that if you don't know how to do that.", 'start': 107.481, 'duration': 3.965}, {'end': 116.132, 'text': "But you definitely want those two things up and running or this won't work.", 'start': 112.207, 'duration': 3.925}, {'end': 121.387, 'text': "okay, so i'm at keystonejs.com and i'm going to just click on,", 'start': 116.843, 'duration': 4.544}, {'end': 129.875, 'text': "get started and that's going to basically just give us the the initial commands we need to install the generator and then create a project.", 'start': 121.387, 'duration': 8.488}, {'end': 131.476, 'text': "now it's not here, but you all.", 'start': 129.875, 'duration': 1.601}, {'end': 136.641, 'text': 'you want to install the yo generator or the the yeoman scaffolding tool.', 'start': 131.476, 'duration': 5.165}, {'end': 138.843, 'text': "so to do that i'm on linux.", 'start': 136.641, 'duration': 2.202}, {'end': 149.747, 'text': "so i'm going to use sudo and then we're going to say npm, install dash g, yo and that's going to install the yeoman scaffolding tool, all right.", 'start': 138.843, 'duration': 10.904}, {'end': 154.348, 'text': "so now that that's all set, we can now install the keystone generator.", 'start': 149.747, 'duration': 4.601}, {'end': 167.873, 'text': "so we're going to say npm, install, or actually i need to do sudo, npm, install dash g and then generator, dash, keystone.", 'start': 154.348, 'duration': 13.525}, {'end': 171.165, 'text': "Okay, that'll install the generator globally.", 'start': 169.124, 'duration': 2.041}, {'end': 182.17, 'text': "Okay, so once that's done, we're gonna create a project folder, so I'm gonna say make directory, and we're gonna call this project acme.", 'start': 174.846, 'duration': 7.324}, {'end': 189.813, 'text': "And then we'll cd into acme, and then we wanna generate our application with yo keystone.", 'start': 183.01, 'duration': 6.803}, {'end': 194.855, 'text': 'Okay, and this can take a little bit, well actually we have to answer some questions first.', 'start': 191.293, 'duration': 3.562}, {'end': 198.474, 'text': "So the name of our project, We'll say Acme.", 'start': 195.115, 'duration': 3.359}, {'end': 201.896, 'text': 'Now it asks us which template engine we want to use.', 'start': 199.535, 'duration': 2.361}], 'summary': 'Keystone is an expandable node.js platform. install node.js and mongodb. install yeoman scaffolding tool, then the keystone generator. create a project folder and generate the application with yo keystone.', 'duration': 80.512, 'max_score': 87.361, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g87361.jpg'}, {'end': 268.951, 'src': 'embed', 'start': 241.775, 'weight': 0, 'content': [{'end': 251.703, 'text': "this will actually be your admin username, so i'm going to say traversimedia gmail.com, and then your password.", 'start': 241.775, 'duration': 9.928}, {'end': 258.666, 'text': 'And then it asks us if we want to include Gulp or Grunt, which are task runners.', 'start': 254.864, 'duration': 3.802}, {'end': 260.507, 'text': "I'm going to choose to use Gulp.", 'start': 259.046, 'duration': 1.461}, {'end': 268.951, 'text': "And then would you like to create a new directory for your project? I'm going to say no, because I want it created in the Acme folder.", 'start': 262.528, 'duration': 6.423}], 'summary': 'Setting up admin username and password, choosing gulp as task runner, and specifying project directory.', 'duration': 27.176, 'max_score': 241.775, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g241775.jpg'}, {'end': 337.13, 'src': 'heatmap', 'start': 277.435, 'weight': 0.861, 'content': [{'end': 279.876, 'text': 'If you want to do that, you can put in your URL.', 'start': 277.435, 'duration': 2.441}, {'end': 281.517, 'text': "I'm just going to click Enter.", 'start': 280.536, 'duration': 0.981}, {'end': 288.375, 'text': "And then would you like to include extra comments in your code? I'm going to say yes, because that could help us out.", 'start': 282.99, 'duration': 5.385}, {'end': 290.717, 'text': 'All right, now this takes a little bit.', 'start': 288.395, 'duration': 2.322}, {'end': 292.879, 'text': "It takes, I don't know, three or four minutes or so.", 'start': 290.737, 'duration': 2.142}, {'end': 295.641, 'text': "So I'm going to go ahead and pause, and I'll be back when it's done.", 'start': 292.899, 'duration': 2.742}, {'end': 299.285, 'text': 'All right, so that only took about two minutes or so.', 'start': 295.661, 'duration': 3.624}, {'end': 303.809, 'text': 'Now it tells us to run node keystone to start our project.', 'start': 299.505, 'duration': 4.304}, {'end': 304.99, 'text': "So let's do that.", 'start': 304.149, 'duration': 0.841}, {'end': 311.552, 'text': 'and our project has started on port three thousand.', 'start': 308.75, 'duration': 2.802}, {'end': 315.695, 'text': "so let's go to localhost three thousand.", 'start': 311.552, 'duration': 4.143}, {'end': 317.416, 'text': 'and this is what the front end looks like.', 'start': 315.695, 'duration': 1.721}, {'end': 325.281, 'text': 'okay, so you can see, it uses twitter bootstrap by default and basically have a navbar, and then we have this jumbotron with some information.', 'start': 317.416, 'duration': 7.865}, {'end': 327.563, 'text': 'tells us our username, password.', 'start': 325.281, 'duration': 2.282}, {'end': 329.564, 'text': 'obviously you want to get rid of this, uh.', 'start': 327.563, 'duration': 2.001}, {'end': 333.967, 'text': "before you go live and then we have our blog link, so we don't have any posts.", 'start': 329.564, 'duration': 4.403}, {'end': 337.13, 'text': 'but we have a blog with with category functionality.', 'start': 333.967, 'duration': 3.163}], 'summary': 'Setting up project, running on port 3000, using twitter bootstrap, with blog and category functionality.', 'duration': 59.695, 'max_score': 277.435, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g277435.jpg'}], 'start': 87.361, 'title': 'Setting up keystone and bootstrap with node.js', 'summary': 'Covers setting up keystone with node.js, including installing dependencies, generating a project, and configuring options. it also demonstrates a bootstrap website with various functionalities such as a navbar, jumbotron, blog, image gallery, and contact form, showcasing features like post creation and category assignment.', 'chapters': [{'end': 317.416, 'start': 87.361, 'title': 'Setting up keystone with node.js', 'summary': 'Covers the process of setting up keystone with node.js, including installing necessary dependencies, generating a project, and configuring various options, with a final demonstration of the project running on localhost:3000.', 'duration': 230.055, 'highlights': ["Installing Node.js and MongoDB is a prerequisite for setting up Keystone. It's essential to have Node.js and MongoDB installed before starting the Keystone setup process to ensure everything works properly.", 'Installing the yeoman scaffolding tool and keystone generator are key steps in the setup process. The installation of yeoman scaffolding tool and keystone generator is crucial for creating the project and generating the application.', 'Configuration options such as template engine, preprocessor, and additional features like blog, image gallery, and contact form are selected during the project setup. During the project setup, choices for template engine, preprocessor, and additional features like blog, image gallery, and contact form are made, along with the user model and other configurations.', 'Running the project on localhost:3000 after setup demonstrates the successful setup and functioning of the Keystone project. After completing the setup, running the project on localhost:3000 demonstrates the successful setup and functioning of the Keystone project.']}, {'end': 562.427, 'start': 317.416, 'title': 'Bootstrap website demo', 'summary': 'Demonstrates the default layout and functionality of a bootstrap website, including a navbar, jumbotron with user information, blog with category functionality, image gallery, contact form, back end login, and basic content creation and display, showcasing features like post creation, category assignment, and front-end display.', 'duration': 245.011, 'highlights': ['The chapter demonstrates the default layout and functionality of a Bootstrap website The transcript illustrates the default features of a Bootstrap website, showcasing a navbar, jumbotron with user information, blog with category functionality, image gallery, contact form, and back end login.', 'Basic content creation and display, showcasing features like post creation, category assignment, and front-end display It covers the process of creating a blog post, including category assignment, content creation, and display on the front end, highlighting the basic functionality of content management.', 'Back end login with different sections for posts, post categories, galleries, inquiries, and users The back end login interface provides access to various sections for managing posts, post categories, galleries, inquiries, and users, showcasing the administrative functionality of the website.', 'Demonstration of creating a gallery and displaying it on the front end It demonstrates the process of creating a gallery, choosing images, and displaying the gallery on the front end, highlighting the basic functionality of image management.', "Limited functionality of the default website, requiring additional programming for features like comment functionality and lightbox for the gallery The default website lacks certain functionalities such as comment functionality and lightbox for the gallery, indicating the need for custom programming to enhance the website's features."]}], 'duration': 475.066, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g87361.jpg', 'highlights': ['Installing Node.js and MongoDB is a prerequisite for setting up Keystone.', 'Installing the yeoman scaffolding tool and keystone generator are key steps in the setup process.', 'Configuration options such as template engine, preprocessor, and additional features are selected during the project setup.', 'Running the project on localhost:3000 after setup demonstrates the successful setup and functioning of the Keystone project.', 'The chapter demonstrates the default layout and functionality of a Bootstrap website.', 'Basic content creation and display, showcasing features like post creation, category assignment, and front-end display.', 'Back end login with different sections for posts, post categories, galleries, inquiries, and users.', 'Demonstration of creating a gallery and displaying it on the front end.', 'Limited functionality of the default website, requiring additional programming for features like comment functionality and lightbox for the gallery.']}, {'end': 1104.533, 'segs': [{'end': 659.81, 'src': 'embed', 'start': 636.116, 'weight': 0, 'content': [{'end': 645.64, 'text': 'But then we have Lodash, we have our handlebars, Template Engine, Cloudinary, Moment for dealing with times and dates, Node, SAS.', 'start': 636.116, 'duration': 9.524}, {'end': 651.663, 'text': "And then down here, we have the dev dependencies, which we're using Gulp for our task runner and ESLint.", 'start': 645.8, 'duration': 5.863}, {'end': 656.829, 'text': 'Okay, so Keystone.js is the main configuration file for Keystone.', 'start': 652.526, 'duration': 4.303}, {'end': 659.81, 'text': 'It has our template directories, things like that.', 'start': 656.849, 'duration': 2.961}], 'summary': 'Keystone.js configures lodash, handlebars, cloudinary, moment, node, sas, gulp, and eslint for task running and linting.', 'duration': 23.694, 'max_score': 636.116, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g636116.jpg'}, {'end': 717.849, 'src': 'embed', 'start': 686.826, 'weight': 1, 'content': [{'end': 691.709, 'text': 'And then in the routes folder we have a views folder where we have each route.', 'start': 686.826, 'duration': 4.883}, {'end': 695.971, 'text': "This is basically like the controller, if you're familiar with MVC.", 'start': 692.009, 'duration': 3.962}, {'end': 702.982, 'text': 'This is where we can actually call our queries or call the model to create our queries.', 'start': 697.87, 'duration': 5.112}, {'end': 707.673, 'text': "You can see here we're getting the gallery model and we're calling find and then we're sorting it.", 'start': 703.022, 'duration': 4.651}, {'end': 709.763, 'text': "And then we're going to render a view.", 'start': 708.462, 'duration': 1.301}, {'end': 717.849, 'text': "In this case, it's rendering the gallery view, which if we go down here into templates and then views, you'll see gallery.hbs.", 'start': 709.823, 'duration': 8.026}], 'summary': 'Routes folder contains views to call model queries and render gallery view.', 'duration': 31.023, 'max_score': 686.826, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g686826.jpg'}, {'end': 1016.71, 'src': 'embed', 'start': 981.774, 'weight': 2, 'content': [{'end': 988.089, 'text': "So we can say product.add And in here we're going to put our fields.", 'start': 981.774, 'duration': 6.315}, {'end': 990.07, 'text': 'So obviously we want title.', 'start': 988.209, 'duration': 1.861}, {'end': 994.913, 'text': "And that's going to have a type of string.", 'start': 991.451, 'duration': 3.462}, {'end': 1000.136, 'text': "Type string and let's say required true.", 'start': 997.014, 'duration': 3.122}, {'end': 1001.737, 'text': 'We want it to be required.', 'start': 1000.557, 'duration': 1.18}, {'end': 1004.659, 'text': "Next thing we'll have is a price.", 'start': 1002.718, 'duration': 1.941}, {'end': 1009.522, 'text': "And we're going to set price to have the type of number.", 'start': 1006, 'duration': 3.522}, {'end': 1013.024, 'text': 'We also want a quantity.', 'start': 1010.943, 'duration': 2.081}, {'end': 1015.45, 'text': "So let's set quantity.", 'start': 1014.269, 'duration': 1.181}, {'end': 1016.71, 'text': 'That will also be a number.', 'start': 1015.51, 'duration': 1.2}], 'summary': 'Defining product fields: title(string, required), price(number), quantity(number)', 'duration': 34.936, 'max_score': 981.774, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g981774.jpg'}], 'start': 562.427, 'title': 'Website product section and keystone.js overview', 'summary': "Covers troubleshooting email configuration, adding users, implementing a product section to the website, and providing an overview of a keystone.js project, including file structure, dependencies, configuration files, model creation, route handling, and adding fields to a model, with a focus on creating a 'product' model and defining its fields.", 'chapters': [{'end': 614.344, 'start': 562.427, 'title': 'Adding product section to website', 'summary': 'Discusses troubleshooting an issue with email configuration, adding users, and implementing a product section to the website.', 'duration': 51.917, 'highlights': ['Troubleshooting email configuration issue and confirming successful resolution', 'Discussing default user functionality and the ability to add users with backend access', 'Planning to add a product section to the website']}, {'end': 1104.533, 'start': 614.384, 'title': 'Keystone.js project overview', 'summary': "Provides an overview of a keystone.js project, including its file structure, package.json dependencies, configuration files, model creation, route handling, and adding fields to a model, with a focus on creating a 'product' model and defining its fields.", 'duration': 490.149, 'highlights': ['Explaining the file structure and package.json dependencies The chapter outlines the file structure of a Keystone.js project and the dependencies listed in the package.json file, including Lodash, Handlebars, Cloudinary, Moment, Node, and SAS.', "Overview of Keystone.js configuration file and model creation The main configuration file for Keystone.js, 'Keystone.js', is discussed, along with the process of creating models in the 'models' folder, with examples of post and gallery models, and the plan to create a 'product' model.", "Explanation of route handling and view controller The chapter delves into route handling using Express, the 'index.js' file for setting routes, the 'routes' folder for creating route views similar to a controller in MVC, and the rendering of views after calling model queries.", "Defining fields for the 'product' model The detailed process of creating a 'product' model is provided, including defining fields such as title, price, quantity, description, image using Cloudinary, and a publish date with a default value of date.now."]}], 'duration': 542.106, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g562427.jpg', 'highlights': ["Defining fields for the 'product' model including title, price, quantity, description, image using Cloudinary, and a publish date with a default value of date.now", 'Explaining the file structure and package.json dependencies of a Keystone.js project', 'Discussing default user functionality and the ability to add users with backend access', 'Planning to add a product section to the website', 'Overview of Keystone.js configuration file and model creation']}, {'end': 1504.449, 'segs': [{'end': 1175.391, 'src': 'embed', 'start': 1128.47, 'weight': 5, 'content': [{'end': 1136.036, 'text': "basically, we're going to have two files because we want a product, and products Because we're going to have two different views.", 'start': 1128.47, 'duration': 7.566}, {'end': 1141.24, 'text': "So let's create one called products.js.", 'start': 1136.136, 'duration': 5.104}, {'end': 1146.965, 'text': "And then we're also going to create product.js.", 'start': 1142.581, 'duration': 4.384}, {'end': 1149.507, 'text': "So let's start with products.", 'start': 1148.226, 'duration': 1.281}, {'end': 1153.33, 'text': "So we're going to bring in Keystone.", 'start': 1151.008, 'duration': 2.322}, {'end': 1167.487, 'text': "and then what we're going to do is say exports uh..", 'start': 1163.124, 'duration': 4.363}, {'end': 1175.391, 'text': 'exports equals module dot exports equals function.', 'start': 1167.487, 'duration': 7.904}], 'summary': 'Creating two files, products.js and product.js, for two different views in keystone.', 'duration': 46.921, 'max_score': 1128.47, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g1128470.jpg'}, {'end': 1357.418, 'src': 'embed', 'start': 1248.674, 'weight': 0, 'content': [{'end': 1250.495, 'text': 'we wanna set them to store.', 'start': 1248.674, 'duration': 1.821}, {'end': 1253.416, 'text': "And we're gonna have the menu item say store as well.", 'start': 1250.835, 'duration': 2.581}, {'end': 1263.88, 'text': 'All right, so now what we wanna do is we wanna load our products.', 'start': 1254.436, 'duration': 9.444}, {'end': 1267.602, 'text': "So we're gonna say, we're gonna take that view and we're gonna call query.", 'start': 1264.08, 'duration': 3.522}, {'end': 1283.439, 'text': "and let's pass in here products, and then we want to pass in our model, so keystone dot list,", 'start': 1270.769, 'duration': 12.67}, {'end': 1294.908, 'text': "and we want to grab our product product model and then call dot model and then dot find, okay, and that's going to grab all of our products.", 'start': 1283.439, 'duration': 11.469}, {'end': 1297.37, 'text': 'and then the last thing we want to do is just render our view.', 'start': 1294.908, 'duration': 2.462}, {'end': 1305.068, 'text': "so view dot render, And we're going to render a view called products.", 'start': 1297.37, 'duration': 7.698}, {'end': 1311.532, 'text': "Okay, and that's it.", 'start': 1305.088, 'duration': 6.444}, {'end': 1313.053, 'text': "So let's save that.", 'start': 1312.132, 'duration': 0.921}, {'end': 1318.556, 'text': "Now to set the route, we're going to go to routes and then index.js.", 'start': 1314.573, 'duration': 3.983}, {'end': 1321.317, 'text': "And we're going to go down here.", 'start': 1319.496, 'duration': 1.821}, {'end': 1324.439, 'text': "And let's put this here.", 'start': 1323.038, 'duration': 1.401}, {'end': 1326.38, 'text': "So we'll say app.get.", 'start': 1324.519, 'duration': 1.861}, {'end': 1331.523, 'text': "And it's going to be slash products.", 'start': 1328.881, 'duration': 2.642}, {'end': 1339.414, 'text': 'And we want that to go to routes.views.products.', 'start': 1333.132, 'duration': 6.282}, {'end': 1341.954, 'text': 'Just like that.', 'start': 1341.334, 'duration': 0.62}, {'end': 1343.655, 'text': "Okay, we'll save that.", 'start': 1341.974, 'duration': 1.681}, {'end': 1346.875, 'text': 'And then I believe we have to add something to middleware.js as well.', 'start': 1343.775, 'duration': 3.1}, {'end': 1352.957, 'text': 'Yeah, so right here..', 'start': 1348.356, 'duration': 4.601}, {'end': 1354.517, 'text': 'This is actually the menu item.', 'start': 1352.957, 'duration': 1.56}, {'end': 1357.418, 'text': "So let's go ahead and paste that in.", 'start': 1354.857, 'duration': 2.561}], 'summary': "Developing a store with menu item 'store', loading products, and setting route for '/products'.", 'duration': 108.744, 'max_score': 1248.674, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g1248674.jpg'}], 'start': 1104.533, 'title': 'Creating models and view controllers for store products', 'summary': 'Covers registering models in keystone, creating view controllers for products.js and product.js, setting up global variables for the section, and building a store page with product loading, route creation, menu item addition, and template creation, while addressing errors related to model functions and server restarts.', 'chapters': [{'end': 1248.674, 'start': 1104.533, 'title': 'Register models and create view controllers', 'summary': 'Covers the process of registering models in keystone and creating view controllers for products.js and product.js, including setting up global variables for the section and utilizing it for the active class for the navbar.', 'duration': 144.141, 'highlights': ['The chapter explains the process of registering models in Keystone and creating view controllers for products.js and product.js.', "It covers the setup of global variables and setting the 'section' variable to 'store' for the product.js view controller.", 'The section variable is used for the active class for the navbar in the front end.']}, {'end': 1504.449, 'start': 1248.674, 'title': 'Building store products view', 'summary': 'Details setting up a store page, loading products, creating routes, adding menu items, and creating a template for products, while troubleshooting errors related to model functions and server restarts.', 'duration': 255.775, 'highlights': ['Setting up a store page Explaining the process of setting up a store page and ensuring that the menu item reflects the same, while emphasizing the goal to load products for the store.', 'Loading products Detailing the process of loading products by calling the query with the product model and finding all products to render on the view, and the necessity to troubleshoot and correct errors related to model functions.', 'Creating routes and menu items Describing the configuration of routes to direct to the products view, the addition of menu items with corresponding labels and keys to connect to the active class, and the need for further adjustments in the middleware file.', 'Creating a template for products Illustrating the creation of a handlebars template file for products in the views folder and the process of restarting the server to check for errors and ensure the successful display of the products on the back end and front end.']}], 'duration': 399.916, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g1104533.jpg', 'highlights': ['Covers registering models in Keystone and creating view controllers for products.js and product.js.', 'Setting up a store page and ensuring that the menu item reflects the same, while emphasizing the goal to load products for the store.', 'Detailing the process of loading products by calling the query with the product model and finding all products to render on the view, and the necessity to troubleshoot and correct errors related to model functions.', 'Describing the configuration of routes to direct to the products view, the addition of menu items with corresponding labels and keys to connect to the active class, and the need for further adjustments in the middleware file.', 'Illustrating the creation of a handlebars template file for products in the views folder and the process of restarting the server to check for errors and ensure the successful display of the products on the back end and front end.', 'The section variable is used for the active class for the navbar in the front end.', "It covers the setup of global variables and setting the 'section' variable to 'store' for the product.js view controller."]}, {'end': 2796.649, 'segs': [{'end': 1578.386, 'src': 'embed', 'start': 1504.849, 'weight': 5, 'content': [{'end': 1507.269, 'text': 'Store And there we go.', 'start': 1504.849, 'duration': 2.42}, {'end': 1509.11, 'text': "We're loading up our products template.", 'start': 1507.349, 'duration': 1.761}, {'end': 1511.09, 'text': "So that's good.", 'start': 1510.25, 'duration': 0.84}, {'end': 1523.782, 'text': 'And then if we go in the back end and click on products, we get no products found and we can now create them.', 'start': 1511.11, 'duration': 12.672}, {'end': 1539.832, 'text': "so let's actually do that will create a product and let's say we want to add the iphone seven create and you can see we have our fields.", 'start': 1523.782, 'duration': 16.05}, {'end': 1544.316, 'text': 'so price will say 299.99.', 'start': 1539.832, 'duration': 4.484}, {'end': 1546.398, 'text': 'say we have a hundred of them.', 'start': 1544.316, 'duration': 2.082}, {'end': 1552.663, 'text': "description I'm just gonna paste this in it's just description.", 'start': 1546.398, 'duration': 6.265}, {'end': 1556.606, 'text': "I got from the Apple website and then I'm gonna upload an image.", 'start': 1552.663, 'duration': 3.943}, {'end': 1563.512, 'text': "so I have this iPhone image and the publish date is going to be set to now and then we're gonna save.", 'start': 1556.606, 'duration': 6.906}, {'end': 1567.103, 'text': 'Okay, so it says your changes has been saved.', 'start': 1565.202, 'duration': 1.901}, {'end': 1574.025, 'text': 'And now if we go to products, there it is, our iPhone 7.', 'start': 1568.023, 'duration': 6.002}, {'end': 1576.145, 'text': "So let's create one more product.", 'start': 1574.025, 'duration': 2.12}, {'end': 1578.386, 'text': "We'll add the iPad Air.", 'start': 1576.766, 'duration': 1.62}], 'summary': 'Uploaded iphone 7 at $299.99 with 100 units. added ipad air.', 'duration': 73.537, 'max_score': 1504.849, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g1504849.jpg'}, {'end': 1659.805, 'src': 'embed', 'start': 1615.639, 'weight': 8, 'content': [{'end': 1621.3, 'text': "so products dot HBS And we're using bootstrap.", 'start': 1615.639, 'duration': 5.661}, {'end': 1629.212, 'text': "so let's add a container and And we're going to have an H1..", 'start': 1621.3, 'duration': 7.912}, {'end': 1630.693, 'text': "We'll say products.", 'start': 1629.433, 'duration': 1.26}, {'end': 1640.095, 'text': "Okay, and then let's do a row.", 'start': 1630.713, 'duration': 9.382}, {'end': 1648.137, 'text': "And this is going to be, let's just do a 12 column.", 'start': 1643.936, 'duration': 4.201}, {'end': 1650.938, 'text': "So it'll reach all the way across.", 'start': 1649.497, 'duration': 1.441}, {'end': 1654.599, 'text': "We'll say column D12 and call LG12.", 'start': 1651.318, 'duration': 3.281}, {'end': 1659.805, 'text': "And if you don't know Bootstrap, These are just some predefined classes for the grid.", 'start': 1655.059, 'duration': 4.746}], 'summary': 'Using bootstrap classes to create a layout for products, including a container, h1 header, and a 12-column row.', 'duration': 44.166, 'max_score': 1615.639, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g1615639.jpg'}, {'end': 1730.354, 'src': 'embed', 'start': 1690.514, 'weight': 9, 'content': [{'end': 1704.705, 'text': "So for each one we want a div with the class of call MD for and call LG for, And let's put an h2.", 'start': 1690.514, 'duration': 14.191}, {'end': 1717.725, 'text': "Okay, so this will have a link to the details page which we haven't set up yet, and We want to put the title here,", 'start': 1704.705, 'duration': 13.02}, {'end': 1722.568, 'text': 'so we can use the triple curly braces and say title.', 'start': 1717.725, 'duration': 4.843}, {'end': 1725.871, 'text': "So let's just try that and see if it works.", 'start': 1723.729, 'duration': 2.142}, {'end': 1728.372, 'text': 'Okay, there we go.', 'start': 1725.891, 'duration': 2.481}, {'end': 1730.354, 'text': 'iPhone 7, iPad Air.', 'start': 1728.833, 'duration': 1.521}], 'summary': 'Creating divs with classes for call md and call lg, with a link to details page and titles.', 'duration': 39.84, 'max_score': 1690.514, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g1690514.jpg'}, {'end': 1819.456, 'src': 'embed', 'start': 1775.647, 'weight': 1, 'content': [{'end': 1781.749, 'text': "And let's also give it a class of thumbnail, which is a bootstrap class.", 'start': 1775.647, 'duration': 6.102}, {'end': 1783.95, 'text': "Okay, so we'll save.", 'start': 1782.849, 'duration': 1.101}, {'end': 1788.771, 'text': 'Okay, so we do want to set a width.', 'start': 1787.13, 'duration': 1.641}, {'end': 1792.172, 'text': "Let's say width.", 'start': 1791.112, 'duration': 1.06}, {'end': 1794.233, 'text': 'You could do this in your CSS if you want.', 'start': 1792.252, 'duration': 1.981}, {'end': 1795.993, 'text': 'Width 160, height 160.', 'start': 1795.373, 'duration': 0.62}, {'end': 1797.614, 'text': "Let's try that.", 'start': 1795.993, 'duration': 1.621}, {'end': 1815.735, 'text': "um yeah, that's what I have.", 'start': 1808.352, 'duration': 7.383}, {'end': 1819.456, 'text': "I guess that'll do alright.", 'start': 1815.735, 'duration': 3.721}], 'summary': 'Adding a thumbnail class with a width and height of 160 in bootstrap.', 'duration': 43.809, 'max_score': 1775.647, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g1775647.jpg'}, {'end': 1880.502, 'src': 'embed', 'start': 1845.071, 'weight': 3, 'content': [{'end': 1852.754, 'text': "I'm going to copy what we have in products.js and put it in product.js.", 'start': 1845.071, 'duration': 7.683}, {'end': 1854.552, 'text': 'All right.', 'start': 1854.212, 'duration': 0.34}, {'end': 1859.654, 'text': 'And then we want to see this is going to be the same.', 'start': 1854.652, 'duration': 5.002}, {'end': 1861.615, 'text': 'The section is going to be the same.', 'start': 1860.154, 'duration': 1.461}, {'end': 1863.055, 'text': "It's going to be in the store section.", 'start': 1861.675, 'duration': 1.38}, {'end': 1868.657, 'text': "Now we're going to change this query is going to work a little different.", 'start': 1864.396, 'duration': 4.261}, {'end': 1871.198, 'text': "So we're going to get rid of this.", 'start': 1869.598, 'duration': 1.6}, {'end': 1876.74, 'text': "And we're going to say view dot on.", 'start': 1873.719, 'duration': 3.021}, {'end': 1880.502, 'text': 'View dot on init.', 'start': 1876.761, 'duration': 3.741}], 'summary': 'Copying code from products.js to product.js, modifying query to work differently', 'duration': 35.431, 'max_score': 1845.071, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g1845071.jpg'}, {'end': 1991.584, 'src': 'embed', 'start': 1962.163, 'weight': 10, 'content': [{'end': 1972.937, 'text': "and then we're just gonna set another locals variable called data and set that to an object with our products, which is going to be an empty array.", 'start': 1962.163, 'duration': 10.774}, {'end': 1983.041, 'text': 'And then we want to be able to basically click on this and have it go to slash products, slash and then the slug,', 'start': 1972.957, 'duration': 10.084}, {'end': 1988.083, 'text': 'which in this case would be iPad Air, just formatted differently formatted for a URL.', 'start': 1983.041, 'duration': 5.042}, {'end': 1991.584, 'text': "So that's our query.", 'start': 1989.623, 'duration': 1.961}], 'summary': "Setting 'data' variable with empty array for 'products' and creating url query for 'ipad air'.", 'duration': 29.421, 'max_score': 1962.163, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g1962163.jpg'}, {'end': 2214.244, 'src': 'heatmap', 'start': 2175.896, 'weight': 0.721, 'content': [{'end': 2183.2, 'text': "All right, and let's just change this comment.", 'start': 2175.896, 'duration': 7.304}, {'end': 2186.221, 'text': "And we'll save that.", 'start': 2185.341, 'duration': 0.88}, {'end': 2194.585, 'text': "Then let's go back here and in this link, we want to call that product URL.", 'start': 2187.782, 'duration': 6.803}, {'end': 2201.128, 'text': "So we'll put our double curly brace and product URL and pass in slug.", 'start': 2194.625, 'duration': 6.503}, {'end': 2204.121, 'text': "Okay, so let's save that.", 'start': 2202.861, 'duration': 1.26}, {'end': 2206.242, 'text': "And we're going to have to restart the server.", 'start': 2204.481, 'duration': 1.761}, {'end': 2214.244, 'text': "Okay Let's see.", 'start': 2206.262, 'duration': 7.982}], 'summary': 'Configuring a new product url and restarting the server.', 'duration': 38.348, 'max_score': 2175.896, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g2175896.jpg'}, {'end': 2468.58, 'src': 'embed', 'start': 2365.306, 'weight': 0, 'content': [{'end': 2376.83, 'text': "so under the header we're gonna put in another row and basically I want to have two, six column divs.", 'start': 2365.306, 'duration': 11.524}, {'end': 2388.484, 'text': "Okay, so there's one.", 'start': 2387.383, 'duration': 1.101}, {'end': 2394.709, 'text': "Two And then this side's going to be the image.", 'start': 2391.667, 'duration': 3.042}, {'end': 2396.731, 'text': "So first thing we'll do is check for the image.", 'start': 2394.79, 'duration': 1.941}, {'end': 2401.816, 'text': "So if, and it's going to be data.image.", 'start': 2397.672, 'duration': 4.144}, {'end': 2406.52, 'text': "Oh, I'm sorry, data.product.image.", 'start': 2403.397, 'duration': 3.123}, {'end': 2414.287, 'text': "And if there is one, we'll display it.", 'start': 2412.045, 'duration': 2.242}, {'end': 2440.647, 'text': "so source is going to be uh, cloudinary url data, dot product dot image, and let's just do crop equals fit, okay,", 'start': 2417.006, 'duration': 23.641}, {'end': 2448.054, 'text': "and let's give it a class of image responsive.", 'start': 2440.647, 'duration': 7.407}, {'end': 2453.856, 'text': "All right, now on this side, in this six column div, we're going to put the information.", 'start': 2449.954, 'duration': 3.902}, {'end': 2458.437, 'text': "So I'm going to put this in a UL right here and say class list group.", 'start': 2453.876, 'duration': 4.561}, {'end': 2468.58, 'text': "And then we'll put in an ally with the class of list group item.", 'start': 2462.598, 'duration': 5.982}], 'summary': 'Creating a layout with two 6-column divs, one displaying an image using data.product.image and the other displaying information in a ul list with class list group item.', 'duration': 103.274, 'max_score': 2365.306, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g2365306.jpg'}, {'end': 2578.81, 'src': 'heatmap', 'start': 2541.606, 'weight': 0.71, 'content': [{'end': 2552.388, 'text': "okay, so we'll say ask about this product and let's save it.", 'start': 2541.606, 'duration': 10.782}, {'end': 2554.608, 'text': 'take a look, there we go.', 'start': 2552.388, 'duration': 2.22}, {'end': 2557.749, 'text': "there's our product page.", 'start': 2554.608, 'duration': 3.141}, {'end': 2564.07, 'text': 'notice that the store is also highlighted up here as active, because this and this page are both in the store section.', 'start': 2557.749, 'duration': 6.321}, {'end': 2572.746, 'text': 'so when we go to the contact page, i just want to add an extra um select option here to ask about a product.', 'start': 2565.04, 'duration': 7.706}, {'end': 2578.81, 'text': "for that you go into i think it's in the model and then in inquiry js,", 'start': 2572.746, 'duration': 6.064}], 'summary': 'Adding a select option to ask about a product in the contact page within the store section.', 'duration': 37.204, 'max_score': 2541.606, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g2541606.jpg'}], 'start': 1504.849, 'title': 'Displaying and customizing products on front end', 'summary': 'Discusses creating and displaying products on the front end using handlebars templates and bootstrap, including adding product details and customizing the homepage of a keystone app to improve user experience and visual appeal.', 'chapters': [{'end': 1819.456, 'start': 1504.849, 'title': 'Displaying products on front end', 'summary': 'Discusses the process of creating and displaying products on the front end using handlebars templates and bootstrap, including adding details such as product name, price, quantity, description, and images.', 'duration': 314.607, 'highlights': ['Creating and displaying products on the front end using handlebars templates and bootstrap The process of creating and displaying products on the front end using handlebars templates and bootstrap is discussed, including adding details such as product name, price, quantity, description, and images.', 'Adding iPhone 7 and iPad Air as products with their respective details The speaker adds the iPhone 7 and iPad Air as products with their respective details, such as price ($299.99 and $6.99), quantity (100 and 50), and descriptions.', "Using predefined classes for the grid in Bootstrap The speaker utilizes predefined classes for the grid in Bootstrap, such as 'column D12' and 'call LG12', to structure the product display on the front end.", 'Checking for images and setting attributes using handlebars and Cloudinary URL The process of checking for images and setting attributes using handlebars and Cloudinary URL is explained, including setting the width and height attributes for the images.']}, {'end': 2027.942, 'start': 1819.456, 'title': 'Creating individual product page', 'summary': 'Discusses creating individual product pages using a single model for both listing and individual product pages, involving setting up routes views, initializing view, querying data, and displaying results.', 'duration': 208.486, 'highlights': ['The chapter emphasizes using the same model for both the listing page and the individual product page.', 'It explains the process of setting up routes views and initializing view by running a function when the view initializes.', 'It details the process of querying data using a different query method and setting up filters for the products.', 'The chapter demonstrates the execution of the query and handling the results by populating the data object with the obtained product information.']}, {'end': 2637.471, 'start': 2027.942, 'title': 'Adding product view and routing', 'summary': 'Details the process of creating a product view and routing, including creating a route, adding a view, creating a helper for the product, and adding content to the handlebars template.', 'duration': 609.529, 'highlights': ['The process of creating a route for the product view and explaining the use of placeholders for slugs and matching them to the slug, along with the request params. Explains the creation of a route for the product view, including the use of placeholders for slugs and matching them to the slug, along with the request params.', 'The creation of a helper for the product, including defining the URL structure and updating the link in the template to call the product URL helper. Details the creation of a helper for the product, defining the URL structure and updating the link in the template to call the product URL helper.', 'Adding content to the handlebars template for the product view, including creating a div with a class of container, adding a link to go back to the products, displaying the product title, image, price, quantity, description, and a link to the contact page. Describes the process of adding content to the handlebars template for the product view, including creating a div with a class of container, adding a link to go back to the products, displaying the product title, image, price, quantity, description, and a link to the contact page.', 'The addition of a new option to ask about a product in the contact page, including the process of updating the model and restarting the server, highlighting the ability to add new functionalities to the existing system. Highlights the addition of a new option to ask about a product in the contact page, including the process of updating the model and restarting the server, showcasing the ability to add new functionalities to the existing system.']}, {'end': 2796.649, 'start': 2641.175, 'title': 'Customizing homepage with keystone app', 'summary': 'Covers customizing the homepage of a keystone app by removing login info, adding content using div classes, and discussing the process of adding functionality through model, view model, and template view.', 'duration': 155.474, 'highlights': ['The chapter covers customizing the homepage of a Keystone app by removing login info, adding content using div classes, and discussing the process of adding functionality through model, view model, and template view. The speaker explains the process of customizing the homepage of a Keystone app by removing login info, adding content using div classes, and discussing the process of adding functionality through model, view model, and template view.', 'The speaker demonstrates the addition of content using div classes such as div class row, div class call md4, and call lg4. The speaker demonstrates the addition of content using div classes such as div class row, div class call md4, and call lg4.', 'The speaker discusses the process of adding functionality through model, view model, and template view, emphasizing their importance in adding any kind of functionality to a Keystone app. The speaker discusses the process of adding functionality through model, view model, and template view, emphasizing their importance in adding any kind of functionality to a Keystone app.']}], 'duration': 1291.8, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/DPXDFeUEk3g/pics/DPXDFeUEk3g1504849.jpg', 'highlights': ['Creating and displaying products on the front end using handlebars templates and bootstrap, including adding product details and customizing the homepage of a keystone app to improve user experience and visual appeal.', 'Adding iPhone 7 and iPad Air as products with their respective details, such as price ($299.99 and $6.99), quantity (100 and 50), and descriptions.', 'Using predefined classes for the grid in Bootstrap to structure the product display on the front end.', 'Checking for images and setting attributes using handlebars and Cloudinary URL, including setting the width and height attributes for the images.', 'The chapter emphasizes using the same model for both the listing page and the individual product page.', 'Explaining the process of setting up routes views and initializing view by running a function when the view initializes.', 'Detailing the process of querying data using a different query method and setting up filters for the products.', 'The process of creating a route for the product view, including the use of placeholders for slugs and matching them to the slug, along with the request params.', 'The creation of a helper for the product, defining the URL structure and updating the link in the template to call the product URL helper.', 'Adding content to the handlebars template for the product view, including creating a div with a class of container, adding a link to go back to the products, displaying the product title, image, price, quantity, description, and a link to the contact page.', 'The addition of a new option to ask about a product in the contact page, including the process of updating the model and restarting the server, showcasing the ability to add new functionalities to the existing system.', 'Customizing the homepage of a Keystone app by removing login info, adding content using div classes, and discussing the process of adding functionality through model, view model, and template view, emphasizing their importance in adding any kind of functionality to a Keystone app.']}], 'highlights': ['Keystone.js is a content management system and web application platform built on node.js, using Express and MongoDB, with a Yeoman generator for rapid development and prototyping.', 'Demonstrating how to add a product section to the admin side, enabling management of products including adding images, descriptions, quantities, and displaying them on the front end with a link to the contact form.', 'Installing Node.js and MongoDB is a prerequisite for setting up Keystone.', 'Installing the yeoman scaffolding tool and keystone generator are key steps in the setup process.', 'Configuration options such as template engine, preprocessor, and additional features are selected during the project setup.', 'Running the project on localhost:3000 after setup demonstrates the successful setup and functioning of the Keystone project.', "Defining fields for the 'product' model including title, price, quantity, description, image using Cloudinary, and a publish date with a default value of date.now", 'Covers registering models in Keystone and creating view controllers for products.js and product.js.', 'Setting up a store page and ensuring that the menu item reflects the same, while emphasizing the goal to load products for the store.', 'Creating and displaying products on the front end using handlebars templates and bootstrap, including adding product details and customizing the homepage of a keystone app to improve user experience and visual appeal.']}