Tuesday, 28 June 2016

Getting started with fluent migrator


Migrations are a structured way to alter a database schema and are an alternative to creating lots of sql scripts that have to be run manually by every developer involved. It acts like the version control system for an application database allowing a team to easily share the schema. Also, it aides in the evolution of a schema used several physical databases

Fluentmigrator is the .net migration framework. Database migrations was first started in ruby on rails applications and soon afterwards every languages had their own migration framework.

Typically any modification onthe schema of a database typically involve dding/removing new table or columns to/from the database. So the basic concept of most migration frameworks is to just move the schema of the database forward or backward in time. Fluentmigrator is no different as it has both an “Up” method (ie: forward through time) and a “Down” method (ie. backwards through time).

The basic unit of fluent migrator is an abstract class called “Migration” that has two virtual methods “Up” and “Down”. So your migration classes will have to derive from these class and implement those methods. Also you will decorate your migration class with a migration attribute that takes a long value as identifier. Commonly, most programmers use time stamps such as YYYYMMDDHHMM as their identifier. This identifier is  used in sorting the execution order of the migration classes. Lower numbers are executed first. Migrations can also be run out of sequence depending on how they were checked in. For example if migration 12, 14 and 15 is checked in before migration 13 these migrations will be executed, but it does not prevent migration 13 from being executed.

Using FluentMigrator

To use fluentmigrator, install the nugget packages a class library of your project (It is highly recommended to install into a new class library specifically meant for migration).

Nuget packgaes

Install-Package FluentMigrator

Install-Package FluentMigrator.Tools

Then create a concrete class that derives from the abstract "Migration" class and implement the virtual methods as shown below.

    public class CreateTableMigration: Migration
        public override void Down()
            //Creates a table with three columns

             //creates an index on the FirstName column of the table.

            //creates an index call "Lst_Index" on the LastName column of the table.

            // Inserts data into the table using anonymous classes
                .Row(new {FirstName = "John", LastName = "Doe"})
                .Row(new {FirstName = "Jane", LastName = "Doe"});

             //Inserts a column called id if it does not already exist.
            if (!Schema.Table("Profiles").Column("Id").Exists())

        public override void Up()

The Fluent Interface

The fluent migrator fluent api allows one to create tables, columns, indexes, foreign keys, insert data into tables and most other constructs you will need to manipulate a database.

It works by populating a semantic model that is used to analyze and apply migrations in batch. The fluent api is available in the migration class with five (5) root expressions which are:
  1.  Create: This expression allows you to create a table, column, index, foreign key and     schema.
  2.  Delete: This expression allows one to delete a table, column, foreign key and a     schema. You can also delete multiple column using the “Column” extension method.
  3.              Alter: This expression allows you to alter existing tables and columns.
  4.              Execute: This expression allows you to execute a block of sql, or a script by name (ie. myscript.sql) or an embedded sql script.
    Note: To embed a sql script, add the file to your migration project and change the build action property to Embedded Resource.
  5. Rename: This expression allows you to rename a column or a table.

Data Expressions: This expressions allows you to insert a row into a table using an anonymous data type for the row contents.

                .Row(new {FirstName = "John", LastName = "Doe"})
                .Row(new {FirstName = "Jane", LastName = "Doe"});

AllRows Attribute

You use this attribute when you want to add a non-nullable column without specifying a default value. Note you can also you SetExistingRows() methods to add a predefined value to a newly created column.

//Update table
            Update.Table("Profiles").Set(new {DateJoined = DateTime.Today}).AllRows();

IfDatabase Expression

This expression allows you to execute conditional expression depending on the type of database in use. Currently fluentmigrator supports these databases:
  1.        SqlServer (this includes Sql Server 2005 and Sql Server 2008)
  2.        SqlServer2000
  3.             SqlServerCe
  4.         Postgres
  5.         MySql
  6.        Oracle
  7.       Jet
  8.      Sqlite.

Multiple databases type (as specified above) can be passed into the IfDatabase Expression.

IfDatabase("SqlServer", "Postgres")

Schema.Exists Expressions

This expression allows you to write conditional migrations that gets executed based on some preexisting schema. For example you can write a migration checking if some columns already exists before adding it.

if (!Schema.Table("Profiles").Column("Id").Exists())


Fluent migrator is a simple but powerful framework used in managing and migrating different versions of your database schema in c#. One  major advantage is that the code can be checked into a version control system as it provides a neat interface for growing or regressing your schema without resorting to multiple sql scripts.

In this post, I have tried to give you a brief but detailed introduction to fluent migrator. In the next we will go inroad into the various usage scenario and how one can use nant, commandline, fluentmigrator.runner to execute migration class. Thanks.


Saturday, 15 August 2015

Make sure you have a well documented schedule and time table for any project if you are an independent developer.

Although it was not of recent that I discovered the need for a written design document, schedule and plans. But it was until recently that I realized that I do need one. You know I pride myself with having a retentive memory, you know typically all those stuff that classic nerds are known for. So I guessed I kind of dismissed the idea that having a well written design document is not for me. But damn I was wrong.

Ways in which not having a well thought out design document can undermine your effort.

1. Lack of prioritization: This is one of the greatest disadvantage of not having a design document. This is because without any structure to all your work and effort, you will be implementing features on the spur of the moment basis and not on their importance basis. Without structure, your project will be haphazardly developed, without flow and unorganized. Also and most importantly, you will be consistently missing your schedules.

2. Lack of focus: Without a well written design document, I discovered in my experience that I usually lack focus. This is because most times even when you want to work on the project, you will be at loss at what feature set you will implement. And the result of these is lost productivity times and thereby leading to delayed project.

3. Improper implementation of your project feature set: Without a written document, most features in your project will be improperly implemented as it is not well thought out. One good thing about having a well written project document, is that it will help you think about the project that you are developing and on how its features will function under different conditions.

4. Lack of schedule and timeline for further project development and enhancement: Not having any design document often leads to incomplete feature set and can hamper further project development even after the project is completed and shipped and this often leads to having a software that does advance and grow as the requirements of its users changes.

5. Buggy Software: In the absence of any design document, the end product is usually buggy as there is no form or shape taken to develop the project and this goes on to affect the testing of the project and also it tends to lead to software that is often hard to extend and maintain.


Not having a well written document can undermine your efforts in various ways as a independent developer. Before embarking on any project of any considerable size, it is important that one  must do his due diligence and create a well written design document and not the usual vague on the memory on the go type that many people are usually okay with. 

Monday, 29 June 2015

Sending emails from a background thread in asp.net mvc

In the current application am working on I encountered a problem, and that is how to send an email from the backend. This problem was unique as there are currently no nuget project tackling this problem, because the available asp.net mvc email sending packages (like Mvc Mailer, Postal) can only send mail in the context of a request. In this post we are going to look at how to send mails in the background while making effective use of views to order and style your mail.

In this project, we are going to need 2 essential nuget packages: RazorEngine, PreMailer. So fire up your visual studio, create an asp.net mvc project and add the following package in nuget manager console.

Install-Package RazorEngine

This nuget package allows you to use razor to build robust template. Since we only want to be sending professional looking emails, we are going to use it in creating our message body so as to enable to style it appropriately instead of using string concatenation or ordinary text.

Install-Package Premailer.net

This nuget package will be used in converting page head style blocks to inline styles as most email clients dont render perfectly if you don't inline its css.

In this project, we are going to utilize Quartz, to schedule that our email to sent 5 minutes after it was created. So add Quartz also to your project

Install-Package Quartz

The next thing to do is to create a folder where your mail templates will live. Its not a must for you to create the folder inside the Views Directory but its advisable to create the folder where you can easily access it from the root of the AppDomain.

After that create a base mail layout inside the 'mails template' folder. This will serve as the layout for your emails, as it will help in the styling of the emails like the one shown below:

1:  @model dynamic  
2:  @using System.Web.Optimization  
3:  <!DOCTYPE html>  
4:  <html>  
5:  <head>  
6:    <style rel="stylesheet">  
7:      body {  
8:        background-color: #bbb;  
9:        font-family: arial helvetica sans-serif;  
10:        font-size: 16px;  
11:        line-height: 1.557;  
12:        margin: 0;  
13:        padding: 0;  
14:      }  
15:      .mailBody {  
16:        margin: 15px auto;  
17:        width: 750px;  
18:        padding: 0 10px 10px;  
19:        background-color: #fff;  
20:        -ms-border-radius: 5px;  
21:        -moz-border-radius: 5px;  
22:        -webkit-border-radius: 5px;  
23:        border-radius: 5px;  
24:      }  
25:      .header {  
26:        background-color: #2478BF;  
27:        margin: 0;  
28:        padding: 10px;  
29:      }  
30:      .logo {  
31:        text-align: center;  
32:        color: #fff;  
33:      }  
34:      .col-md-8 {  
35:        position: relative;  
36:        min-height: 1px;  
37:        padding-right: 15px;  
38:        padding-left: 15px;  
39:      }  
40:      .btn {  
41:        padding: 10px 15px;  
42:        display: block;  
43:        background-color: #2478BF;  
44:        color: #fff;  
45:        text-decoration: none;  
46:        text-align: center;  
47:        -ms-border-radius: 5px;  
48:        -moz-border-radius: 5px;  
49:        -webkit-border-radius: 5px;  
50:        border-radius: 5px;  
51:        border: 1px solid #206cac;  
52:      }  
53:      .col-md-offset-2 {  
54:        margin-left: 16.66666667%;  
55:      }  
56:      .container {  
57:        width: 750px;  
58:        margin: 0 auto;  
59:      }  
60:      .center {  
61:        width: 350px;  
62:        margin: 10px auto;  
63:      }  
64:      .clearfix:before,  
65:      .clearfix:after {  
66:        display: table;  
67:        content: " ";  
68:      }  
69:      .clearfix:after {  
70:        clear: both;  
71:      }  
72:      .float-right {  
73:        float: right;  
74:      }  
75:    </style>  
76:  </head>  
77:  <body class="container" style="background-color: #bbb;">  
78:    <div class="mailBody">  
79:      <header class="header">  
80:        <h3 class="logo">Welcome to <a href="http://oursite.com">Our site</a></h3>  
81:      </header>  
82:      <div>  
83:        @RenderBody()  
84:      </div>  
85:      <div class="clearfix">  
86:        <hgroup class="float-right">  
87:          <h5>Yours sincerely</h5>  
88:          <span>Kings, Admin</span>  
89:        </hgroup>  
90:      </div>  
91:    </div>  
92:  </body>  
93:  </html>  

The next thing to do is to go ahead and create view templates that will be used by the email sender to compile your emails.

1:  @using BackgroundMailSender.Common.MailWorker  
2:  @model Message  
3:  @{  
4:    Layout = "_MailLayout.cshtml";  
5:  }  
6:  <div>  
7:    @Message.Body  
8:  </div>  

Then lets create classes that we be using to pass message to our background sender. We will call the class Message.cs

1:  namespace BackgroundMailSender.Common.MailWorker  
2:  {  
3:    public class Message  
4:    {  
5:      public string Fullname { get; set; }  
6:      public string Body { get; set; }  
7:      public string Title { get; set; }  
8:      public string To { get; set; }  
9:    }  
10:  }  

//Here is the email class

 public class Email
        public Email(string to)
            if (!CommonHelper.IsValidEmail(to))
                throw new ArgumentNullException(to, "This is not a valid email address!");
            Priority = MailPriority.Normal;
            To = to;
        public string To { get; private set; }
        public string Message { get; set; }
        public MailPriority Priority { get; set; }
        public string Title { get; set; }

Here is our EmailWorker class.

1:  using System;  
2:  using System.IO;  
3:  using System.Net;  
4:  using System.Net.Mail;  
5:  using System.Threading.Tasks;  
6:  using System.Web.Hosting;  
7:  using MailEngine.MailWorker;  
8:  using RazorEngine;  
9:  using RazorEngine.Templating;;  
11:  namespace BackgroundMailSender.Common.MailWorker  
12:  {  
13:    public class EmailWorker  
14:    {  
15:      private const string EmailTemplatePath = "~/Views/EmailTemplates";  
16:      private string _templatePath = string.Empty;  
18:      public EmailWorker()  
19:      {  
20:        //Resolve virtual url to file path url  
21:        _templatePath = MapPath(EmailTemplatePath);  
23:        //Map the Layout path.  
24:        var mailLayoutPath = Path.Combine(_templatePath, "_MailLayout.cshtml");  
27:        //Add out layout template.  
28:        var layout = File.ReadAllText(mailLayoutPath);  
29:        Engine.Razor.AddTemplate("_MailLayout", layout);  
32:      }  
34:      /// <summary>  
35:      ///   Maps a virtual path to a physical disk path.  
36:      /// </summary>  
37:      /// <param name="path">The path to map. E.g. "~/bin"</param>  
38:      /// <returns>The physical path. E.g. "c:\inetpub\wwwroot\bin"</returns>  
39:      private string MapPath(string path)  
40:      {  
41:        if (HostingEnvironment.IsHosted)  
42:        {  
43:          //hosted  
44:          return HostingEnvironment.MapPath(path);  
45:        }  
46:        //not hosted. For example, run in unit tests  
47:        string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;  
48:        path = path.Replace("~/", "").TrimStart('/').Replace('/', '\\');  
49:        return Path.Combine(baseDirectory, path);  
50:      }  
52:      private Task Send(Email email)  
53:      {  
54:        Func<Task> funct = () =>  
55:        {  
56:          var message = new MailMessage  
57:          {  
58:            Body = email.Body,  
59:            IsBodyHtml = true,  
60:            Subject = email.Subject,  
61:            Priority = MailPriority.Normal  
62:          };  
63:          message.To.Add(email.To);  
65:          var smtp = new SmtpClient();  
66:          return smtp.SendMailAsync(message);  
67:        };  
69:        var task = Task.Run(funct);  
70:        return task;  
71:      }  
73:      /// <summary>  
74:      /// converts block level css to inline css  
75:      /// </summary>  
76:      /// <param name="razorResult"></param>  
77:      /// <returns>Inlined html</returns>  
78:      private string InlineCss(string razorResult)  
79:      {  
80:        //Create a new Premailer instance, note this can be done using Dependency injection.  
81:        var pm = new PreMailer.Net.PreMailer(razorResult);  
83:        //Inline css  
84:        var compileResult = pm.MoveCssInline(stripIdAndClassAttributes: true,  
85:          removeComments: true, removeStyleElements: true);  
87:        return compileResult.Html;  
88:      }  
91:      public Task SendMessage(Message mail)  
92:      {  
93:        var task = Task.Run(() =>  
94:        {  
95:          if (mail == null)  
96:            return Task.FromResult(0);  
98:          string commonTemplates = Path.Combine(_templatePath, "Message.cshtml");  
99:          string cshtml = File.ReadAllText(commonTemplates);  
101:          //Add a new message template.  
102:          Engine.Razor.AddTemplate("MessageTemplate", cshtml);  
104:          string result = Engine.Razor.RunCompile("CommonTemplates", typeof (Message),  
105:            mail);  
107:          //Use Premailer.net to inline css  
108:          var inlineResult = InlineCss(result);  
110:          var email = new Email  
111:          {  
112:            To = mail.To,  
113:            Body = inlineResult,  
114:            Subject = mail.Title  
115:          };  
117:          return Send(email);  
118:        });  
119:        return task;  
120:      }  
121:    }  
122:  }  

Notice that in the constructor that the main mail layout was added. This class has 2 major private methods: InlineCss() and Send(). 

The InlineCss method inlines the block level styles in the mail layout into the html 'styles' tag using the Premailer.net which we added in the beginning. While the SendMessage sends the message using the good old 'System.Net.Mail'.

Another class method worth pointing out at is the SendMessage() public method, this method takes in the Message you are sending, compiles it with the prescribed template calls the InlineCss method and then sends out the message by calling the Send() private method. This method serves as the controller  in the mailer service.

Finally add the system.net.mail configuration in your config file.

1:   <system.net>  
2:       <mailSettings>  
3:        <!--Specify a pick up directory for testing-->  
4:        <smtp from="Kings &lt;admin@oursite.com&gt;" deliveryMethod="SpecifiedPickupDirectory">  
5:         <network host="localhost" />  
6:         <specifiedPickupDirectory pickupDirectoryLocation="c:\users\...\documents\emails" />  
7:        </smtp>  
8:       </mailSettings>  
9:     </system.net>  

There you have it a background email sender that you can use in any project, be it console, winforms, wpf or asp.net project. Hope it helps someone. Here is the full source code in github. Here is the email I sent using the background sender

Feel free and download and play with source code

Sunday, 7 December 2014

Making use of parent selectors, selector chaining and namespaces in sass.


In the last post, we looked at nesting, mixins, placeholders, variables and partials. In this post we are going to continue from where we stopped by looking at the parent selector, selector chaining and the use of namespaces so chill and enjoy the ride.

Using parent selector

Though the use of parent selector is not what you will do most of the time in your day to day usage of the sass preprocessor framework, yet parent selectors can come in handy sometimes. So whats' a parent selector by the way? To answer this question, we will use an example, lets imagine that you are working on a project using a combination of Sass and Modernizr but you want to a particular style to be applied only when some class name exists (or not exist) in the in the root of the document (You that's where Modernizr adds all its classes) or some place higher up in the document tree. Yet you are deep within the document tree. So how do you apply your style only when this pre-condition is met? By using the parent selector. Correct!. Yes!!! (cheesy, I know). Let's see how it works with this example


   display: inline-block;
   position: relative;

      background: #edac12;
      font-size: .85em;

      .gradient &{
         background: rgba(123, 34, 22, .6);


   display: inline-block;
   position: relative;

.content .half{
   background: #edac12;
   font-size: .85em;

.gradient .content half{
   background: rgba(123, 34, 22, .6);

Now if you look at the sass part of the code, you will notice in the third block where we used .gradient &, that's the parent selector in action.Notice also that in the third block of the Css code produced that it made the class name that came before the ampersand (&) the first selector. So in essence the style will be only applied when this class exist as a parent in the document hierarchy.


Chaining is a concept is usually used in Css (most often misused). It is process of identifying a particular element in the DOM with multiple selectors. Am I sounding like your physics teacher, sorry about that. Sometimes multiple selectors is needed to select an element, (maybe when you want to come out of the inheritance hell that you dug yourself into) to do so, simply chain your selector with the ampersand (&) like so &#id-selector. For example

   display: block;

      padding: 10px;
      margin: 0;

This css above will produce

display: block;

   padding: 10px;
   margin: 0;

Notice how .main and .side-content are chained together in the produced Css.

Using namespaces

To me namespace is among the coolest features in Sass. It allows one to shorten the number of codes he writes when writing Css key/value pair that belongs to one family. Before, if you wanted to use the long form in writing out the key/value pairs of properties such as font, you will write:

font-family: 'Open sans', verdana, sans-serif;
font-style: italic;
font-weight: 600;

But with sass namespace, you can write the same properties like this:

   family: 'Open sans', verdana, sans-serif;
   style: italic;
   weight: 600;

Isn't this cool. As you can see, because all the above properties belong to the font family, there is no need for the repetition anymore.


In this post, we have looked at some of the ways in which Sass can help out when authoring Css so as to produce efficient and when constructed Css. In the next post, we will take a look at some of the Compass and Sass color manipulation methods. Stay tuned!. Happy sassing!

Tuesday, 2 December 2014

Variables, Nesting, Mixins, Partials and Placeholders in Sass.


In the last post, we looked at the configuration settings of sass and how to compile a sass stylesheet in order to output a css stylesheet. In this post however we will start writing our first sass stylesheet. We will learn how to use variables, what nesting is all about, reusing code with mixins  partials among others. So buckle up and let the fun begin.

Using variables in sass.

In all main stream programming that are worth a dime, variables are some of the most commonly use concept. But what is a variable, you may ask? A variable is a temporary container which is used in storing a value during the execution of a portion of a program. It aides re-usability of the content of the variable so far that it is still in scope. Sorry if am using high sounding words that are over your head. What I meant is that before a variable can be used, it has to be available in memory so that codes being executed can access and make use of it. So to declare and use a variable in sass is simply easy just prefix the name of the variable with a dollar sign ($) and suffix it with a colon (:) then assign your value and end the statement with a semi-colon (;) like so: 

$primary: gray;

In the code above, we have declared a variable. To use the variable in our style just assign it in the default way in which a value is assigned in css like so:

   background-color: $primary;

Nesting of styles

In css, we can assess child element of a selector by separating the parent and child selector with space. In sass, this can be achieved by nesting of child styles within the parent style. An example is worth a thousand words in this scenario:

   margin: 0;
   padding: 0;

      list-style: none;
      display: inline-block;

Now we have nested the li style inside the ul above. When it is compiled, it will output the following:

   margin: 0;
   padding: 0;

ul li{
   list-style: none;
   display: inline-block;

Why this pattern  is better is because it reduces the number of codes which you have to write and that it gives more structure to your code making it more readable.

Understanding mixins

Mixins are a great way to reuse code in sass. Though functions and placeholders can be used in writing reusable code in sass (more on that in the future), mixins also is another way to reuse code and infact the most common way. Most of the compass stylesheet authoring framework codes was written in mixins. An example is given below:

//The declaration of mixin for media query
@mixin BorderRadius($top-left: 5px, $top-right: 5px, $bottom-left: 5px, $bottom-right: 5px){
   -webkit-border-radius: $top-left $top-right $bottom-left $bottom-right;
   -moz-border-radius: $top-left $top-right $bottom-left $bottom-right;
   -o-border-radius: $top-left $top-right $bottom-left $bottom-right;
   border-radius: $top-left $top-right $bottom-left $bottom-right;

In this code, we have created a cross browser mixin for the border-radius property (Note: Compass also has a border-radius mixin border-radius()). This mixin will aide in minimizing the number of code we have to write if say we have to use the border-radius property again in another block in the sass file. Let's put our mixin to use

 width: 80%;
 margin: 20px auto;
 background-color: #777;
 border: 1px solid #555;
 @include BorderRadius();

Notice in the above code that we did not specify any parameter in our mixin property. This is because when we declared our mixin function, we assigned to it default values which will be utilized in case we did not assign any value like in this case. Notice also that before calling the mixin function, we prefixed include keyword with the at (@). This is the norm as it tells sass to include the mixin called BorderRadius() in our content block. When compiled, the above style will output the following css.

     width: 80%;
     margin: 20px auto;
     background-color: #777;
     border: 1px solid #555;
   -webkit-border-radius: 5px 5px 5px 5px;
   -moz-border-radius: 5px 5px 5px 5px;
   -o-border-radius: 5px 5px 5px 5px;
   border-radius: 5px 5px 5px 5px;

Isn't it wonderful and cool.

Getting to Know Partials

Partials is a concept in sass used in dividing styles into different modules that will be assembled together when compiled. Not so long, css is usually written in a long monolithic block that defines the entire part of a page in one stylesheet. But with sass, you can separate your code into different files. This is very useful as it allows the developer to easily scan and locate different blocks in a file and to separate different parts of the stylesheet into related components. Another great advantage in using partials is that it allows code reuse as code written in one project can be reused in another thereby reducing the project development time. 

Making a partial file is fairly easy in sass, just prepend the name of the file with an underscore like so _partial.scss. To use the partial file, you have to import it into another file like so @import "partials/_partial.scss"; This code will then import and make the partial styles available for use in the file. When the file is compiled, the produced css will contain both the styles defined in the partial file and the one defined in the main file.

Making do with placeholders

When you want different parts of your document to share the same style in css, you list all the selectors for those parts separated by comma before assigning the block. This code sharing is accomplished in css by the use of a placeholder. A placeholder is just a css block. This means that any css block can serve as a placeholder in sass for example.

width: 20%;
float: left;

@extend .left;
font-size: .9em;

Here .left selector is serving as a code block and as a placeholder. When compiled, this will produce the following css

.left, .display-left{
   width: 20%;
   float: left;

   font-size: .9em;

But what if you just want the placeholder not to be outputted in the compiled css but to just hold a series of css properties that is shared between code blocks. Then instead of using a normal code block as your placeholder, prefix your placeholder name with a percentage symbol like so %side-content for example:

width: 20%;
display: inline-block;

@extend %side-content;
float: left;

@extend %side-content;
float: right;

When compiled, this will output the following css

.left, .right{
width: 20%;
display: inline-block;

float: left;

float: right;

One thing you will notice is that %side-content is no longer shown is the compiled css as it just served the purpose of a placeholder for us. Another thing  you will notice from the above codes is that a placeholder is referred to by using the extend keyword prefixed with the at (@) symbol followed by the name of the selector or placeholder.


We have looked at the various parts of the sass css preprocessor such as variables, nesting, mixins, partials and placeholders. We have seen that

  1. Variables are used in storing reusable css values
  2. Nesting are used in declaring css inheritance hierarchy.
  3. Mixins are used in writing reusable css code block
  4. Partials are used in separating the sass code into files of related components
  5. Placeholders are used in sharing code blocks or extending styles.
Happy sassing!