Stroyka

Thank you for purchasing my theme. If you have any questions that are beyond the scope of this help file, please feel free to email via my user page contact form here. Thanks so much!

Features

  • 100% Responsive Layout
  • LTR/RTL supported
  • HTML5 and CSS3
  • Bootstrap 4
  • SASS
  • CSS3 Animation
  • SVG Icons
  • Font Awesome Icons
  • BEM syntax
  • Roboto Google Font
  • Compatible with all major browsers
  • Grid / List products view
  • Quickview
  • 2 Variants of the home page
  • 3 Variants of the product page
  • 3 Variants of the blog page layout
  • 2 Variants of the post page layout

Getting Started

Preparation

  1. Make sure your system has installed Node.js.
  2. Open a terminal window and go to the Sources directory.
  3. Run the npm install command. This command will load all necessary dependencies specified in the package.json file.
  4. Then run the npm install -g @angular/cli command to install Angular CLI (if not yet installed).

Build Project

To start a local HTTP server and runs the build process with change tracking run the command:

ng serve

To build for production, run the command:

ng build --prod

After executing the command, the compiled project will be located in the dist directory.

For a complete list of available Angular CLI commands, go to this link.

Server Side Rendering

To build server and client version of angular application, and start an ExpressJS server run the command:

npm run dev:ssr

Other useful commands related to SSR:

  • serve:ssr - Starts an ExpressJS server;
  • build:ssr - Builds client and server version of the angular application and build ExpressJS server;
  • start:ssr - Builds production version of the server, application and starts ExpressJS server.

Project Structure

Project source codes are in the Sources directory. After downloading and unpacking the package, the Sources directory will look like this:

Sources/
    e2e/
    src/
        app/
        assets/
        data/
        environments/
        fake-server/
        scss/
        svg/
        favicon.ico
        index.html
        main.server.ts
        main.ts
        polyfills.ts
        sprite-config.json
        styles.scss
        test.ts
        tslint.json
    .editorconfig
    .gitignore
    angular.json
    browserslist
    karma.conf.js
    package.json
    package-lock.json
    README.md
    server.ts
    tsconfig.app.json
    tsconfig.json
    tsconfig.server.json
    tsconfig.spec.json
    tslint.json

Here is a description of the most important files and directories of the project:

  • Sources/src/app/ - Contains components, modules, directives, etc. More details below.
  • Sources/src/assets/ - This directory contains static files such as images, fonts, svg sprite, etc.
  • Sources/src/data/ - Contains stubs data for the template, products, categories, etc.
  • Sources/src/fake-server/ - Contains functionality needed for demo purposes only. More details in the Integration section.
  • Sources/src/scss/ - Contains project styles. More details are described in the SCSS Files section.
  • Sources/src/svg/ - Contains separate SVG files.
  • Sources/src/sprite-config.json - This files contains necessary information to build svg sprite. See the SVG section for details.

App directory

Sources/src/app is a main directory with the following structure:

components/
modules/
    account/
    blocks/
    blog/
    footer/
    header/
    mobile/
    shop/
    site/
    widgets/
pages/
shared/
app.component.html
app.component.scss
app.component.ts
app.module.ts
app-routing.module.ts

Modules Description

  • modules/account/account.module.ts
    Contains customer pages (currently only login page).

  • modules/blocks/blocks.nodule.ts
    This module contains components used as a construction bricks for pages (mainly used on the home page).

  • modules/blog/blog.nodule.ts
    Blog related components, pages, etc.

  • modules/footer/footer.nodule.ts
    Contains the components used in the footer of the site.

  • modules/header/header.nodule.ts
    Contains the components used in the header of the site.

  • modules/mobile/mobile.nodule.ts
    Contains the components used in the mobile header and mobile menu.

  • modules/shop/shop.nodule.ts
    Contains shop pages (category, product, cart, checkout, etc.) and components.

  • modules/site/site.nodule.ts
    Contains rest site pages (About Us, Contact Us, etc.).

  • modules/widgets/widgets.nodule.ts
    Contains components used in the shop or/and blog sidebar.

  • shared/shared.module.ts
    Contains components, services, directives, interfaces used across all template.

  • app.module.ts
    The main module contains home and "not found" pages.

Simplified routing scheme

/ (homeComponent)
    /shop (modules/shop/shop.module#ShopModule)
        ... shop routes
    /blog (modules/blog/blog.module#BlogModule)
        ... blog routes
    /account (modules/account/account.module#AccountModule)
        ... account routes
    /site (modules/site/site.module#SiteModule)
        ... site routes

Third-Party Modules

This template uses four third-party modules:

The following libraries and frameworks are also used:

SCSS Files

The directory with SCSS files contains the following files and subdirectories:

scss/
   blocks/
   blog/
   common/
   components/
   filters/
   footer/
   header/
   mixins/
   pages/
   shop/
   themes/
   widgets/
   _custom.scss
   _custom-variables.scss
   _functions.scss
   _style.scss
   _variables.scss

You can make changes to any of these files.

To make it easier for you in the future to upgrade the template to the new version, we recommend (if possible) making changes only to _custom-variables.scss and _custom.scss files.

  • _custom-variables.scss - It is used to override the values of variables.
  • _custom.scss - Use to write your own scss code.

Predefined color schemes

To compile a template with one of the predefined color schemes, open the _custom-variables.scss file, then find and uncomment one of the following lines:

//@import 'themes/theme-red/theme-variables';
//@import 'themes/theme-blue/theme-variables';
//@import 'themes/theme-black/theme-variables';
//@import 'themes/theme-green/theme-variables';

After that, you need to rebuild the template.

LTR/RTL

The template supports two ways to use directions.

  1. If you need only one direction, LTR or RTL:

    Open src/scss/_custom-variables.scss, and define next variables:

    $direction:       ltr;   // specify the direction you need (ltr or rtl)
    $both-directions: false; // set to false to disable style compilation
                             // for two directions

    Then open src/index.html and specify value of the dir attribute (ltr or rtl) for <html> tag:

    ...
    <html lang="en" dir="ltr">
    ...
  2. If you need two directions simultaneously (your application will be available in at least two languages, one LTR and one RTL):

    Open src/app/app.component.ts and define your logic to determine the direction in the component constructor's function AppComponent. Then use the DirectionService service to set direction:

    constructor(
        ...
        private direction: DirectionService
    ) {
        const detectedDirection = 'rtl';
    
        this.direction.value = detectedDirection;
    }

NOTE: Currently, on-the-fly (after loading and initialization) direction switching (ltr <--> rtl) is not supported.

How does LTR/RTL support work?

The direction is controlled using two scss variables:

  • $direction - indicates direction. Possible values: ltr or rtl.
  • $both-directions - if true compiles styles for two directions, the $direction variable will be ignored. Possible values: true or false.

Some "magic" variables are also used, which change their value depending on the given direction value. The names of these variables are the same as the names of the Logical Properties (for example, variable $margin-inline-start). These variables should only be used in the direction mixin.

This example demonstrates how it works:

.alert {
    @include direction {
        #{$margin-inline-start}: 20px;
    }
}

Will be compiled to:

  • If $direction == ltr and $both-directions == false:

     .alert {
         margin-left: 20px;
     }
  • If $direction == rtl and $both-directions == false:

    .alert {
        margin-right: 20px;
    }
  • If $both-directions == true:

    [dir=ltr] .alert {
        margin-left: 20px;
    }
    [dir=rtl] .alert {
        margin-right: 20px;
    }

Currency

How to change currency?

  1. Open the src/app/app.component.ts file and find the following code:
this.currency.options = {
    code: 'USD',
    // display: 'symbol',
    // digitsInfo: '1.2-2',
    // locale: 'en-US'
};
  1. Replace 'USD' with the currency code you need.

How to change currency format?

There is currently no easy way to set an arbitrary currency format (for example: dot instead of comma). But Angular allows you to change the format of the currency in accordance with the specified locale. I think in most cases this is what you need.

Here is an example for the it (it_IT, Italy) locale:

$1,019.00 -> 1.019,00 €
  1. Open the src/app/app.module.ts file;
  2. Uncomment some parts of the code, as in the example below:
import { LOCALE_ID, NgModule } from '@angular/core';
import { registerLocaleData } from '@angular/common';
import localeIt from '@angular/common/locales/it';

registerLocaleData(localeIt, 'it');

// ...

@NgModule({
    // ...
    providers: [
        { provide: LOCALE_ID, useValue: 'it' }
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

SVG

How to add SVG icon?

Just put your file with SVG icon to the Sources/src/svg directory.

How to compile SVG sprite?

From the Sources directory, run the next command:

npm run sprite

After executing the command, you can find the SVG sprite on this path Sources/src/assets/images/sprite.svg.

How to use icons in the template?

To display the icon, you can use the app-icon component. For example, we have an SVG icon named my-icon.svg, whose width and height equals to 20px:

<app-icon name="my-icon" size="20x20"></app-icon>

If the width and height are equal, then we can simplify the size property as follows:

<app-icon name="my-icon" size="20"></app-icon>

What is the sprite-config.json file for?

sprite-config.json file contains configuration for svg-sprite module. It used to build svg sprite. You can get more info here.

Fonts

We used three fonts in this template:

  • Roboto (Google Web Font: https://fonts.google.com/specimen/Roboto) The main font used in the template.

  • FontAwesome (https://fontawesome.com/) Icon Font to display some icons in the template.

  • stroyka (src/assets/fonts/stroyka) Custom Icon Font to display some icons in the template. It is used only in Edge to solve performance issue associated with rendering a huge amount of SVG icons.

Update

To simplify the process of updating the template, I recommend using the tools for visual comparison and merging, such as:

Integration

First of all, you should understand that the process of integrating a template with your server is likely to be quite time-consuming and complicated. This is due to the fact that in the world of online stores there are no uniform standards. Some use integers as identifiers, others use UUID strings, and the third use something else. Nevertheless, I took some steps to simplify this process as much as possible. This will be discussed in this section.

API services

The template has several services that are designed to interact with the server by sending AJAX requests. All of them are in the src/app/shared/api directory. All you need is to replace requests to a fake server with requests to your (real) server. You can find out more about the fake server below. Also below, several solutions are proposed if the composition of the fields of your data differs from the interfaces used in the template.

export class ProductsService {
    constructor(private http: HttpClient) { }

    getProduct(productSlug: string): Observable<Product> {
        const url = `https://example.com/api/products/${productSlug}.json`;

        return this.http.get<Product>(url);
    }
}

Related links:

Root service

The root service is designed to generate the URLs used in the template (src/app/shared/services/root.service.ts). You can use it to quickly change the URLs of products, categories, etc. For example, this is how you can get the product URL containing its identifier:

export class RootService {
    product(product: Partial<Product>): string {
        return `/products/${product.id}`;
    }
}

Remember to make the appropriate changes to the routes and components.

What if my product fields are different from those used in the template?

Well, I can offer several solutions to this problem (they are sorted by complexity, from simple to complex):

  • Property mapping;
  • Custom fields;
  • Modify product interface.

Property mapping

This method involves converting data when it is received from the server:

export class ProductsService {
    getProduct(productSlug): Observable<Product> {
        const url = `https://example.com/api/products/${productSlug}.json`;

        return this.http.get<Product>(url).pipe(
            map(product => {
                return {
                    id: product.productId,
                    name: product.description,
                    images: product.pictures,
                    ...
                };
            })
        );
    }
}

Custom fields

If there is no suitable property in the product interface, you can use custom fields:

export class ProductsService {
    getProduct(productSlug): Observable<Product> {
        const url = `https://example.com/api/products/${productSlug}.json`;

        return this.http.get<Product>(url).pipe(
            map(product => {
                return {
                    ...
                    customFields: {
                        isbn: product.ISBN,
                    },
                };
            })
        );
    }
}

Modify product interface

And finally, the last and most labor-intensive way. Change the product interface and everything related to it throughout the template.

What is a fake server and why is it needed?

I think this will surprise many, but, as practice shows, this issue also needs to be clarified.

Typically, an Angular application generates HTML pages based on dynamic data received from the server. While the Angular template comes without server-side code. However, to demonstrate the capabilities of the template, we still need something that will process requests and serve as a data provider for the template, and it is for these purposes that I created a fake server that imitates the operation of a real server. You should not use it (and everything related to it) in a real application, it is only needed to demonstrate the capabilities of the template.

All code associated with a fake server is located in the src/fake-server directory. You can remove it.

Data flow on the example of a product page

It is assumed that if you bought this template, then you have sufficient knowledge to use it. But sometimes people buy it for the purpose of training or something else... I don’t know. This section exists for them and it describes how the data received from the server falls into the template.

So this is what happens when you open the http://localhost:4200/shop/products/ash-s-chainsaw-3.5kw page:

  1. First, Angular looks for a suitable route. In this case, it will be the route from the src/app/modules/shop/shop-routing.module.ts file:

    ...
    {
        path: 'products/:productSlug',
        component: PageProductComponent,
        data: {
            layout: 'standard',
            sidebarPosition: 'start'
        },
        resolve: {
            product: ProductResolverService
        },
    }
    ...

    You can learn more about the routes, their processing order, etc. from the official documentation.

  2. As you can see this route uses a pre-fetching component data:

    ...
    resolve: {
        product: ProductResolverService
    }
    ...

    I see no reason to copy the official documentation (Milestone 5: Route guards -> Resolve: pre-fetching component data). I will only say that you need to pay attention to these files:

    • src/app/modules/shop/resolvers/product-resolver.service.ts
      A service that implements the Resolve interface;
    • src/app/shared/api/shop.service.ts
      A service that communicates with the server.
  3. After all data is received and navigation is completed, Angular activates the PageProductComponent component. Now we can access the product data from the product property of the data object:

    export class PageProductComponent implements OnInit {
        product: Product;
    
        constructor(
            private route: ActivatedRoute,
        ) { }
    
        ngOnInit(): void {
            this.route.data.subscribe(data => {
                this.product = data.product;
            });
        }
    }
    • src/app/modules/shop/pages/page-product/page-product.component.ts
  4. Now we can access the product data from the template:

    <app-product [product]="product"></app-product>

    Pay attention to these files:

    • src/app/modules/shop/pages/page-product/page-product.component.html
    • src/app/shared/components/product/product.component.html

Changelog

Version 1.8.0 – February 8, 2020

  • Fixed: Same height of product cards in the block products carousel;
  • Updated:
    • Angular from 8.2.14 to 9.0.0;
    • ngx-owl-carousel-o form 2.0.1 to 2.0.3;
    • bootstrap form 4.3.1 to 4.4.1;
    • ngx-bootstrap form 5.2.0 to 5.3.2;
    • ngx-toastr form 11.2.1 to 11.3.3;
    • @fortawesome/fontawesome-free form 5.11.2 to 5.12.1.

Version 1.7.0 – December 19, 2019

  • Added: SEO friendly URLs for category and product pages;
  • Added: Workable sidebar filters;
  • Changed: Now, the products data comes into the templates through Angular services that receive data from a fake API server. This should simplify the process of integrating the template with your backend API;
  • Changed: The pages structure has been simplified. Now it is more like the page structure of a real online store;
  • Other: Added section "Integration" in the documentation.

Version 1.6.0 – November 14, 2019

  • Changed: Now the menu will be closed when you click on an item;
  • Fixed: Reverse image order in PhotoSwipe gallery for RTL direction;
  • Fixed: Broken "Shop By Category" button in RTL direction;
  • Updated: Angular from 8.1.0 to 8.2.13;
  • Updated: @fortawesome/fontawesome-free form 5.9.0 to 5.11.2;
  • Updated: ngx-bootstrap form 5.0.0 to 5.2.0;
  • Updated: ngx-owl-carousel-o form 1.1.5 to 2.0.1;
  • Updated: ngx-toastr form 10.0.4 to 11.2.1;
  • Other: Now instead of black images of stubs, more friendly gray images with an image resolution printed on them are used.

Version 1.5.1 – August 2, 2019

  • Fixed: "Price" and "Quantity" in the drop-down cart are displayed incorrectly in the RTL version.

Version 1.5.0 – July 7, 2019

  • Added: Off canvas filters on the shop page;
  • Updated: Angular from 8.0 to 8.1;
  • Updated: Angular Universal from 7.1 to 8.1;
  • Updated: ng5-slider form 1.2.1 to 1.2.4;
  • Updated: ngx-bootstrap form 4.3.0 to 5.0.0;
  • Updated: ngx-owl-carousel-o form 1.1.5 to 1.1.6.
  • Fixed: minor CSS issues.

Version 1.4.0 – June 14, 2019

  • Updated: Angular form 7 to 8;
  • Updated: @fortawesome/fontawesome-free form 5.8.1 to 5.9.0;
  • Updated: ng5-slider form 1.1.13 to 1.2.1;
  • Updated: ngx-toastr form 10.0.2 to 10.0.4;
  • Updated: ngx-bootstrap form 4.0.1 to 4.3.0;
  • Updated: ngx-owl-carousel-o form 1.1.0 to 1.1.5.

Version 1.3.0 – May 22, 2019

  • Added pipe currencyFormat, which now used instead of built-in pipe currency. This makes it easy to change the currency for the entire template;
  • Added sections "Currency" and "Update" in the documentation.

Version 1.2.0 – April 24, 2019

  • Added support for RTL.

Version 1.1.0 – April 04, 2019

  • Added: Server Side Rendering (SSR) for SEO;
  • Added: Five account pages (Dashboard, Edit Profile, Order History, Addresses, Change Password);
  • Added: PhotoSwipe gallery on the product page;
  • Updated: ngx-owl-carousel-o from 1.0.11 to 1.1.0;
  • Updated: ngx-bootstrap from 3.2.0 to 4.0.1;
  • Changed: Font Awesome is now used as a npm dependency;
  • Fixed: Unexpected execution of mouse click handlers while dragging the owl-carousel (now mouse click will be prevented);
  • Other minor changes.

Version 1.0.0 – March 25, 2019

  • Initial Release.

Credits