Create Self installing widget from DLL

Posted by Community Admin on 04-Aug-2018 14:21

Create Self installing widget from DLL

All Replies

Posted by Community Admin on 14-Nov-2014 00:00

I'm hoping to get some help and guidance on how to create a DLL that self installs a widget into a toolbox in sitefinity. I don't want to create and install a module with widgets - just a single widget on it own, using the fluent API if that's possible?

I've seen a great blog post by Peter Marinov which shows how to achieve this when creating a module with a widget. I only want to install a single widget, without a module. Is this not possible? 

My apologies in advance if I'm being a bit dumb, but I've not been able to figure out how to do it. Would really appreciate a big nudge in the right direction.

- Mark McNeece

Posted by Community Admin on 14-Nov-2014 00:00

No thats the perfect post to use...you don't need to do any of the module bits, just install your toolbox stuff.  That's what I'm doing with my widget assembly right now.  I'm not a module, but I can (and do) install a ConfigElement and Widgets and Layouts.

 Like do whatever you want to in that event, as long as the DLL is in the bin folder Sitefinity will fire it :)

 

Posted by Community Admin on 14-Nov-2014 00:00

Hey Mark,

Maybe this blogpost can be of help. It contains also the source on GitHub that I created some time ago which covers your case, I think.

http://www.konstrui.nl/over-ons/blog/daniel-plomp/2013/07/02/building-a-redistributable-sitefinity-widget-(falafelcon)

Best regards,
Daniel

Posted by Community Admin on 19-Nov-2014 00:00

Hi Daniel

 I've downloaded the source from GitHub.  I need to pour over it and see where it takes me.  Hopefully I'll be able to figure out where I'm going wrong from this.

 Thanks heaps!

 - Mark

Posted by Community Admin on 19-Nov-2014 00:00

Hello all,

You can use the following approach to register your controls:

public class Installer
    
        public static void PreApplicationStart()
        
            // With this method we subscribe for the Sitefinity Bootstrapper_Initialized event, which is fired after initialization of the Sitefinity application
            Bootstrapper.Initialized += (new EventHandler<ExecutedEventArgs>(Installer.Bootstrapper_Initialized));
        
 
        private static void Bootstrapper_Initialized(object sender, ExecutedEventArgs e)
        
            if (e.CommandName != "RegisterRoutes" || !Bootstrapper.IsDataInitialized)
            
                return;
            
 
            InstallWidget();
        
 
        /// <summary>
        /// Registering the widget using the fluent API
        /// </summary>
        private static void InstallWidget()
        
            RegisterControl("EcommerceDonations", typeof(DonationsWidget), "PageControls", "EcommerceDonations");
        
 
        public static void RegisterControl(string controlName, Type controlType, string toolboxName, string sectionName)
        
            var configManager = ConfigManager.GetManager();
            var config = configManager.GetSection<ToolboxesConfig>();
 
            var controls = config.Toolboxes[toolboxName];
            var section = controls.Sections.Where<ToolboxSection>(e => e.Name == sectionName).FirstOrDefault();
 
            if (section == null)
            
                section = new ToolboxSection(controls.Sections)
                
                    Name = sectionName,
                    Title = sectionName,
                    Description = sectionName,
                    ResourceClassId = typeof(PageResources).Name
                ;
                controls.Sections.Add(section);
            
 
            if (!section.Tools.Any<ToolboxItem>(e => e.Name == controlName))
            
                var tool = new ToolboxItem(section.Tools)
                
                    Name = controlName,
                    Title = controlName,
                    Description = controlName,
                    ControlType = controlType.AssemblyQualifiedName
                ;
                section.Tools.Add(tool);
            
 
            configManager.SaveSection(config);
        
    

Do not forget to define the virtual paths your control will need, whether they will not be resolved by some already registered virtual path resolver. You can register them the way its shown in my colleague Peter post.

Regards,
Nikola Zagorchev
Telerik
 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 19-Nov-2014 00:00

Hi Nikola

 Thanks for your input.  I've got that part working.  The toolbox section gets created and my widget gets added to it.  I just can't get the widget designer to work.  I'm slightly lost on getting that part working.

I've had a look through the example at the link Daniel gave above, but it's a bit complex and hard to follow.  I'm afraid I need a "HelloWorld" type example on this.  It's driving me nuts.  I must be close to it, but there's something that's eluding me.

My work in progress class library is at the following dropbox link. Would be great if someone could show me where I'm going wrong and/or what else I need to do?

https://www.dropbox.com/s/w3win5zudbhtcpu/Breadcrumbs.zip?dl=0

Thanks :-)

Posted by Community Admin on 19-Nov-2014 00:00

Hi Mark,

Please, change the designer template and JavaScript to be embedded resource and reference them the following way:

public static readonly string layoutTemplatePath = Breadcrumbs.breadcrumbWidgetVirtualPath + "Breadcrumbs.Widgets.Breadcrumb.Designer.BreadcrumbsDesigner.ascx";
public static readonly string scriptReference = Breadcrumbs.breadcrumbWidgetVirtualPath + "Breadcrumbs.Widgets.Breadcrumb.Designer.BreadcrumbsDesigner.js";

Add the script as embedded in the project assembly info, as well:
[assembly: System.Web.UI.WebResource("Breadcrumbs.Widgets.Breadcrumb.Designer.BreadcrumbsDesigner.js", "text/javascript")]

This will make the widget designer work, as well.

Regards,
Nikola Zagorchev
Telerik
 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 19-Nov-2014 00:00

Thanks Nikola

 I did those things, but still no joy.  However, I no longer get an error when trying to edit the widget, but the designer isn't loading.  I've updated the dropbox with my updated class library, which now includes your suggestions.  Must be very close now?

https://www.dropbox.com/s/w3win5zudbhtcpu/Breadcrumbs.zip?dl=0

Posted by Community Admin on 19-Nov-2014 00:00

Hello,

The widget and the designer are working on my end. Here is a video (screencast.com/.../qdjPYJij) showing this. Please, ensure the resources are embedded, delete the widget section from the application, build and restart it. Could you please provide information on the error you receive? Is the script loaded?

Regards,
Nikola Zagorchev
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 19-Nov-2014 00:00

Hi Nikola

It's still not working for me unfortunately.  I created a video showing me deleting everything from the sitefinitywebapp, then building it again, etc.

I've attached a screen capture with the chrome dev tools open showing that the designer script isn't being loaded.  

Posted by Community Admin on 20-Nov-2014 00:00

Hi Mark,

I think you need to add the javascript file to the AssemblyInfo file like this:

[assembly: System.Web.UI.WebResource("Breadcrumbs.Widgets.Breadcrumb.Designer.BreadcrumbsDesigner.js", "application/x-javascript")]

Or decorate your designer class (aka: BreadcrumbsDesigner.cs) with the following code:

using System;
using System.Linq;
using System.Web.UI;
using Telerik.Sitefinity.Web.UI;
using Telerik.Sitefinity.Web.UI.ControlDesign;
using System.Collections.Generic;
 
[assembly: WebResource(Breadcrumbs.Widgets.Breadcrumb.Designer.BreadcrumbsDesigner.js, "application/x-javascript")]
namespace Breadcrumbs.Widgets.Breadcrumb.Designer
 ---

Either way will work.
Let me know if that solved your problem?

Best regards,
Daniel Plomp

Posted by Community Admin on 20-Nov-2014 00:00

Ah, you already added the line to the AssemblyInfo file. I missed that.

I also noticed that this line of code:

private readonly string breadcrumbWidgetTemplatePath = breadcrumbWidgetVirtualPath + "Breadcrumbs.Widgets.Breadcrumbs.breadcrumbs.ascx";

... probably needs to be like this:

private readonly string breadcrumbWidgetTemplatePath = breadcrumbWidgetVirtualPath + "Breadcrumbs.Widgets.Breadcrumb.breadcrumbs.ascx";

Since there is no Breadcrumbs folder under the Widget directory. It is named Breadcrumbs with an extra 's', so you need to strip that.

Maybe that is causing the error.

Best regards,
Daniel

Posted by Community Admin on 20-Nov-2014 00:00

Well spotted Daniel - but I'm sorry to say it's made no difference.  Still got the exact same problem when I try to edit the widget.  

Posted by Community Admin on 20-Nov-2014 00:00

Weird problem!?

I always delete the reference to the project from my Sitefinity installation. Then I delete the /Debug and /Release folder under the projects /bin folder and also delete the hidden /obj folder. After that rebuild and re-add the project as a reference.

Maybe that does do the trick?

Best,
Danie.

Posted by Community Admin on 20-Nov-2014 00:00

You've got one more cleanup step there than me - I'll try that right now... brb! ;-)

Posted by Community Admin on 20-Nov-2014 00:00

No joy I'm afraid.  Exactly the same as before. Screen grab attached.

Posted by Community Admin on 20-Nov-2014 00:00

That is so strange. Is that dropbox link still the actual source? I don't want to ask, but you're sure that the .js and .ascx files are embedded into the project?

Best,
Daniel

Posted by Community Admin on 20-Nov-2014 00:00

I've just now updated the dropbox with the latest version of my class library - as I have indeed tweaked things here and there.  Yes, the .js and .ascx files are definitely set as embedded resources.

Posted by Community Admin on 20-Nov-2014 00:00

Can you try to update this code inside the BreadcrumbsDesigner.cs file:

#region Private members & constants
           public static readonly string layoutTemplatePath = Breadcrumbs.breadcrumbWidgetVirtualPath + "Breadcrumbs.Widgets.Breadcrumb.Designer.BreadcrumbsDesigner.ascx";
           public static readonly string scriptReference = Breadcrumbs.breadcrumbWidgetVirtualPath + "Breadcrumbs.Widgets.Breadcrumb.Designer.BreadcrumbsDesigner.js";
       #endregion

... to this:

#region Private members & constants
           public static readonly string layoutTemplatePath = Breadcrumbs.breadcrumbWidgetVirtualPath + "Breadcrumbs.Widgets.Breadcrumb.Designer.BreadcrumbsDesigner.ascx";
           public static readonly string scriptReference = "Breadcrumbs.Widgets.Breadcrumb.Designer.BreadcrumbsDesigner.js";
       #endregion

As I don't think the virtual path is needed to reference the script file.

Best,
Daniel

Posted by Community Admin on 20-Nov-2014 00:00

I tried it - exactly the same result I'm afraid.

Posted by Community Admin on 20-Nov-2014 00:00

Hi Mark,

I think I've found the problem. When you add a ScriptReference to the ScriptReference collection that is inserted into the javascript file, you also need to give the assembly name. Here you see the GetScriptReferences code:

public override IEnumerable<ScriptReference> GetScriptReferences()
   var scripts = new List<ScriptReference>(base.GetScriptReferences());
 
   // Get the assembly name
   var assemblyName = GetType().Assembly.GetName().ToString();
 
   scripts.Add(new ScriptReference(scriptReference, assemblyName));
   return scripts;

I think you need to change this in your project and also remove the virtual path from the ScriptReference, as stated in my previous post.

Let me know how that works out for you?

I needed to do the total cleanup, before it worked :)

Best,
Daniel

Posted by Community Admin on 20-Nov-2014 00:00

OMG! ... OMG!!

"Daniel Plomp for World President!" 

Your an absolute mega star!! My computer very nearly er... "fell down the stairs", and I was fast losing the will to live.  I'm a bit confused how Nikola got it to work then?  Maybe she added that and forgot to mention it?

Um... I now want to add an embedded style sheet.  Is there any I should know to achieve that, or should I be able to figure it out from what I have now?  

Thank you again so much, and to everyone that helped me!! 

- Mark

Posted by Community Admin on 20-Nov-2014 00:00

Hey Mark,

Glad you got it to work! Great news.

Regarding the stylesheet: you should indeed add this also to your project as an
embedded resource and also to your AssemblyInfo file or to your Breadcrumbs.ascx.cs:

[assembly: WebResource(STYLE_REFERENCE_PATH_WITHOUT_VIRTUAL_PATH, "text/css")]
namespace Breadcrumbs.Widgets.Breadcrumb
 ...

Then inside your Page_Load or Page_Init (not sure which one) you can add the stylesheet like this:

// Include our stylesheet
const string includeTemplate = "<link rel='stylesheet' text='text/css' href='0' />";
var includeLocation =
Page.ClientScript.GetWebResourceUrl(typeof(BreadCrumbs), STYLE_REFERENCE_PATH_WITHOUT_VIRTUAL_PATH);
var include = new LiteralControl(String.Format(includeTemplate, includeLocation));
Page.Header.Controls.Add(include);

Because the stylesheet also is an embedded resource now, you have to include it like this.

Best,
Daniel

 

 

 

Posted by Community Admin on 20-Nov-2014 00:00

Thanks Daniel!

 I added the code add the stylesheet to the onPreRender event and got it working.  Page_Load and Page_Init didn't work.

protected override void OnPreRender(EventArgs e)
    // Include our stylesheet
    const string includeTemplate = "<link rel='stylesheet' text='text/css' href='0' />";
    var includeLocation = Page.ClientScript.GetWebResourceUrl(typeof(Breadcrumbs), stylesheetReference);
    var include = new LiteralControl(String.Format(includeTemplate, includeLocation));
    Page.Header.Controls.Add(include);
 
    base.OnPreRender(e);
 
public static readonly string breadcrumbWidgetVirtualPath = "~/BreadcrumbWidget/";
private readonly string breadcrumbWidgetTemplatePath = breadcrumbWidgetVirtualPath + "Breadcrumbs.Widgets.Breadcrumb.breadcrumbs.ascx";
public readonly string stylesheetReference = "Breadcrumbs.Widgets.Breadcrumb.Styles.breadcrumbs.css";

This has been an invaluable exercise indeed!!  Many, many thanks again!!

Very best,
Mark

Posted by Community Admin on 21-Nov-2014 00:00

Hi,

I was actually referenced the script correclty from the assembly but have forgotten to mention it. Please, excuse me for that. All resources used in external widget should be embedded, so they could be loaded from the widget assembly. They should be loaded as a WebResources (WebResource.axd). This could be done through the script manager or using the ResourceLinks widget, as described here, so we can ensure the resources are loaded only once. The resource links widget could load embedded and not embedded scripts.

Regards,
Nikola Zagorchev
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 17-Mar-2016 00:00

Hi 

Did the issue got resolved ?? If yes please provide me the solution as I am getting the same problem.

 

 

Posted by Community Admin on 17-Mar-2016 00:00

Hello Balanjaneyulu,

The problem was with the script reference. It was not loading the javascript file needed for the control.

Regards,
Nikola Zagorchev
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 28-Mar-2016 00:00

Hi Daniel,

I hope you are doing well. I have a question on how to install a single  module on its own. Can you please help me how to install module automatically(self installing module).

Thanks,

Balu

Posted by Community Admin on 28-Mar-2016 00:00

Hello Balu,

What module you would like to create and install?
You can take a look at the Sitefinity STS Integration sample, since it shows a separate installing module with a widget and other resources:
https://github.com/Sitefinity/Sitefinity-External-STS-Integration

Regards,
Nikola Zagorchev
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 28-Mar-2016 00:00


I could create and install the module in the Sitefinity project. The registered module is not  listed under content however It was listed under Administrator-->settings-->Modules and services.

Can you please help me the following queries?


How can I create child pages for the module through coding??

Posted by Community Admin on 29-Mar-2016 00:00

Hi Balu,

If you import a Dynamic Module built using the Module Builder, the backend pages will be created automatically.
Note that if you are in Multisite, you need to add the module for the sites you want, so it creates a provider for that module and shows under Content page.

Regards,
Nikola Zagorchev
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

This thread is closed