├── .gitignore ├── README.md ├── assets ├── .babelrc ├── build │ ├── css │ │ ├── editor.css │ │ └── main.css │ └── js │ │ ├── editor.js │ │ └── main.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── src │ ├── js │ │ ├── components │ │ │ └── menu.js │ │ ├── editor.js │ │ └── main.js │ ├── sass │ │ ├── components │ │ │ ├── _pagination.scss │ │ │ └── _products.scss │ │ ├── editor.scss │ │ ├── main.scss │ │ └── settings │ │ │ └── _colors.scss │ └── svgs │ │ ├── cart.svg │ │ ├── hamburger.svg │ │ ├── user.svg │ │ └── wishlist.svg ├── tailwind.config.js └── webpack.config.js ├── classes ├── class-advanced-woocommerce-theme-assets.php ├── class-advanced-woocommerce-theme-menus.php └── class-advanced-woocommerce-theme.php ├── footer.php ├── front-page.php ├── functions.php ├── header.php ├── index.php ├── style.css ├── template-parts ├── front-page │ ├── pagination.php │ ├── product.php │ └── products.php └── header │ └── nav.php └── woocommerce ├── single-product.php └── single-product └── title.php /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore everything in the root except the "wp-content" directory. 2 | !wp-content/ 3 | 4 | # ignore everything in the "wp-content" directory, except: 5 | # "mu-plugins", "plugins", "themes" directory 6 | wp-content/* 7 | !wp-content/mu-plugins/ 8 | !wp-content/plugins/ 9 | !wp-content/themes/ 10 | 11 | # ignore these plugins 12 | wp-content/plugins/hello.php 13 | 14 | # ignore specific themes 15 | wp-content/themes/twenty*/ 16 | 17 | # ignore node dependency directories 18 | node_modules/ 19 | 20 | # ignore log files and databases 21 | *.log 22 | *.sql 23 | *.sqlite 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Advanced WooCommerce Theme](https://youtu.be/lNtw4yxEydM) 🛍️ 2 | [![Project Status: Active.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) 3 | 4 | * A WooCommerce theme Project for Advanced WooCommerce Theme Development Course. 5 | This theme uses Tailwindcss. [Learn](https://www.youtube.com/playlist?list=PLD8nQCAhR3tR3ZzS4ie2ylGdVM_mPpUkm) to build an Advanced WordPress Theme from scratch 6 | 7 | ## [Tutorial Course](https://www.youtube.com/playlist?list=PLD8nQCAhR3tR3ZzS4ie2ylGdVM_mPpUkm) 8 | 9 | ## Features 10 | 11 | - Custom Home page. 12 | - Single Product Page 13 | - Custom Cart Page 14 | - Custom Checkout Page 15 | 16 | ## Uses 17 | 18 | - TailwindCSS 19 | - Webpack 20 | - Babel 21 | - Sass 22 | 23 | ## Maintainer 24 | 25 | | Name | Github Username | 26 | |--------------------------------------------------------|-----------------| 27 | | [Imran Sayed](mailto:codeytek.academy@gmail.com) | @imranhsayed | 28 | 29 | ## Usage 30 | 31 | 1. Clone the WordPress theme [advanced-woocommerce-theme](https://github.com/imranhsayed/advanced-woocommerce-theme) in your WordPress 32 | themes directory and activate it. 33 | 2. Make sure WooCommerce plugin is active. 34 | 35 | 36 | ## Development ( To be added ) 37 | 38 | **Install** 39 | 40 | Clone the repo and run 41 | 42 | ```bash 43 | cd advanced-woocommerce-theme/assets 44 | npm install 45 | ``` 46 | 47 | **During development** 48 | 49 | ```bash 50 | cd assets 51 | npm run dev 52 | ``` 53 | 54 | **Production** 55 | 56 | ```bash 57 | cd assets 58 | npm run build 59 | ``` 60 | -------------------------------------------------------------------------------- /assets/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "browsers": [ 8 | "last 2 Chrome versions", 9 | "last 2 Firefox versions", 10 | "last 2 Safari versions", 11 | "last 2 iOS versions", 12 | "last 1 Android version", 13 | "last 1 ChromeAndroid version", 14 | "ie 11" 15 | ] 16 | } 17 | } 18 | ], 19 | "@babel/preset-react" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /assets/build/css/editor.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imranhsayed/advanced-woocommerce-theme/a46ae0758dba068c2445f0de43be06e5608d0df3/assets/build/css/editor.css -------------------------------------------------------------------------------- /assets/build/css/main.css: -------------------------------------------------------------------------------- 1 | /*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,Helvetica,Arial,Apple Color Emoji,Segoe UI Emoji}hr{height:0;color:inherit}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}button{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}button{background-color:transparent;background-image:none}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}fieldset,ol,ul{margin:0;padding:0}ol,ul{list-style:none}html{font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,Helvetica Neue,Arial,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{font-family:inherit;line-height:inherit}*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}hr{border-top-width:1px}img{border-style:solid}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#9ca3af}input::placeholder,textarea::placeholder{color:#9ca3af}[role=button],button{cursor:pointer}table{border-collapse:collapse}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}button,input,optgroup,select,textarea{padding:0;line-height:inherit;color:inherit}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.bg-black{--tw-bg-opacity:1;background-color:rgba(0,0,0,var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgba(255,255,255,var(--tw-bg-opacity))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgba(31,41,55,var(--tw-bg-opacity))}.hover\:bg-purple-600:hover{--tw-bg-opacity:1;background-color:rgba(124,58,237,var(--tw-bg-opacity))}.bg-opacity-80{--tw-bg-opacity:0.8}.border-current{border-color:currentColor}.border-black,.hover\:border-black:hover{--tw-border-opacity:1;border-color:rgba(0,0,0,var(--tw-border-opacity))}.hover\:border-purple-600:hover{--tw-border-opacity:1;border-color:rgba(124,58,237,var(--tw-border-opacity))}.rounded-sm{border-radius:.125rem}.rounded{border-radius:.25rem}.border-solid{border-style:solid}.border{border-width:1px}.block{display:block}.flex{display:flex}.table{display:table}.grid{display:grid}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.flex-none{flex:none}.flex-grow{flex-grow:1}.flex-shrink-0{flex-shrink:0}.font-normal{font-weight:400}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.h-0{height:0}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.m-auto{margin:auto}.my-24{margin-top:6rem;margin-bottom:6rem}.mx-auto{margin-left:auto;margin-right:auto}.mt-1{margin-top:.25rem}.ml-1{margin-left:.25rem}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-3{margin-top:.75rem}.mr-3{margin-right:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mb-5{margin-bottom:1.25rem}.mt-8{margin-top:2rem}.mr-10{margin-right:2.5rem}.mt-12{margin-top:3rem}.mr-20{margin-right:5rem}.max-w-1280{max-width:1280px}.overflow-hidden{overflow:hidden}.p-4{padding:1rem}.p-6{padding:1.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.absolute{position:absolute}.relative{position:relative}.top-0{top:0}.right-0{right:0}*{--tw-shadow:0 0 transparent;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,0.5);--tw-ring-offset-shadow:0 0 transparent;--tw-ring-shadow:0 0 transparent}.text-center{text-align:center}.text-black{--tw-text-opacity:1;color:rgba(0,0,0,var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgba(31,41,55,var(--tw-text-opacity))}.text-green-600{--tw-text-opacity:1;color:rgba(5,150,105,var(--tw-text-opacity))}.hover\:text-black:hover{--tw-text-opacity:1;color:rgba(0,0,0,var(--tw-text-opacity))}.hover\:text-white:hover{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}.hover\:text-blue-400:hover{--tw-text-opacity:1;color:rgba(96,165,250,var(--tw-text-opacity))}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.tracking-tight{letter-spacing:-.025em}.w-full{width:100%}.z-10{z-index:10}.gap-4{grid-gap:1rem;gap:1rem}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}@-webkit-keyframes spin{to{transform:rotate(1turn)}}@keyframes spin{to{transform:rotate(1turn)}}@-webkit-keyframes ping{75%,to{transform:scale(2);opacity:0}}@keyframes ping{75%,to{transform:scale(2);opacity:0}}@-webkit-keyframes pulse{50%{opacity:.5}}@keyframes pulse{50%{opacity:.5}}@-webkit-keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}.pagination .page-numbers{display:block;padding:.5rem .75rem;margin:0 1px;line-height:1.25}.pagination .page-numbers.current,.pagination .page-numbers:hover{color:#fff;background-color:#343a40;border-color:#343a40}.main-title{position:relative}.main-title:before{left:0}.main-title:after,.main-title:before{content:"";position:absolute;bottom:50%;height:2px;width:50%;background:#222;z-index:-1}.main-title:after{right:0}.main-title .main-title-inner{padding:0 20px;background:#fff}@media (min-width:640px){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:768px){.md\:flex{display:flex}.md\:flex-col{flex-direction:column}.md\:ml-0{margin-left:0}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (min-width:1024px){.lg\:inline-block{display:inline-block}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:items-center{align-items:center}.lg\:flex-grow{flex-grow:1}.lg\:h-full{height:100%}.lg\:mt-0{margin-top:0}.lg\:p-4{padding:1rem}.lg\:w-auto{width:auto}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width:1280px){.xl\:px-0{padding-left:0;padding-right:0}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}} -------------------------------------------------------------------------------- /assets/build/js/editor.js: -------------------------------------------------------------------------------- 1 | !function(r){var n={};function o(e){if(n[e])return n[e].exports;var t=n[e]={i:e,l:!1,exports:{}};return r[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.m=r,o.c=n,o.d=function(e,t,r){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(o.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)o.d(r,n,function(e){return t[e]}.bind(null,n));return r},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=3)}([,,,function(e,t,r){"use strict";r.r(t);t=r(4)},function(e,t,r){}]); -------------------------------------------------------------------------------- /assets/build/js/main.js: -------------------------------------------------------------------------------- 1 | !function(t){var r={};function u(e){if(r[e])return r[e].exports;var n=r[e]={i:e,l:!1,exports:{}};return t[e].call(n.exports,n,n.exports,u),n.l=!0,n.exports}u.m=t,u.c=r,u.d=function(e,n,t){u.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},u.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},u.t=function(n,e){if(1&e&&(n=u(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var t=Object.create(null);if(u.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var r in n)u.d(t,r,function(e){return n[e]}.bind(null,r));return t},u.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return u.d(n,"a",n),n},u.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},u.p="",u(u.s=0)}([function(e,n,t){"use strict";t.r(n);n=t(1),n=t(2)},function(e,n,t){},function(e,n){function u(e,n){for(var t=0;t { 12 | if ( this.menuItems.hasClass( 'is-open' ) ) { 13 | this.menuItems.addClass( 'h-0' ); 14 | this.menuItems.removeClass( 'is-open max-h-full h-full' ); 15 | } else { 16 | this.menuItems.addClass( 'is-open max-h-full h-full' ); 17 | this.menuItems.removeClass( 'h-0' ); 18 | } 19 | } ) 20 | } 21 | } 22 | } 23 | 24 | new Menu(); 25 | })(jQuery); 26 | -------------------------------------------------------------------------------- /assets/src/js/editor.js: -------------------------------------------------------------------------------- 1 | import '../sass/editor.scss'; 2 | -------------------------------------------------------------------------------- /assets/src/js/main.js: -------------------------------------------------------------------------------- 1 | import '../sass/main.scss'; 2 | 3 | import './components/menu'; 4 | -------------------------------------------------------------------------------- /assets/src/sass/components/_pagination.scss: -------------------------------------------------------------------------------- 1 | .pagination { 2 | .page-numbers { 3 | display: block; 4 | padding: .5rem .75rem; 5 | margin: 0 1px; 6 | line-height: 1.25; 7 | 8 | &.current, 9 | &:hover { 10 | color: $white; 11 | background-color: $gray-dark-secondary; 12 | border-color: $gray-dark-secondary; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /assets/src/sass/components/_products.scss: -------------------------------------------------------------------------------- 1 | .main-title { 2 | position: relative; 3 | 4 | &::before { 5 | content: ""; 6 | position: absolute; 7 | bottom: 50%; 8 | left: 0; 9 | height: 2px; 10 | width: 50%; 11 | background: $gray-dark; 12 | z-index: -1; 13 | } 14 | &::after { 15 | content: ""; 16 | position: absolute; 17 | bottom: 50%; 18 | right: 0; 19 | height: 2px; 20 | width: 50%; 21 | background: $gray-dark; 22 | z-index: -1; 23 | } 24 | 25 | .main-title-inner { 26 | padding: 0 20px; 27 | background: $white; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /assets/src/sass/editor.scss: -------------------------------------------------------------------------------- 1 | // To be added. 2 | -------------------------------------------------------------------------------- /assets/src/sass/main.scss: -------------------------------------------------------------------------------- 1 | @import "tailwindcss/base"; 2 | @import "tailwindcss/components"; 3 | @import "tailwindcss/utilities"; 4 | 5 | // Components 6 | @import "settings/colors"; 7 | @import "components/pagination"; 8 | @import "components/products"; 9 | 10 | -------------------------------------------------------------------------------- /assets/src/sass/settings/_colors.scss: -------------------------------------------------------------------------------- 1 | $white: #fff; 2 | 3 | $gray-dark-secondary: #343a40; 4 | $gray-dark: #222; 5 | -------------------------------------------------------------------------------- /assets/src/svgs/cart.svg: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /assets/src/svgs/hamburger.svg: -------------------------------------------------------------------------------- 1 | 2 | Menu 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/src/svgs/user.svg: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /assets/src/svgs/wishlist.svg: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /assets/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | purge: [ 3 | // Paths to your templates... 4 | "../**.php", 5 | "../**/**.php", 6 | "./src/js/**.js" 7 | ], 8 | darkMode: false, // or 'media' or 'class' 9 | theme: { 10 | maxWidth: { 11 | '1280': '1280px' 12 | } 13 | }, 14 | variants: { 15 | extend: {}, 16 | }, 17 | plugins: [], 18 | } 19 | -------------------------------------------------------------------------------- /assets/webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Webpack configuration. 4 | */ 5 | const path = require('path') 6 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') 7 | const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin') 8 | const cssnano = require('cssnano') 9 | const { CleanWebpackPlugin } = require('clean-webpack-plugin') 10 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin') 11 | 12 | // JS Directory path. 13 | const JS_DIR = path.resolve(__dirname, 'src/js') 14 | const IMG_DIR = path.resolve(__dirname, 'src/img') 15 | const BUILD_DIR = path.resolve(__dirname, 'build') 16 | 17 | const entry = { 18 | main: JS_DIR + '/main.js', 19 | editor: JS_DIR + '/editor.js' 20 | } 21 | 22 | const output = { 23 | path: BUILD_DIR, 24 | filename: 'js/[name].js' 25 | } 26 | 27 | const plugins = (argv) => [ 28 | new CleanWebpackPlugin({ 29 | cleanStaleWebpackAssets: ('production' === argv.mode) 30 | }), 31 | 32 | new MiniCssExtractPlugin({ 33 | filename: 'css/[name].css' 34 | }), 35 | ] 36 | 37 | const rules = [ 38 | { 39 | test: /\.js$/, 40 | include: [JS_DIR], 41 | exclude: /node_modules/, 42 | use: 'babel-loader' 43 | }, 44 | { 45 | test: /\.scss$/, 46 | exclude: /node_modules/, 47 | use: [ 48 | MiniCssExtractPlugin.loader, 49 | 'css-loader', 50 | 'postcss-loader', 51 | 'sass-loader', 52 | ] 53 | }, 54 | { 55 | test: /\.(png|jpg|svg|jpeg|gif|ico)$/, 56 | use: { 57 | loader: 'file-loader', 58 | options: { 59 | name: '[path][name].[ext]', 60 | publicPath: 'production' === process.env.NODE_ENV ? '../' : '../../' 61 | } 62 | } 63 | }, 64 | { 65 | test: /\.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, 66 | exclude: [IMG_DIR, /node_modules/], 67 | use: { 68 | loader: 'file-loader', 69 | options: { 70 | name: '[path][name].[ext]', 71 | publicPath: 'production' === process.env.NODE_ENV ? '../' : '../../' 72 | } 73 | } 74 | } 75 | ] 76 | 77 | /** 78 | * Since you may have to disambiguate in your webpack.config.js between development and production builds, 79 | * you can export a function from your webpack configuration instead of exporting an object 80 | * 81 | * @param {string} env environment ( See the environment options CLI documentation for syntax examples. https://webpack.js.org/api/cli/#environment-options ) 82 | * @param argv options map ( This describes the options passed to webpack, with keys such as output-filename and optimize-minimize ) 83 | * @return {{output: *, devtool: string, entry: *, optimization: {minimizer: [*, *]}, plugins: *, module: {rules: *}, externals: {jquery: string}}} 84 | * 85 | * @see https://webpack.js.org/configuration/configuration-types/#exporting-a-function 86 | */ 87 | module.exports = (env, argv) => ({ 88 | 89 | entry: entry, 90 | 91 | output: output, 92 | 93 | /** 94 | * A full SourceMap is emitted as a separate file ( e.g. main.js.map ) 95 | * It adds a reference comment to the bundle so development tools know where to find it. 96 | * set this to false if you don't need it 97 | */ 98 | devtool: 'source-map', 99 | 100 | module: { 101 | rules: rules 102 | }, 103 | 104 | optimization: { 105 | minimizer: [ 106 | new OptimizeCssAssetsPlugin({ 107 | cssProcessor: cssnano 108 | }), 109 | 110 | new UglifyJsPlugin({ 111 | cache: false, 112 | parallel: true, 113 | sourceMap: false 114 | }) 115 | ] 116 | }, 117 | 118 | plugins: plugins(argv), 119 | 120 | externals: { 121 | jquery: 'jQuery' 122 | } 123 | }) 124 | -------------------------------------------------------------------------------- /classes/class-advanced-woocommerce-theme-assets.php: -------------------------------------------------------------------------------- 1 | setup_hooks(); 13 | } 14 | 15 | public function setup_hooks() { 16 | 17 | /** 18 | * Actions. 19 | */ 20 | add_action( 'wp_enqueue_scripts', [ $this, 'register_styles' ] ); 21 | add_action( 'wp_enqueue_scripts', [ $this, 'register_scripts' ] ); 22 | 23 | } 24 | 25 | /** 26 | * Register Styles 27 | * 28 | * @return void 29 | */ 30 | public function register_styles() { 31 | 32 | wp_register_style( 'main-css', AWT_BUILD_CSS_URI . '/main.css', [], filemtime( AWT_BUILD_CSS_DIR_PATH . '/main.css' ), 'all' ); 33 | wp_enqueue_style( 'main-css' ); 34 | 35 | } 36 | 37 | /** 38 | * Register Scripts 39 | * 40 | * @return void 41 | */ 42 | public function register_scripts() { 43 | 44 | wp_register_script( 'main-js', AWT_BUILD_JS_URI . '/main.js', ['jquery'], filemtime( AWT_BUILD_JS_DIR_PATH . '/main.js' ), 'all' ); 45 | wp_enqueue_script( 'main-js' ); 46 | 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /classes/class-advanced-woocommerce-theme-menus.php: -------------------------------------------------------------------------------- 1 | setup_hooks(); 14 | } 15 | 16 | public function setup_hooks() { 17 | 18 | /** 19 | * Actions. 20 | */ 21 | add_action( 'init', [ $this, 'register_menus' ] ); 22 | } 23 | 24 | public function register_menus() { 25 | register_nav_menus([ 26 | 'awt-header-menu' => esc_html__( 'Header Menu', 'advanced-woocommerce-theme' ), 27 | 'awt-footer-menu' => esc_html__( 'Footer Menu', 'advanced-woocommerce-theme' ), 28 | ]); 29 | } 30 | 31 | /** 32 | * Get the menu id by menu location. 33 | * 34 | * @param string $location 35 | * 36 | * @return integer 37 | */ 38 | public function get_menu_id( $location ) { 39 | 40 | // Get all locations 41 | $locations = get_nav_menu_locations(); 42 | 43 | // Get object id by location. 44 | $menu_id = $locations[$location]; 45 | 46 | return ! empty( $menu_id ) ? $menu_id : ''; 47 | 48 | } 49 | 50 | /** 51 | * Get all child menus that has given parent menu id. 52 | * 53 | * @param array $menu_array Menu array. 54 | * @param integer $parent_id Parent menu id. 55 | * 56 | * @return array Child menu array. 57 | */ 58 | public function get_child_menu_items( $menu_array, $parent_id ) { 59 | 60 | $child_menus = []; 61 | 62 | if ( ! empty( $menu_array ) && is_array( $menu_array ) ) { 63 | 64 | foreach ( $menu_array as $menu ) { 65 | if ( intval( $menu->menu_item_parent ) === $parent_id ) { 66 | array_push( $child_menus, $menu ); 67 | } 68 | } 69 | } 70 | 71 | return $child_menus; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /classes/class-advanced-woocommerce-theme.php: -------------------------------------------------------------------------------- 1 | setup_hooks(); 13 | } 14 | 15 | public function setup_hooks() { 16 | 17 | /** 18 | * Actions. 19 | */ 20 | add_action( 'after_setup_theme', [ $this, 'setup_theme' ] ); 21 | 22 | } 23 | 24 | /** 25 | * Setup theme. 26 | * 27 | * @return void 28 | */ 29 | public function setup_theme() { 30 | 31 | /** 32 | * Let WordPress manage the document title. 33 | * By adding theme support, we declare that this theme does not use a 34 | * hard-coded tag in the document head, and expect WordPress to 35 | * provide it for us. 36 | */ 37 | add_theme_support( 'title-tag' ); 38 | 39 | /** 40 | * Custom logo. 41 | * 42 | * @see Adding custom logo 43 | * @link https://developer.wordpress.org/themes/functionality/custom-logo/#adding-custom-logo-support-to-your-theme 44 | */ 45 | add_theme_support( 46 | 'custom-logo', 47 | [ 48 | 'header-text' => [ 49 | 'site-title', 50 | 'site-description', 51 | ], 52 | 'height' => 100, 53 | 'width' => 400, 54 | 'flex-height' => true, 55 | 'flex-width' => true, 56 | ] 57 | ); 58 | 59 | /** 60 | * Adds Custom background panel to customizer. 61 | * 62 | * @see Enable Custom Backgrounds 63 | * @link https://developer.wordpress.org/themes/functionality/custom-backgrounds/#enable-custom-backgrounds 64 | */ 65 | add_theme_support( 66 | 'custom-background', 67 | [ 68 | 'default-color' => 'ffffff', 69 | 'default-image' => '', 70 | 'default-repeat' => 'no-repeat', 71 | ] 72 | ); 73 | 74 | /** 75 | * Enable support for Post Thumbnails on posts and pages. 76 | * 77 | * Adding this will allow you to select the featured image on posts and pages. 78 | * 79 | * @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/ 80 | */ 81 | add_theme_support( 'post-thumbnails' ); 82 | 83 | add_theme_support( 'post-formats', array( 'aside', 'gallery' ) ); 84 | 85 | 86 | /** 87 | * Register image sizes. 88 | */ 89 | add_image_size( 'featured-thumbnail', 350, 233, true ); 90 | 91 | 92 | // Add theme support for selective refresh for widgets. 93 | /** 94 | * WordPress 4.5 includes a new Customizer framework called selective refresh 95 | * 96 | * Selective refresh is a hybrid preview mechanism that has the performance benefit of not having to refresh the entire preview window. 97 | * 98 | * @link https://make.wordpress.org/core/2016/03/22/implementing-selective-refresh-support-for-widgets/ 99 | */ 100 | add_theme_support( 'customize-selective-refresh-widgets' ); 101 | 102 | // Add default posts and comments RSS feed links to head. 103 | add_theme_support( 'automatic-feed-links' ); 104 | 105 | /** 106 | * Switch default core markup for search form, comment form, comment-list, gallery, caption, script and style 107 | * to output valid HTML5. 108 | */ 109 | add_theme_support( 110 | 'html5', 111 | [ 112 | 'search-form', 113 | 'comment-form', 114 | 'comment-list', 115 | 'gallery', 116 | 'caption', 117 | 'script', 118 | 'style', 119 | ] 120 | ); 121 | 122 | // Gutenberg theme support. 123 | 124 | /** 125 | * Some blocks in Gutenberg like tables, quotes, separator benefit from structural styles (margin, padding, border etc…) 126 | * They are applied visually only in the editor (back-end) but not on the front-end to avoid the risk of conflicts with the styles wanted in the theme. 127 | * If you want to display them on front to have a base to work with, in this case, you can add support for wp-block-styles, as done below. 128 | * @see Theme Styles. 129 | * @link https://make.wordpress.org/core/2018/06/05/whats-new-in-gutenberg-5th-june/, https://developer.wordpress.org/block-editor/developers/themes/theme-support/#default-block-styles 130 | */ 131 | add_theme_support( 'wp-block-styles' ); 132 | 133 | /** 134 | * Some blocks such as the image block have the possibility to define 135 | * a “wide” or “full” alignment by adding the corresponding classname 136 | * to the block’s wrapper ( alignwide or alignfull ). A theme can opt-in for this feature by calling 137 | * add_theme_support( 'align-wide' ), like we have done below. 138 | * 139 | * @see Wide Alignment 140 | * @link https://developer.wordpress.org/block-editor/developers/themes/theme-support/#wide-alignment 141 | */ 142 | add_theme_support( 'align-wide' ); 143 | 144 | /** 145 | * Loads the editor styles in the Gutenberg editor. 146 | * 147 | * Editor Styles allow you to provide the CSS used by WordPress’ Visual Editor so that it can match the frontend styling. 148 | * If we don't add this, the editor styles will only load in the classic editor ( tiny mice ) 149 | * 150 | * @see https://developer.wordpress.org/block-editor/developers/themes/theme-support/#editor-styles 151 | */ 152 | add_theme_support( 'editor-styles' ); 153 | /** 154 | * 155 | * Path to our custom editor style. 156 | * It allows you to link a custom stylesheet file to the TinyMCE editor within the post edit screen. 157 | * 158 | * Since we are not passing any parameter to the function, 159 | * it will by default, link the editor-style.css file located directly under the current theme directory. 160 | * In our case since we are passing 'assets/build/css/editor.css' path it will use that. 161 | * You can change the name of the file or path and replace the path here. 162 | * 163 | * @see add_editor_style( 164 | * @link https://developer.wordpress.org/reference/functions/add_editor_style/ 165 | */ 166 | add_editor_style( 'assets/build/css/editor.css' ); 167 | 168 | /** 169 | * For using custom WooCommerce template overrides 170 | * 171 | * @see https://github.com/woocommerce/woocommerce/wiki/Declaring-WooCommerce-support-in-themes 172 | */ 173 | add_theme_support( 'woocommerce' ); 174 | 175 | /** 176 | * Set the maximum allowed width for any content in the theme, 177 | * like oEmbeds and images added to posts 178 | * 179 | * @see Content Width 180 | * @link https://codex.wordpress.org/Content_Width 181 | */ 182 | global $content_width; 183 | if ( ! isset( $content_width ) ) { 184 | $content_width = 1240; 185 | } 186 | } 187 | 188 | } 189 | -------------------------------------------------------------------------------- /footer.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Footer template 4 | * 5 | * @package Advanced WooCommerce Theme 6 | */ 7 | 8 | $menu_class = new Advanced_Woocommerce_Theme_Menus(); 9 | $footer_menu_id = $menu_class->get_menu_id( 'awt-footer-menu' ); 10 | $footer_menus = wp_get_nav_menu_items( $footer_menu_id ); 11 | ?> 12 | 13 | 14 | <footer> 15 | <div class="footer bg-gray-800 p-6 text-white"> 16 | <div class="container mx-auto"> 17 | <div class="footer-text flex-none md:flex items-center justify-between"> 18 | <p>© Codeytek Academy 2020</p> 19 | <ul> 20 | <?php 21 | 22 | 23 | if ( ! empty( $footer_menus ) && is_array( $footer_menus ) ) { 24 | foreach ( $footer_menus as $footer_menu ) { 25 | printf( 26 | '<li><a class="block mt-4 lg:inline-block lg:mt-0 text-white hover:text-blue-400 mr-10" href="%1$s">%2$s</a></li>', 27 | esc_url( $footer_menu->url ), 28 | esc_html( $footer_menu->title ) 29 | ); 30 | } 31 | 32 | } 33 | 34 | ?> 35 | </ul> 36 | </div> 37 | <ul class="social-links mt-8 flex align-center"> 38 | <li><a href="https://www.facebook.com/codeytek" class="fa fa-facebook" target="_blank"> 39 | <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 18 18"> 40 | <path d="M2.637 18h5.87v-6.398H6.399v-2.11h2.11V6.855a2.64 2.64 0 012.637-2.636h2.636v2.11h-2.11c-.581 0-1.054.472-1.054 1.054v2.11h3.07l-.351 2.109h-2.719V18h4.746A2.64 2.64 0 0018 15.363V2.637A2.64 2.64 0 0015.363 0H2.637A2.64 2.64 0 000 2.637v12.726A2.64 2.64 0 002.637 18zM1.055 2.637c0-.871.71-1.582 1.582-1.582h12.726c.871 0 1.582.71 1.582 1.582v12.726c0 .871-.71 1.582-1.582 1.582h-3.691v-4.289h2.555l.703-4.219h-3.258V7.383h3.164V3.164h-3.691a3.696 3.696 0 00-3.692 3.691v1.582h-2.11v4.22h2.11v4.288H2.637c-.871 0-1.582-.71-1.582-1.582zm0 0" 41 | fill="#fff"></path> 42 | </svg> 43 | </a></li> 44 | <li class="ml-2 mt-1"><a href="https://twitter.com/codeytek" target="_blank"> 45 | <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 18 18"> 46 | <path d="M18 1.969c-1.133.05-1.11.047-1.234.058L17.434.11s-2.09.774-2.622.91C13.418-.233 11.348-.288 9.864.622 8.653 1.367 8 2.648 8.22 4.145 5.859 3.816 3.87 2.695 2.3.813L1.805.215l-.371.68a4.142 4.142 0 00-.442 2.773c.078.379.207.742.387 1.082l-.426-.164-.05.71c-.051.724.19 1.567.644 2.259.129.195.293.406.5.617l-.219-.031.27.816a3.957 3.957 0 002.039 2.36c-.953.402-1.719.66-2.98 1.074L0 12.773l1.066.582c.407.223 1.844.965 3.262 1.188 3.156.496 6.711.09 9.102-2.063 2.015-1.816 2.675-4.394 2.539-7.082-.02-.406.09-.793.312-1.093.45-.594 1.715-2.332 1.719-2.336zm-2.559 1.707a2.712 2.712 0 00-.523 1.777c.137 2.707-.602 4.809-2.191 6.246-1.864 1.672-4.864 2.332-8.235 1.801-.61-.094-1.242-.309-1.762-.523 1.06-.364 1.875-.688 3.196-1.313l1.84-.871-2.036-.129c-.972-.062-1.785-.535-2.28-1.305.265-.011.519-.054.773-.129l1.941-.539-1.957-.48a2.915 2.915 0 01-2.164-2.086c.195.05.422.09.793.125l1.809.18L3.21 5.313c-1.035-.81-1.45-2.02-1.145-3.184 3.227 3.348 7.012 3.094 7.395 3.183-.086-.816-.086-.816-.11-.894-.488-1.727.583-2.602 1.067-2.898 1.008-.622 2.605-.715 3.715.308a.95.95 0 00.867.23c.27-.066.496-.14.71-.218l-.452 1.3h.582c-.11.15-.242.325-.399.536zm0 0" 47 | fill="#fff"></path> 48 | </svg> 49 | </a></li> 50 | <li class="ml-2 mt-1"><a href="https://youtube.com/ImranSayedDev" class="fa fa-youtube" target="_blank"> 51 | <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 18 18"> 52 | <g fill="#fff"> 53 | <path d="M2.637 13.71h12.726A2.64 2.64 0 0018 11.075V2.637A2.64 2.64 0 0015.363 0H2.637A2.64 2.64 0 000 2.637v8.437a2.64 2.64 0 002.637 2.637zM1.055 2.638c0-.871.71-1.582 1.582-1.582h12.726c.871 0 1.582.71 1.582 1.582v8.437c0 .871-.71 1.582-1.582 1.582H2.637c-.871 0-1.582-.71-1.582-1.582zm0 0"></path> 54 | <path d="M6.363 3.324v7.168l6.348-3.644zm1.055 1.79l3.144 1.75-3.144 1.804zm0 0"></path> 55 | </g> 56 | </svg> 57 | </a></li> 58 | <li class="ml-2"><a href="https://www.instagram.com/codeytek_academy/" class="fa fa-instagram" 59 | target="_blank"> 60 | <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 18 18"> 61 | <g fill="#fff"> 62 | <path d="M2.637 18h12.726A2.64 2.64 0 0018 15.363V2.637A2.64 2.64 0 0015.363 0H2.637A2.64 2.64 0 000 2.637v12.726A2.64 2.64 0 002.637 18zM1.055 2.637c0-.871.71-1.582 1.582-1.582h12.726c.871 0 1.582.71 1.582 1.582v12.726c0 .871-.71 1.582-1.582 1.582H2.637c-.871 0-1.582-.71-1.582-1.582zm0 0"></path> 63 | <path d="M9 13.746A4.751 4.751 0 0013.746 9 4.751 4.751 0 009 4.254 4.751 4.751 0 004.254 9 4.751 4.751 0 009 13.746zM9 5.31A3.696 3.696 0 0112.691 9 3.696 3.696 0 019 12.691 3.696 3.696 0 015.309 9 3.696 3.696 0 019 5.309zm0 0M14.273 5.309c.872 0 1.582-.711 1.582-1.582 0-.872-.71-1.582-1.582-1.582-.87 0-1.582.71-1.582 1.582 0 .87.711 1.582 1.582 1.582zm0-2.11a.53.53 0 01.528.528.53.53 0 01-.528.527.53.53 0 01-.527-.527.53.53 0 01.527-.528zm0 0"></path> 64 | </g> 65 | </svg> 66 | </a></li> 67 | </ul> 68 | </div> 69 | </div> 70 | 71 | </footer> 72 | </div> 73 | </div> 74 | <?php wp_footer(); ?> 75 | </body> 76 | </html> 77 | -------------------------------------------------------------------------------- /front-page.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Front Page 4 | * 5 | * @package Advance WooCommerce Theme 6 | */ 7 | 8 | get_header(); 9 | 10 | ?> 11 | <div id="primary"> 12 | <main id="main" class="site-main max-w-1280 m-auto mt-4 lg:p-4" role="main"> 13 | <?php get_template_part( '/template-parts/front-page/products' ); ?> 14 | </main> 15 | </div> 16 | <?php 17 | get_footer(); 18 | -------------------------------------------------------------------------------- /functions.php: -------------------------------------------------------------------------------- 1 | <?php 2 | 3 | if ( ! defined( 'AWT_DIR_PATH' ) ) { 4 | define( 'AWT_DIR_PATH', untrailingslashit( get_template_directory() ) ); 5 | } 6 | 7 | if ( ! defined( 'AWT_DIR_URI' ) ) { 8 | define( 'AWT_DIR_URI', untrailingslashit( get_template_directory_uri() ) ); 9 | } 10 | 11 | if ( ! defined( 'AWT_BUILD_URI' ) ) { 12 | define( 'AWT_BUILD_URI', untrailingslashit( get_template_directory_uri() ) . '/assets/build' ); 13 | } 14 | 15 | if ( ! defined( 'AWT_BUILD_PATH' ) ) { 16 | define( 'AWT_BUILD_PATH', untrailingslashit( get_template_directory() ) . '/assets/build' ); 17 | } 18 | 19 | if ( ! defined( 'AWT_BUILD_JS_URI' ) ) { 20 | define( 'AWT_BUILD_JS_URI', untrailingslashit( get_template_directory_uri() ) . '/assets/build/js' ); 21 | } 22 | 23 | if ( ! defined( 'AWT_BUILD_JS_DIR_PATH' ) ) { 24 | define( 'AWT_BUILD_JS_DIR_PATH', untrailingslashit( get_template_directory() ) . '/assets/build/js' ); 25 | } 26 | 27 | if ( ! defined( 'AWT_BUILD_IMG_URI' ) ) { 28 | define( 'AWT_BUILD_IMG_URI', untrailingslashit( get_template_directory_uri() ) . '/assets/build/src/img' ); 29 | } 30 | 31 | if ( ! defined( 'AWT_BUILD_CSS_URI' ) ) { 32 | define( 'AWT_BUILD_CSS_URI', untrailingslashit( get_template_directory_uri() ) . '/assets/build/css' ); 33 | } 34 | 35 | if ( ! defined( 'AWT_BUILD_CSS_DIR_PATH' ) ) { 36 | define( 'AWT_BUILD_CSS_DIR_PATH', untrailingslashit( get_template_directory() ) . '/assets/build/css' ); 37 | } 38 | 39 | if ( ! defined( 'AWT_BUILD_LIB_URI' ) ) { 40 | define( 'AWT_BUILD_LIB_URI', untrailingslashit( get_template_directory_uri() ) . '/assets/build/library' ); 41 | } 42 | 43 | // File Includes 44 | require_once AWT_DIR_PATH . '/classes/class-advanced-woocommerce-theme-assets.php'; 45 | new Advanced_Woocommerce_Theme_Assets(); 46 | require_once AWT_DIR_PATH . '/classes/class-advanced-woocommerce-theme-menus.php'; 47 | new Advanced_Woocommerce_Theme_Menus(); 48 | require_once AWT_DIR_PATH . '/classes/class-advanced-woocommerce-theme.php'; 49 | new Advanced_Woocommerce_Theme(); 50 | 51 | 52 | -------------------------------------------------------------------------------- /header.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Header template. 4 | * 5 | * @package Advanced WooCommerce Theme 6 | */ 7 | ?> 8 | <!doctype html> 9 | <html <?php language_attributes(); ?>> 10 | <head> 11 | <meta charset="<?php bloginfo( 'charset' ); ?>"> 12 | <meta name="viewport" 13 | content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> 14 | <meta http-equiv="X-UA-Compatible" content="ie=edge"> 15 | <?php wp_head(); ?> 16 | </head> 17 | <body <?php body_class(); ?>> 18 | 19 | <?php 20 | if ( function_exists( 'wp_body_open' ) ) { 21 | wp_body_open(); 22 | } 23 | ?> 24 | 25 | <div id="page" class="site"> 26 | <header id="masthead" class="site-header" role="banner"> 27 | <?php get_template_part( 'template-parts/header/nav' ); ?> 28 | </header> 29 | <div id="content" class="site-content"> 30 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | <?php 2 | 3 | get_header(); 4 | 5 | ?> 6 | <div id="primary"> 7 | <main id="main" class="site-main mt-5" role="main"> 8 | <div class="flex text-center">Hello world</div> 9 | </main> 10 | </div> 11 | <?php 12 | 13 | get_footer(); 14 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | /* 2 | Theme Name: Advanced WooCommerce Theme 3 | Theme URI: https://codeytek.com/advanced-woocommerce-theme 4 | Author: Imran Sayed 5 | Author URI: https://codeytek.com/about 6 | Description: WordPress blogging theme 7 | Tags: woocommerce, theme 8 | Version: 1.0 9 | Requires at least: 5.0 10 | Tested up to: 5.4 11 | Requires PHP: 7.0 12 | License: GNU General Public License v2 or later 13 | License URI: http://www.gnu.org/licenses/gpl-2.0.html 14 | Text Domain: advanced-woocommerce-theme 15 | This theme, like WordPress, is licensed under the GPL. 16 | Use it to make something cool, have fun, and share what you've learned with others. 17 | */ 18 | -------------------------------------------------------------------------------- /template-parts/front-page/pagination.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Pagination Template. 4 | * 5 | * To be used inside the WordPress loop. 6 | * 7 | * @package 8 | */ 9 | 10 | if ( ! empty( $args['total_pages'] ) && ! empty( $args['current_page'] ) ) { 11 | if ( 1 < $args['total_pages'] ) { 12 | ?> 13 | <div class="flex justify-center mt-12 pagination"> 14 | <?php 15 | echo paginate_links( [ 16 | 'base' => get_pagenum_link( 1 ) . '%_%', 17 | 'format' => 'page/%#%', 18 | 'current' => $args['current_page'], 19 | 'total' => $args['total_pages'], 20 | 'prev_text' => __( '« Prev', 'advanced-woocommerce-theme' ), 21 | 'next_text' => __( 'Next »', 'advanced-woocommerce-theme' ), 22 | ] ); 23 | ?> 24 | </div> 25 | <?php 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /template-parts/front-page/product.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | <<<<<<< HEAD 4 | * Product Card Template. 5 | * 6 | * @package Advance WooCommerce Theme 7 | */ 8 | 9 | $product_id = get_the_ID(); 10 | $product = wc_get_product( $product_id ); 11 | $product_thumbnail_url = get_the_post_thumbnail_url( $product_id, 'medium' ); 12 | $product_title = get_the_title(); 13 | $product_link = get_the_permalink(); 14 | $sale_price = $product->get_sale_price(); 15 | $regular_price = $product->get_regular_price(); 16 | $is_product_on_sale = $product->is_on_sale(); 17 | $is_product_in_stock = $product->is_in_stock(); 18 | $product_price = $product->get_price_html(); 19 | $discount_percent = ! empty( $sale_price ) ? floatval( ( $regular_price - $sale_price ) / $regular_price * 100 ) : 0; 20 | 21 | if ( $is_product_in_stock ) { 22 | ?> 23 | <div class="product mb-5"> 24 | <div class="relative"> 25 | <a href="<?php echo esc_url( $product_link ); ?>"> 26 | <img src="<?php echo esc_url( $product_thumbnail_url ); ?>" alt="<?php echo esc_html( $product_title ); ?>"> 27 | </a> 28 | <?php 29 | if ( $is_product_on_sale ) { 30 | ?> 31 | <span class="absolute top-0 right-0 px-3 py-1 text-white capitalize bg-black z-10 bg-opacity-80"> 32 | Sale 33 | </span> 34 | <?php 35 | } 36 | ?> 37 | </div> 38 | <div class="product-info"> 39 | <h3 class="product-title mt-3 font-medium text-gray-800"><?php echo esc_html( $product_title ); ?></h3> 40 | <h6 class="product-price text-gray-800 font-semibold mr-3 mb-5"> 41 | <span class="product-price mr-2"><?php echo wp_kses_post( $product_price ); ?> 42 | <?php 43 | if ( ! empty( $discount_percent ) ) { 44 | ?> 45 | <span class="product-discount text-green-600 font-bold text-sm font-normal"> 46 | <?php echo round( $discount_percent, 2 ); ?>% OFF 47 | </span> 48 | <?php 49 | } 50 | ?> 51 | </span> 52 | </h6> 53 | <div> 54 | <a href="<?php echo esc_url( sprintf( '%1$s/?add-to-cart=%2$s', site_url(), $product_id ) ); ?>" class="px-3 py-1 rounded-sm mr-3 text-sm border-solid border border-current hover:bg-purple-600 hover:text-white hover:border-purple-600"> 55 | Add to cart 56 | </a> 57 | </div> 58 | </div> 59 | </div> 60 | <?php 61 | } 62 | -------------------------------------------------------------------------------- /template-parts/front-page/products.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Products Template 4 | * 5 | * @package Advanced WooCommerce Theme 6 | */ 7 | 8 | // Current page. 9 | $paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1; 10 | 11 | $args = [ 12 | 'post_type' => 'product', 13 | 'posts_per_page' => 10, 14 | 'paged' => $paged, 15 | 'order' => 'DESC', 16 | 'post_status' => 'publish', 17 | ]; 18 | 19 | $the_query = new WP_Query( $args ); 20 | 21 | ?> 22 | <div class="products container mx-auto my-24 px-4 xl:px-0"> 23 | <h2 class="products-main-title main-title mb-5 text-xl text-center uppercase"> 24 | <span class="main-title-inner">Products</span> 25 | </h2> 26 | <?php 27 | if ( $the_query->have_posts() ) { 28 | ?> 29 | <div class="grid grid-cols-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-4 gap-4"> 30 | <?php 31 | while ( $the_query->have_posts() ) : $the_query->the_post(); 32 | get_template_part( 'template-parts/front-page/product' ); 33 | endwhile; 34 | ?> 35 | </div> 36 | <?php 37 | 38 | // Pagination 39 | $total_pages = $the_query->max_num_pages; 40 | get_template_part( 'template-parts/front-page/pagination', null, [ 41 | 'total_pages' => $total_pages, 42 | 'current_page' => $paged, 43 | ] ); 44 | } 45 | ?> 46 | </div> 47 | -------------------------------------------------------------------------------- /template-parts/header/nav.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Header Navigation. 4 | * 5 | * @package Advance WooCommerce Theme 6 | */ 7 | 8 | $menu_class = new Advanced_Woocommerce_Theme_Menus(); 9 | $header_menu_id = $menu_class->get_menu_id( 'awt-header-menu' ); 10 | $header_menus = wp_get_nav_menu_items( $header_menu_id ); 11 | 12 | ?> 13 | 14 | <nav class="bg-white p-4 max-w-1280 m-auto"> 15 | <div class="flex items-center justify-between flex-wrap container mx-auto"> 16 | <div class="flex items-center flex-shrink-0 text-black mr-20"> 17 | <div class="mr-2"> 18 | <?php the_custom_logo(); ?> 19 | </div> 20 | <div> 21 | <p class="font-semibold text-xl tracking-tight"> 22 | <a class="" href="<?php echo home_url(); ?>"><?php echo get_bloginfo( 'name', 'display' ); ?></a> 23 | </p> 24 | <p><?php bloginfo( 'description' ); ?></p> 25 | </div> 26 | </div> 27 | <div class="block lg:hidden"> 28 | <button id="menu-btn" class="flex items-center px-3 py-2 border rounded text-black border-black hover:text-black hover:border-black"> 29 | <img width="16" height="16" src="<?php echo AWT_DIR_URI . '/assets/src/svgs/hamburger.svg'; ?>" alt="wishlist"> 30 | </button> 31 | </div> 32 | <div id="menu-items" class="h-0 w-full overflow-hidden lg:h-full flex-grow lg:flex lg:items-center lg:w-auto"> 33 | <div class="text-sm font-medium uppercase lg:flex-grow"> 34 | <?php 35 | 36 | if ( ! empty( $header_menus ) && is_array( $header_menus ) ) { 37 | foreach ( $header_menus as $header_menu ) { 38 | printf( 39 | '<a class="block mt-4 lg:inline-block lg:mt-0 text-black hover:text-black mr-10" href="%1$s">%2$s</a>', 40 | esc_url( $header_menu->url ), 41 | esc_html( $header_menu->title ) 42 | ); 43 | } 44 | 45 | } 46 | ?> 47 | 48 | </div> 49 | <div class="text-sm font-medium md:flex"> 50 | <a href="#responsive-header" class="block mt-4 flex items-center md:flex-col lg:mt-0 text-black hover:text-black mr-10"> 51 | <img width="18" height="18" src="<?php echo AWT_DIR_URI . '/assets/src/svgs/user.svg'; ?>" alt="user"> 52 | <div class="ml-1 md:ml-0"> 53 | Profile 54 | </div> 55 | </a> 56 | <a href="#responsive-header" class="block mt-4 flex items-center md:flex-col lg:mt-0 text-black hover:text-black mr-10"> 57 | <img width="18" height="18" src="<?php echo AWT_DIR_URI . '/assets/src/svgs/wishlist.svg'; ?>" alt="wishlist"> 58 | <div class="ml-1 md:ml-0"> 59 | Wishlist 60 | </div> 61 | </a> 62 | <a class="block mt-4 flex items-center md:flex-col lg:mt-0 text-black hover:text-black mr-10" href="/cart/"> 63 | <img width="18" height="18" src="<?php echo AWT_DIR_URI . '/assets/src/svgs/cart.svg'; ?>" alt="cart"> 64 | <div class="ml-1 md:ml-0"> 65 | <span>Bag</span> 66 | <span class="ml-1">(<?php echo WC()->cart->get_cart_contents_count(); ?>)</span> 67 | </div> 68 | </a> 69 | </div> 70 | </div> 71 | </div> 72 | </nav> 73 | -------------------------------------------------------------------------------- /woocommerce/single-product.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * The Template for displaying all single products 4 | * 5 | * This template can be overridden by copying it to yourtheme/woocommerce/single-product.php. 6 | * 7 | * HOWEVER, on occasion WooCommerce will need to update template files and you 8 | * (the theme developer) will need to copy the new files to your theme to 9 | * maintain compatibility. We try to do this as little as possible, but it does 10 | * happen. When this occurs the version of the template file will be bumped and 11 | * the readme will list any important changes. 12 | * 13 | * @see https://docs.woocommerce.com/document/template-structure/ 14 | * @package WooCommerce\Templates 15 | * @version 1.6.4 16 | */ 17 | 18 | if ( ! defined( 'ABSPATH' ) ) { 19 | exit; // Exit if accessed directly 20 | } 21 | 22 | get_header( 'shop' ); ?> 23 | 24 | <?php 25 | /** 26 | * woocommerce_before_main_content hook. 27 | * 28 | * @hooked woocommerce_output_content_wrapper - 10 (outputs opening divs for the content) 29 | * @hooked woocommerce_breadcrumb - 20 30 | */ 31 | do_action( 'woocommerce_before_main_content' ); 32 | ?> 33 | 34 | <?php while ( have_posts() ) : ?> 35 | <?php the_post(); ?> 36 | 37 | <?php wc_get_template_part( 'content', 'single-product' ); ?> 38 | 39 | <?php endwhile; // end of the loop. ?> 40 | 41 | <?php 42 | /** 43 | * woocommerce_after_main_content hook. 44 | * 45 | * @hooked woocommerce_output_content_wrapper_end - 10 (outputs closing divs for the content) 46 | */ 47 | do_action( 'woocommerce_after_main_content' ); 48 | ?> 49 | 50 | <?php 51 | /** 52 | * woocommerce_sidebar hook. 53 | * 54 | * @hooked woocommerce_get_sidebar - 10 55 | */ 56 | do_action( 'woocommerce_sidebar' ); 57 | ?> 58 | 59 | <?php 60 | get_footer( 'shop' ); 61 | 62 | /* Omit closing PHP tag at the end of PHP files to avoid "headers already sent" issues. */ 63 | -------------------------------------------------------------------------------- /woocommerce/single-product/title.php: -------------------------------------------------------------------------------- 1 | <?php 2 | /** 3 | * Single Product title 4 | * 5 | * This template can be overridden by copying it to yourtheme/woocommerce/single-product/title.php. 6 | * 7 | * HOWEVER, on occasion WooCommerce will need to update template files and you 8 | * (the theme developer) will need to copy the new files to your theme to 9 | * maintain compatibility. We try to do this as little as possible, but it does 10 | * happen. When this occurs the version of the template file will be bumped and 11 | * the readme will list any important changes. 12 | * 13 | * @see https://docs.woocommerce.com/document/template-structure/ 14 | * @package WooCommerce\Templates 15 | * @version 1.6.4 16 | */ 17 | 18 | if ( ! defined( 'ABSPATH' ) ) { 19 | exit; // Exit if accessed directly. 20 | } 21 | 22 | the_title( '<h1 class="product_title entry-title">', '</h1>' ); 23 | --------------------------------------------------------------------------------