Here is another tag helper cheat sheet, this time it is about creating simple custom tag helpers.

Again this document is not suitable for absolute beginners, so if you are seeking to understand tag helper creation forthe first time I would recommend the following articles:

- [Authoring tag helpers](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/authoring)
- [Creating custom ASP.NET Core Tag Helpers](http://www.davepaquette.com/archive/2015/06/22/creating-custom-mvc-6-tag-helpers.aspx)

[The full code is available on Github](https://github.com/MissaouiChedy/AspNetTagHelpersCheatSheet) if you want to build, run and hack the examples in this document.

## Super simple hello world tag helper

Tag helpers are represented by a C# class that inherits the `TagHelper` abstract class or implements the `ITagHelper` interface.

The `TagHelper.Process` method or its async equivalent `TagHelper.ProcessAsync` is typically overitten to contain the rendering logic.

The content that will substitute the tag helper is written into the `output` argument.

<script src="https://gist.github.com/MissaouiChedy/e763f5882b52ff5295a921684de6eff5.js"></script>

The previous `SimpleTagHelper` will be substituted by `<p>Very simple!</p>` and can be used as follows:

<script src="https://gist.github.com/MissaouiChedy/a28c1defad8266c669a111783da4602c.js"></script>
## Controlling the naming of the tag helper

You will notice that often times the tag helper C# class name ends with "TagHelper", this is actually a convention and is not mandatory.

The default html name of the tag helper is the class's name [kebab cased](http://wiki.c2.com/?KebabCase) with the "TagHelper" postfix removed, for example:

- `SimpleTagHelper` becomes `simple`
- `SuperSimpleTagHelper` becomes `super-simple`
- `LonglyNamed` (postfix optional) becomes `longly-named`

The name of the tag helper can be controlled with the `[HtmlTargetElement("some-name")]` attribute:

<script src="https://gist.github.com/MissaouiChedy/5c62033f377d2ecfabd21bfc3bf3f575.js"></script>

The html element represented by the previous class is `<arbitrary-name></arbitrary-name>`.

It is possible to provide a [pascal cased](http://wiki.c2.com/?PascalCase) custom name such as `[HtmlTargetElement("SomeName")]`, **but please stick with the convention**.

## Tag helper as empty html element

It is possible to specify that a tag helper is an empty html element by using the `TagStructure` property in the `[HtmlTargetElement]` attribute, make sure to specify an explicit name otherwise the tag helper will target any custom tag helper.

Unfortunately, it seems that it is not possible to render regular html elements (with end and start tag) from an empty tag helper.

<script src="https://gist.github.com/MissaouiChedy/1b0219f22a59f10c6ba4a1a03fab278f.js"></script>
## Tag helper activated by attribute

Tag helper can target standard html elements that have a user(developer) defined attribute, for example:

<script src="https://gist.github.com/MissaouiChedy/9f09e330c0867647bb0ef4f34b848026.js"></script>

It is possible to create a tag helper that act on any element having the `hello-prefix` attribute, by using the `Attributes` property in the `[HtmlTargetElement]` attribute the following tag helper prepends the "Hello " string to the content of targeted elements.

<script src="https://gist.github.com/MissaouiChedy/6cf4ae584da449f320f56c27df91b14c.js"></script>
## Tag helper activated on standard html element

Again, by using the `[HtmlTargetElement]` attribute it is possible to target directly standard html elements by simply providing the name of the html element to the `[HtmlTargetElement]` attribute.

<script src="https://gist.github.com/MissaouiChedy/435825146c3d26831289c83f113176f0.js"></script>

The previous tag helper erases the content of any `<p>` element present in cshtml views that includes it.

### Pay attention to possible conflicts

When defining multiple tag helpers that targets the same standard html elements, you have to pay attention to possible conflicts since that the last tag helpers applied [can erase the content rendred by the previous tag helper](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/authoring#inspecting-and-retrieving-child-content##avoiding-tag-helper-conflicts).

The solution in these cases is to check inside the `Process` method if the html elements content has been modified and, if so, to get the modified content from `output.Content` instead of `output.GetChildContentAsync()` as in the following example.

<script src="https://gist.github.com/MissaouiChedy/95daaec44348ad799207361f0018887b.js"></script>

Furthermore, it is possible to control the order in which the tag helpers are executed by defining the `Order` readonly (get) property in the custom tag helper class. The smallest order as the priority.

## Passing arguments to the tag helper

It is naturally possible to define custom attributes on a tag helper and use these attributes to pass data, consider this example:

<script src="https://gist.github.com/MissaouiChedy/7e40faa08f1bc1787347fe70460e216f.js"></script>

Notice how the `<with-arguments>` tag helpers can accept variables, string literals and even C# expressions.

Argument placeholder are simply defined as properties in the tag helper class.

<script src="https://gist.github.com/MissaouiChedy/8a74d5731e1783919d72392579b5eb67.js"></script>

Similar to the tag helper's html element name, the Pascal cased property names are by default kebab cased on the cshtml side.

The `[HtmlAttributeName]` attribute can be used to specify a custom name.

## Creating the tag helper's output content

Inside the `Process` method you typically populate the output argument with actual output content. Here are some actions performed in this regard.

- Define the output tag name
- Manipulate attributes on the output tag
- Get the initial html content
- Use [interpolated strings](https://msdn.microsoft.com/en-us/library/dn961160.aspx) to render the content

<script src="https://gist.github.com/MissaouiChedy/36ab351afb9f60548ba3992c22adacce.js"></script>