Select Page

Drupal Commerce Store Setup with Drupal 10

Setting Up a T-Shirt Store with drupal/commerce:^3.0

Drupal Commerce 3.x is optimized for Drupal 10 and introduces improvements in order processing, checkout flows, and tax/shipping handling. Below are the steps to set up your T-shirt store with automatic shipping and state tax calculations.

 

1. Install Drupal & Drupal Commerce

Run the following commands in your terminal to install Drupal and Drupal Commerce 3.x:

composer create-project drupal/recommended-project my_store cd my_store composer require drupal/commerce:^3.0

Enable required modules:

drush en commerce commerce_cart commerce_checkout commerce_store commerce_price commerce_product commerce_order commerce_tax commerce_shipping address -y drush updb

 

 

2. Configure the Store

Go to Commerce → Configuration → Store Settings → Stores and create a store with these settings:

  • Name: Your T-shirt Store
  • Address: 2000 S Mill Ave, Tempe, AZ 85282
  • Currency: USD
  • Default Country: United States

 

 

3. Add Products

Using Drupal Commerce 3 how to Create Product Variation Type (Size Attribute) for a “T-Shirt” product. Add an attribute called Size: Options: SM, MD, LG, XL, 2XL, 3XL

In Drupal Commerce 3.x, you can create a Product Variation Type with a Size attribute for your “T-Shirt” product using the following steps:

3.1 Create a Product Variation Type

  1. Go to Commerce → Configuration → Product Variation Types.
  2. Click “Add Product Variation Type”.
  3. Fill in the fields:
    • Label: T-Shirt Variations
    • ID: tshirt_variation (auto-generated)
    • Order item type: Default
  4. Click “Save”.

3.2 Add the “Size” Attribute

  1. Navigate to Commerce → Configuration → Product Attributes.
  2. Click “Add Product Attribute”.
  3. Fill in the details:
    • Label: Size
    • Attribute type: List (text)
    • Variation types: Select T-Shirt Variations
  4. Click “Save”.

3.3 Add Size Options

  1. After saving, go to the “Add values” section.
  2. Enter the size options one by one:
    • SM
    • MD
    • LG
    • XL
    • 2XL
    • 3XL
  3. Click “Save”.

3.4 Assign the Variation Type to the Product Type

  1. Navigate to Commerce → Configuration → Product Types.
  2. Click “Add Product Type”.
  3. Fill in:
    • Label: T-Shirt
    • Variation type: T-Shirt Variations
  4. Click “Save”.

Now, when adding a T-shirt product, you can create variations with different sizes!

 

 

4. Set Up Taxes for All 50 US States

Drupal Commerce 3.x has better tax integration. You can manually configure tax rates or use an external provider.

4.1 Enable Tax Calculation

  1. Navigate to Commerce → Configuration → Taxes.
  2. Click Add Tax Rate → Select “Sales Tax”.
  3. Choose US State-based Taxation.
  4. Set tax rates manually for all 50 states or use a tax provider like Avalara/TaxJar.

4.2 Automatic Tax Calculation (Optional)

For automatic tax calculation, install a tax provider module:

composer require drupal/commerce_avatax

Then, configure it under Commerce → Configuration → Taxes.

 

 

5. Configure Automatic Shipping Calculation

5.1 Install and Enable Commerce Shipping

composer require drupal/commerce_shipping drush en commerce_shipping -y

5.2 Configure Shipping

  1. Go to Commerce → Configuration → Shipping.
  2. Click “Add Shipping Method”.
  3. Set Origin Address as:
    • 2000 S Mill Ave, Tempe, AZ 85282
  4. Choose Flat Rate or install real-time shipping providers.

5.3 Real-time Shipping Rates

To enable FedEx, UPS, or USPS, install their modules:

composer require drupal/commerce_fedex drupal/commerce_ups drupal/commerce_usps

Then configure API credentials under Commerce → Configuration → Shipping.

 

 

6. Test Your Store

  1. Add a T-shirt to the cart.
  2. Proceed to checkout.
  3. Verify:
    • Taxes apply based on the shipping address.
    • Shipping costs are calculated from Tempe, AZ.

Your Drupal Commerce T-shirt store is now ready!

VIM Cheatsheet

vim {file} — Vi IMproved, a programmers text editor

Commands
i – insert mode
esc – get out of insert mode
:{number} – go to that line number 
:q
 – quit
:q! – force quit (no save)
:e! – discard edits to last saved state
:w – save document (write)
:wq – save and quit document
:ZZ – save and quit document

Moving Around
h, j, k, l — move cursor like arrow keys
$ – move cursor to end of current line
0 – move cursor to start of current line
w – move to next word
b – go back a word
ctrl f – page down
ctrl b – page up

Copy and Paste
y
 – yank or copy
yw – copy word
yy – copy whole line
#y – copy # of words. Example 5y (copy 5 words)
#yy – copy # of lines. Example 5yy (copy 5 lines)
p – paste

Undo and Delete
u – undo
x
 – delete current letter
dd – delete whole line
dw
 – delete next word
db – delete previous word
cw – delete next word and go into insert mode
cc – delete line and go into insert mode

Visual Mode
v – activate visual mode

Additional Shortcuts
shift i – go to start of curent line start insert mode
shift a – go to end of current line start insert mode
d arrowletter – delete word direction you point

AngularJS Form Validation

Form validation is an important part of web development. The user experience of your online forms will leave an impression on your visitors so it is important that you build great forms on your website. We will apply AngularJS to an existing online form.

 

Initial Form

Use the following HTML which uses Bootstrap CSS for formatting as a starting point. After you work through this example you can apply the changes to an existing form.

<div class="form-container">
<form name="myform" action="" method="post">
 
 <div class="form-group">
 <label for="firstname">First Name &#42;</label>
 <input type="text" name="firstname" placeholder="First Name">
 </div><!-- .form-group -->
 
 <div class="form-group">
 <label for="lastname">Last Name &#42;</label>
 <input type="text" name="lastname" placeholder="Last Name">
 </div><!-- .form-group -->
 
 <div class="form-group">
 <label for="email">Email Address &#42;</label>
 <input type="text" name="email" placeholder="Email Address">
 </div><!-- .form-group -->
 
 <button type="submit" class="btn btn-default">Submit</button>
</form>
</div><!-- #form-container -->

 

Add AngularJS to your page.

Add AngularJS to the bottom of your page. I also added in the Bootstrap CDN for CSS styling. The ng-app directive tells AngularJS that this is the root element of the AngularJS application. We will apply this to the div outside our form. The “form-container” class is optional we are using it for our demo. You will want to apply ng-app to a div outside your existing form.

<div class="form-container" ng-app>
<form ...>
  ...
</form>
</div><!-- #form-container -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

 

Add form validation.

Apply the following angular directives for form validation.

The ng-required directive indicates that a field is required. If a required field has no value the form will automatically have an ng-invalid class applied until the requirements are met.

  <div class="form-group">
    <label for="firstname">First Name &#42;</label>
    <input type="text" name="firstname" placeholder="First Name"
      ng-required="true">
  </div><!-- .form-group -->

 

Test form values

The ng-model directive binds an input, select, textarea (or custom form control) value to angular. Use the same field name and append user.fieldname to the front to bind it to the {{user}} data object which we will use to view our form values.

  <div class="form-group">
    <label for="firstname">First Name &#42;</label>
    <input type="text" name="firstname" placeholder="First Name"
      ng-model="user.firstname"
      ng-required="true">
  </div><!-- .form-group -->

For testing we add an alert div to output our {{user}} data which will display our ng-model form values. Angular uses the double curly brackets to display data. Add this above the submit button.

 <p class="alert alert-warning">Output: {{user}}</p>

 

Validate the email address

The ng-pattern directive is used on the email field for regular expression matching to validate the email address.

  <div class="form-group">
    <label for="email">Email Address &#42;</label>
    <input type="text" name="email" placeholder="Email Address"
      ng-model="user.email"
      ng-required="true"
      ng-pattern="/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/">
  </div><!-- .form-group -->

 

Disable the submit button until the form passes validation

The ng-disabled directive is applied to our submit button and will remain disabled until all the form validation passes.

  <button type="submit" class="btn btn-default" ng-disabled="myform.$invalid">Submit</button>

 

Final touches

We are adding additional user prompts to let the user know there is missing field data.

  • The ng-show directive will display this element until the requirements indicated in the property are met.
  • The field was marked as required in the previous step by ng-required=”true” property. The myform.firstname.$invalid condition will return true until there is a value added into the field.
  • We also added a $touched condition which means the field has been activated. This will not return true until the cursor has entered the field.
 <div class="form-group">
 <label for="firstname">First Name &#42;</label>
 <input type="text" name="firstname" placeholder="First Name"
 ng-model="user.firstname"
 ng-required="true">
 <div ng-show="myform.firstname.$invalid && myform.firstname.$touched"
 class="alert alert-warning">You must fill out your first name.</div>
 </div><!-- .form-group -->

 

Completed Form

Here is the code for the completed form.

<div class="form-container" ng-app>
<form name="myform" action="" method="post">
 
 <div class="form-group">
 <label for="firstname">First Name &#42;</label>
 <input type="text" name="firstname" placeholder="First Name"
 ng-model="user.firstname"
 ng-required="true">
 <div ng-show="myform.firstname.$invalid && myform.firstname.$touched"
 class="alert alert-warning">You must fill out your first name.</div>
 </div><!-- .form-group -->
 
 <div class="form-group">
 <label for="lastname">Last Name &#42;</label>
 <input type="text" name="lastname" placeholder="Last Name"
 ng-model="user.lastname"
 ng-required="true">
 <div ng-show="myform.lastname.$invalid && myform.lastname.$touched" 
 class="alert alert-warning">You must fill out your last name.</div>
 </div><!-- .form-group -->
 
 <div class="form-group">
 <label for="email">Email Address &#42;</label>
 <input type="text" name="email" placeholder="Email Address"
 ng-model="user.email"
 ng-required="true"
 ng-pattern="/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/">
 <div ng-show="myform.email.$invalid && myform.email.$touched" 
 class="alert alert-warning">This must be a valid email.</div>
 </div><!-- .form-group -->
 
 <!-- Display Form Values for Testing !!!Delete after testing!!! -->
 <p class="alert alert-warning">Output: {{user}}</p>
 
 <button type="submit" class="btn btn-default" ng-disabled="myform.$invalid">Submit</button>
</form>
</div><!-- #form-container -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

Drupal 7 Security Configuration

Prevent Browser caching
Put this at the top of your theme template.php file:

header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");

 

Download and enable the SecKit module:
https://www.drupal.org/project/seckit
There are some nice default settings. We can review tweak these settings as part of a security review when we have more time.

HTML Email Signatures

Creating an HTML email signature can be a deceivingly difficult process. After having to tackle this issue a number of times this is the best method I have found to get the correct formatting.

  1. Start with a clean HTML file. You only want the divs for your signature.
  2. Save to your desktop and view it in your browser.
  3. Use in-line styles and link to external images for any logos or graphics.
  4. When the format is correct you want to use a browser on Windows and Outlook.
  5. Select the formatted details in your browser then copy and paste it into Outlook. As you know Microsoft does preserve a lot of hidden formatting when you cut and paste into their products. You may have experience headaches with Word doing a lot of crazy formatting. But in this case it is helping us preserve the formatting for your signature.
  6. Send a test email out with your updated signature and view it in various email clients to confirm the formatting is correct.