<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Blog</title><link>https://mdameer.com:443/blog</link><description></description><item><title>&lt;strong&gt;Introduction:&lt;/strong&gt; Dependency Injection in Orchard CMS</title><link>https://mdameer.com:443/blog/dependency-injection-orchard</link><description>&lt;p&gt;Before we start talking about Orchard Framework implementation of dependency injection, and how we can use and extend it, you can start with this &lt;a href="https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions/hands-on-labs/aspnet-mvc-4-dependency-injection" target="_blank"&gt;link&lt;/a&gt;&amp;nbsp;to understand the&amp;nbsp;ASP.Net MVC &lt;span&gt;dependency injection&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;Orchard&amp;nbsp;DI was built on top of&amp;nbsp;&lt;a href="https://autofac.org/" target="_blank"&gt;Autofac&lt;/a&gt; library (Which known as one of the best DI libraries for .Net framework), also&amp;nbsp;Orchard&amp;nbsp;framework layer will simplify the manipulation of&amp;nbsp;&lt;span&gt;injectable dependencies,&amp;nbsp;in many aspects as creating, suppressing and scoping.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Register New&amp;nbsp;Dependency&lt;/h3&gt;
&lt;p&gt;Orchard has automatic discovery and registration mechanism for&amp;nbsp;dependencies, so if you want to register new one, simply make it implement "IDependency" interface like the following:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;Public interface IServiceDependency : IDependency&lt;span&gt; {&lt;br /&gt;&lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;Public class ServiceDependency : IServiceDependency {&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;Now, "ServiceDepenency" is&amp;nbsp;injectable.&lt;/p&gt;
&lt;h3&gt;Control Dependency Lifetime Scope&lt;/h3&gt;
&lt;p&gt;One of the main advantages of using dependency injection pattern, is how it make controling the lifetime of dependencies very simple, combining that with the automation of registration in Orchard will make our life easier than ever.&lt;/p&gt;
&lt;p&gt;Orchard has four predefined scopes to be used in our registrations, every one of them has a specific interface to be implemented, this way we will tell Orchard how to register our dependencies,&amp;nbsp;as following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IDependency&lt;/strong&gt;:&amp;nbsp;Base interface for services that are instantiated per unit of work (i.e. web request).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ISingletonDependency&lt;/strong&gt;:&amp;nbsp;Base interface for services that are instantiated per shell/tenant.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IUnitOfWorkDependency&lt;/strong&gt;:&amp;nbsp;Base interface for services that may *only* be instantiated in a unit of work, this interface is used to guarantee they are not accidentally referenced by a singleton dependency.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ITransientDependency&lt;/strong&gt;:&amp;nbsp;Base interface for services that are instantiated per usage.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;span&gt;Feature Based&amp;nbsp;&lt;/span&gt;Dependencies&lt;/h3&gt;
&lt;p&gt;What you should do to bind a dependency to a specific feature? then, simply if the feature being disabled, then all its bound dependencyies will not going to be registered from the beginning, this also can be done simply by what Orchard offers.&lt;/p&gt;
&lt;p&gt;To bind&amp;nbsp;a dependency to specific feature, you can decorate it by&amp;nbsp;"OrchardFeatureAttribute" attribute, like:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span&gt;[OrchardFeature(&lt;/span&gt;"CustomFeature"&lt;span&gt;)]&lt;/span&gt;&lt;br /&gt;Public class ServiceDependency : IServiceDependency {&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;Now, "ServiceDependency" will be bound to feature called "CustomFeature", so we can have multiple implementations of "IServiceDependency" interface with the ability to switch between them easily by enabling or disabling their parent feature.&lt;/p&gt;
&lt;h3&gt;Suppressing&amp;nbsp;Dependencies&lt;/h3&gt;
&lt;p&gt;Sometimes, we need to override one of the dependencies without disabling its feature, here you will need to decorate your dependency by "OrchardSuppressDependency" attribute, which take the full qualified name of the original dependency as a parameter, like:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span&gt;[OrchardFeature("OtherCustomFeature")]&lt;br /&gt;[OrchardSuppressDependency(&lt;/span&gt;"CustomFeature.Services.ServiceDependency"&lt;span&gt;)]&lt;br /&gt;&lt;/span&gt;Public class OtherServiceDependency : IServiceDependency {&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;Now, if "OtherCustomFeature" feature is enabled, "OtherServiceDependency" will be registered as an implementation of "IServiceDependency", instead of "ServiceDependency".&lt;/p&gt;
&lt;h3&gt;Manual&amp;nbsp;Dependency Registration&lt;/h3&gt;
&lt;p&gt;Although, automatic dependency registration with lifetime scope controling is very useful, but in some cases you will need to manually&amp;nbsp;registering your dependencies, to take&amp;nbsp;full control of the registration.&lt;/p&gt;
&lt;p&gt;Since Orchard DI is based on Autofac, then you can use one of Autofac features (which supported by Orchard) to do this.&lt;/p&gt;
&lt;p&gt;With the usage of "Modules" Autofac feature&amp;nbsp;(Please refer to this &lt;a href="https://autofaccn.readthedocs.io/en/latest/configuration/modules.html" target="_blank"&gt;link&lt;/a&gt;&amp;nbsp;for more information), in addition to Orchard&amp;nbsp;&lt;span&gt;automatic discovery and registration mechanism which includes Modules also, you can gain more space to configure your registrations and doing some magical things with them, inside "Module" implementation you will find the following skeleton:&lt;/span&gt;&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;span&gt;public&lt;/span&gt; &lt;span&gt;class&lt;/span&gt; Custom&lt;span&gt;Module&lt;/span&gt; : Module {&lt;br /&gt;&lt;span&gt;    protected&lt;/span&gt; &lt;span&gt;override&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; Load(ContainerBuilder builder) {&lt;br /&gt;        // Add registrations to the container&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;span&gt;    protected &lt;/span&gt;override &lt;span&gt;void&lt;/span&gt; AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration) {&lt;br /&gt;        // Attach module-specific functionality to a component registration.&lt;br /&gt;    }&lt;br /&gt;&lt;span&gt;    &lt;br /&gt;    protected&lt;/span&gt; &lt;span&gt;virtual&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; AttachToRegistrationSource(IComponentRegistry componentRegistry, IRegistrationSource registrationSource) {&lt;br /&gt;        // Perform module-specific processing on a registration source.&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;</description><pubDate>Sat, 03 Nov 2018 13:49:26 GMT</pubDate><guid isPermaLink="true">https://mdameer.com:443/blog/dependency-injection-orchard</guid></item><item><title>&lt;strong&gt;How To:&lt;/strong&gt; Image Watermark Filter</title><link>https://mdameer.com:443/blog/image-watermark-filter</link><description>&lt;p&gt;Orchard CMS has very impressive feature called "Orchard.MediaProcessing", which give us the ability to manibulate media files at runtime through predefined set of filters, to create multiple versions of same media file without the need to upload it&amp;nbsp;multiple times, currently, Orchard comes with two prebuilt filters (Resize and Format), and as always, like other Orchard features, you can extend the list of filters to include any type of manibulation filters as you need using the extensibility hooks.&lt;/p&gt;
&lt;p&gt;In this post, we will learn how to add a new filter, which frequently asked by the community, aims to add image or text watermark to site images,&amp;nbsp;in next steps we will explian most important parts of the code, while you can download the nuget package from attachments section below (Compatible with Orchard 1.10 and later), or you can browse the full source code of the module on &lt;a href="https://github.com/mdameer/Mdameer.Watermark" target="_blank"&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;"ImageProcessor" Library&lt;/h3&gt;
&lt;p&gt;The default library for all Orchard&amp;nbsp;&lt;span&gt;predefined image processing filters is&amp;nbsp;"ImageResizer",&amp;nbsp;that although it is a great library, but it does not has a good watermark plugin to use in our case, so the choice&amp;nbsp;was to use "ImageProcessor" library instead.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The main reason of using "ImageProcessor" library, that it can apply the watermark image and text using&amp;nbsp;streams without the need to save the image in file system to be able to process it like other libraries, so you can manibulate the context stream directly inside the filter provider even if the file stream is coming from external source (Refer to this &lt;a href="http://imageprocessor.org/imageprocessor/imagefactory/" target="_blank"&gt;documentation&lt;/a&gt;&amp;nbsp;for more information).&lt;/p&gt;
&lt;h3&gt;Apply Filter&lt;/h3&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="pl-k"&gt;var&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="pl-en"&gt;result &lt;/span&gt;&lt;span&gt;= &lt;/span&gt;&lt;span class="pl-k"&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="pl-en"&gt;MemoryStream&lt;/span&gt;&lt;span&gt;();&lt;br /&gt;&lt;br /&gt;using (ImageFactory imageFactory = new ImageFactory(preserveExifData: true))&lt;br /&gt;{&lt;br /&gt;    imageFactory.Load(context.Media)&lt;br /&gt;        .Overlay(new ImageLayer&lt;br /&gt;        {&lt;br /&gt;            Image = watermarkImage,&lt;br /&gt;            Size = new Size(width, height),&lt;br /&gt;            Opacity = opacity,&lt;br /&gt;            Position = position&lt;br /&gt;        })&lt;br /&gt;        .Save(result);&lt;br /&gt;&lt;br /&gt;    context.Media = result;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;As you see, "&lt;span&gt;ImageProcessor&lt;/span&gt;" watermark maniplulation is based on layers, so you can add any number of layers (Image or Text Layers), as in the previous code snippet, where we are&amp;nbsp;maniplulating&amp;nbsp;the "Media" stream directly through&amp;nbsp;the "imageFactory"&amp;nbsp;to&amp;nbsp;add new "ImageLayer" with specific properties which should&amp;nbsp;be defined by the user&amp;nbsp;through the admin dashboard (You can try the attached module to see how it is working), also&amp;nbsp;we can do the same to add "Text&lt;span&gt;Layer"&lt;/span&gt;.&lt;/p&gt;</description><pubDate>Mon, 11 Dec 2017 00:46:13 GMT</pubDate><guid isPermaLink="true">https://mdameer.com:443/blog/image-watermark-filter</guid></item><item><title>&lt;strong&gt;Thoughts:&lt;/strong&gt; On Orchard Core</title><link>https://mdameer.com:443/orchard-cms/thoughts-on-orchard-cms-2</link><description>&lt;p&gt;Orchard CMS has a very spirited team, they keep trying to catch up with the latest trends, the first version of Orchard CMS was&amp;nbsp;a very successful start, it was built on a strong foundation, which aims to achieve the goals of MVC architecture, and with the second version (until now, it is in&amp;nbsp;Pre-Alpha stage), they applied&amp;nbsp;a lot of learned lessons from previous version, to up&amp;nbsp;the product to another level of dynamicity and efficiency.&lt;/p&gt;
&lt;p&gt;If you try to &lt;span&gt;experiment&lt;/span&gt;&amp;nbsp;the current Pre-Alpha of Orchard CMS 2.0, you will notice that the main focus in this version is on two aspects, architecture (Decoupling and Abstraction) and performance (Database Structure), and this is what we will briefly&amp;nbsp;talk about in this post (will be explained&amp;nbsp;deeper&amp;nbsp;in the upcoming&amp;nbsp;posts).&lt;/p&gt;
&lt;h3&gt;Decoupling and Abstraction&lt;/h3&gt;
&lt;p&gt;The main purpose of MVC architecture is to boost&amp;nbsp;the decoupling of the system components (isolates the application logic from the user interface layer and supports separation of concerns), ASP.NET is one of the best implementations of this architecture, and ASP.NET Core 1.0 is a huge&amp;nbsp;step in loose-coupling development field, on the other side, Orchard is&lt;span&gt;&amp;nbsp;constantly evolving to&amp;nbsp;keep track of changes and improvements, that&amp;nbsp;reflected in&amp;nbsp;Orchard 2 which is based on ASP.NET Core.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;To achieve the decoupling goal, Orchard 2 will not has a single framework&amp;nbsp;file (which has all the&amp;nbsp;API's, as Orchard 1), it is broken down to&amp;nbsp;several files, and that will lead to get the following benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each of these modules&amp;nbsp;will have a particular target.&lt;/li&gt;
&lt;li&gt;You don't&amp;nbsp;need to reference all these API's in your custom module, While you need only a few of them.&lt;/li&gt;
&lt;li&gt;Improving site performance.&lt;/li&gt;
&lt;li&gt;It will be very smooth&amp;nbsp;to use any orchard module in a non-Orchard projects, since each&amp;nbsp;&lt;span&gt;framework&amp;nbsp;module can be published as a standalone nuget package.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Most of framework modules have an abstraction layer, to be easy to surpass&amp;nbsp;their implementation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Database&amp;nbsp;&lt;span&gt;S&lt;/span&gt;&lt;span&gt;tructure&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;While Orchard 2 will&amp;nbsp;&lt;span&gt;maintain the same single content items table structure, it will have a huge update&amp;nbsp;on how data indexed for search in the database layer, s&lt;/span&gt;ince data access layer in the next version of Orchard will be based on &lt;a href="https://github.com/sebastienros/yessql" target="_blank"&gt;YesSql&lt;/a&gt;&amp;nbsp;library&amp;nbsp;(&lt;span&gt;.NET document database using any RDBMS).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;The following image will describe the new database structure compared to the old one:&lt;/p&gt;
&lt;p&gt;&lt;img width="760" height="428" alt="" src="/Media/Default/Images/Database-Structure.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;As you see, the main difference&amp;nbsp;between them, that in the old&amp;nbsp;structure you can index your data per part, and store the part properties&amp;nbsp;in it's connected record table, but the&amp;nbsp;downside of&amp;nbsp;this structure is that all part records for all the&amp;nbsp;content items which the part is attached&amp;nbsp;to them will be stored in the same table, but this will be changed with the new structure, with the usage of YesSql library, where you are free to&amp;nbsp;add any number of indexing records as you need,&amp;nbsp;either if all the properties&amp;nbsp;are from&amp;nbsp;the same content part, or a&amp;nbsp;combined properties from multiple parts, then you can query your data based on these indexes.&lt;/p&gt;
&lt;h3&gt;Note&lt;/h3&gt;
&lt;p&gt;These are my thoughts on the next version of Orchard CMS, and&amp;nbsp;this post&amp;nbsp;will be updated&amp;nbsp;periodically to reflect any&amp;nbsp;new findings, since Orchard 2&amp;nbsp;is still in Pre-Alpha stage, it will have a lot of changes in the upcoming stages,&amp;nbsp;and we eagerly await to see what's new.&lt;/p&gt;</description><pubDate>Fri, 26 Aug 2016 09:19:19 GMT</pubDate><guid isPermaLink="true">https://mdameer.com:443/orchard-cms/thoughts-on-orchard-cms-2</guid></item><item><title>&lt;strong&gt;How To:&lt;/strong&gt; Add Custom "Dictionary Token"</title><link>https://mdameer.com:443/orchard-cms/how-to-add-dictionary-token</link><description>&lt;p&gt;We all definitely used the tokens feature of orchard before, which provide us a smart way to replace strings with custom data, orchard has the basic tokens built in out of the box (like: Content, Text, Url ... etc), with the ability to connect tokens in chains to be more useful&amp;nbsp;with the ability to build more complex tokens.&lt;/p&gt;
&lt;p&gt;In this post, we will take orchard tokens functonality to another level of&amp;nbsp;dynamicity, by implementing new token called "Dictionary", to be able to support any type of objects, with dynamic chain building.&lt;/p&gt;
&lt;h3&gt;Implement New "ITokenProvider", called "DictionaryTokens"&lt;/h3&gt;
&lt;p&gt;Here, we will describe and evaluate our new dictionary tokens, like the following:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;public class DictionaryTokens : ITokenProvider {&lt;br /&gt;    public DictionaryTokens() {&lt;br /&gt;        T = NullLocalizer.Instance;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Localizer T { get; set; }&lt;br /&gt;&lt;br /&gt;    public void Describe(DescribeContext context) {&lt;br /&gt;        context.For("Dictionary", T("Dictionary"), T("Dictionary tokens"));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void Evaluate(EvaluateContext context) {&lt;br /&gt;        var dataContext = context.For&amp;lt;Dictionary&amp;lt;string, object&amp;gt;&amp;gt;("Dictionary");&lt;br /&gt;        if (dataContext.Data != null) {&lt;br /&gt;            foreach (var data in dataContext.Data) {&lt;br /&gt;                if (data.Value is string) {&lt;br /&gt;                    dataContext.Token(data.Key, d =&amp;gt; (string)d[data.Key])&lt;br /&gt;                        .Chain(data.Key, "Text", d =&amp;gt; (string)d[data.Key]);&lt;br /&gt;                }&lt;br /&gt;                else if (data.Value is DateTime) {&lt;br /&gt;                    dataContext.Token(data.Key, d =&amp;gt; (DateTime)d[data.Key])&lt;br /&gt;                        .Chain(data.Key, "Date", d =&amp;gt; (DateTime)d[data.Key]);&lt;br /&gt;                }&lt;br /&gt;                else if (data.Value is IContent) {&lt;br /&gt;                    dataContext.Token(data.Key, d =&amp;gt; (IContent)d[data.Key])&lt;br /&gt;                        .Chain(data.Key, "Content", d =&amp;gt; (IContent)d[data.Key]);&lt;br /&gt;                }&lt;br /&gt;                else if (data.Value is IUser) {&lt;br /&gt;                    dataContext.Token(data.Key, d =&amp;gt; (IUser)d[data.Key])&lt;br /&gt;                        .Chain(data.Key, "User", d =&amp;gt; (IUser)d[data.Key]);&lt;br /&gt;                }&lt;br /&gt;                else if (data.Value is JObject) {&lt;br /&gt;                    dataContext.Token(data.Key, d =&amp;gt; d[data.Key])&lt;br /&gt;                        .Chain(data.Key, "Dictionary", d =&amp;gt; &lt;br /&gt;                            ((JObject)d[data.Key]).ToObject&amp;lt;Dictionary&amp;lt;string, object&amp;gt;&amp;gt;());&lt;br /&gt;                }&lt;br /&gt;                else {&lt;br /&gt;                    dataContext.Token(data.Key, d =&amp;gt; d[data.Key]);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;This provider will take your dictionary as parameter, then check it's contents in the evaluation process, to link every property to the appropriate token chain, with support to chain itself if there is an object within the dictionary.&lt;/p&gt;
&lt;h3&gt;Let's Use It&lt;/h3&gt;
&lt;p&gt;We can use this new token like any other one, declare a dictionary and pass it to the tokenizer service with a&amp;nbsp;key, as following:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;var message = "Hi {Dictionary.User.FirstName} {Dictionary.User.lastName},&amp;lt;br/&amp;gt;" +&lt;br /&gt;    "This message sent to {Dictionary.Email}:&amp;lt;br/&amp;gt;" +&lt;br /&gt;    "&amp;lt;strong&amp;gt;{Dictionary.Subject}&amp;lt;/strong&amp;gt;&amp;lt;br/&amp;gt;" +&lt;br /&gt;    "{Dictionary.Message}";&lt;br /&gt;var messageDictionary = new Dictionary&amp;lt;string, object&amp;gt; {&lt;br /&gt;    {"Subject", subject},&lt;br /&gt;    {"Message", message},&lt;br /&gt;    {"Email", email},&lt;br /&gt;    {"User", new Dictionary&amp;lt;string, object&amp;gt; {&lt;br /&gt;       {"FirstName", firstName},&lt;br /&gt;       {"LastName", lastName}&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;var tokenizedMessage = _tokenizer.Replace(&lt;br /&gt;                           message, &lt;br /&gt;                           new Dictionary&amp;lt;string, object&amp;gt; { &lt;br /&gt;                               { "Dictionary", messageDictionary } &lt;br /&gt;                           }&lt;br /&gt;                       );&lt;/pre&gt;
&lt;p&gt;If we run this code with the following&amp;nbsp;dictionary data:&lt;/p&gt;
&lt;pre&gt;Subject: "Test&amp;nbsp;Subject"&lt;br /&gt;Message: "Test Message"&lt;br /&gt;Email: "test@test.com"&lt;br /&gt;User:&lt;br /&gt;    FirstName: "testfirstname"&lt;br /&gt;    LastName: "testlastname"&lt;/pre&gt;
&lt;p&gt;The output string will be:&lt;/p&gt;
&lt;pre&gt;Hi testfirstname testlastname,&lt;br /&gt;This message sent to&amp;nbsp;test@test.com:&lt;br /&gt;&lt;strong&gt;Test&amp;nbsp;Subject&lt;/strong&gt;&lt;br /&gt;Test Message&lt;/pre&gt;</description><pubDate>Sun, 01 May 2016 11:39:00 GMT</pubDate><guid isPermaLink="true">https://mdameer.com:443/orchard-cms/how-to-add-dictionary-token</guid></item><item><title>&lt;strong&gt;How To:&lt;/strong&gt; Add "placeholder" attribute to Text Field in Dynamic Forms</title><link>https://mdameer.com:443/orchard-cms/how-to-add-placeholder-to-text-field-in-dynamic-forms</link><description>&lt;p&gt;Orchard CMS&amp;nbsp;is built on a powerful architecture that provide us rich ways to extend it, and to add some missing features as needed.&lt;/p&gt;
&lt;h3&gt;"PlaceHolder" Attribute&lt;/h3&gt;
&lt;p&gt;HTML 5, has a very useful attribute called "placeholder", it is used to display a watermark text on the input field when it's empty, but text field and text area elements in dynamic forms module don't have this attribute out of the box, and we will learn how to add such attribute in this post.&lt;/p&gt;
&lt;h3&gt;Add&amp;nbsp;New Editor Form "PlaceHolderForm"&lt;/h3&gt;
&lt;p&gt;First thing we will do, implement a new editor form for "placeholder" attribute, to be able to attach it to text field and text area editors, this form will have a single tokenized input field, to enter the attribute value, as following:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;public class PlaceHolderForm : Component, IFormProvider {&lt;br /&gt;    public void Describe(DescribeContext context) {&lt;br /&gt;        context.Form("PlaceHolder", factory =&amp;gt; {&lt;br /&gt;            var shape = (dynamic)factory;&lt;br /&gt;            var form = shape.Fieldset(&lt;br /&gt;                Id: "PlaceHolder",&lt;br /&gt;                _Value: shape.Textbox(&lt;br /&gt;                    Id: "PlaceHolder",&lt;br /&gt;                    Name: "PlaceHolder",&lt;br /&gt;                    Title: "PlaceHolder",&lt;br /&gt;                    Classes: new[] { "text", "medium", "tokenized" },&lt;br /&gt;                    Description: T("The value of placeholder attribute.")));&lt;br /&gt;            return form;&lt;br /&gt;        });&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;h3&gt;Implement New "TextFieldElementDriver"&lt;/h3&gt;
&lt;p&gt;Drivers in Orchard CMS used to transport data to a template for rendering, called "Shape", and we can implement multiple drivers for the same item to render more shapes from same data source in different zones.&lt;/p&gt;
&lt;p&gt;Now, we will implement new driver for "TextField" element, called "TextFieldElementDriver", then override "OnBuildEditor" method to attach the form "PlaceHolderForm", which was created on the previous step to the output editor, and override "OnDisplaying" method to read attribute value from the element data property, then add a new attribute to the rendered element shape.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;public class TextFieldElementDriver : FormsElementDriver&amp;lt;TextField&amp;gt; {
    private readonly ITokenizer _tokenizer;

    public TextFieldElementDriver(&lt;br /&gt;        IFormsBasedElementServices formsServices, &lt;br /&gt;        ITokenizer tokenizer) : base(formsServices) {
        _tokenizer = tokenizer;
    }

    protected override EditorResult OnBuildEditor(&lt;br /&gt;        TextField element, &lt;br /&gt;        ElementEditorContext context) {
        var placeholderEditor = BuildForm(context, "PlaceHolder");
        return Editor(context, placeholderEditor);
    }

    protected override void OnDisplaying(&lt;br /&gt;        TextField element, &lt;br /&gt;        ElementDisplayingContext context) {&lt;br /&gt;        context.ElementShape.ClientValidationAttributes.Add("placeholder", &lt;br /&gt;            _tokenizer.Replace(element.Data["PlaceHolder"], context.GetTokenData()));
    }
}&lt;/pre&gt;
&lt;p&gt;Then you can implement new driver for text area field to add the same attribute to it using same "PlaceHolder" form.&lt;/p&gt;
&lt;h3&gt;Note&lt;/h3&gt;
&lt;p&gt;You must have noticed that we used the "ElementShape.ClientValidationAttributes" instead of "ElementShape.Attributes", which is the right way to add attributes to shapes in orchard, but we are currently forced to use this workaround because there is an issue in orchard, and you can see issue &lt;a href="https://github.com/OrchardCMS/Orchard/issues/6812" target="_blank"&gt;#6812&lt;/a&gt;&amp;nbsp;for more information.&lt;/p&gt;</description><pubDate>Fri, 15 Apr 2016 12:24:00 GMT</pubDate><guid isPermaLink="true">https://mdameer.com:443/orchard-cms/how-to-add-placeholder-to-text-field-in-dynamic-forms</guid></item></channel></rss>