Inhalte aufrufen

Profilbild

Creating a widget

widget documentation

  • Bitte melden Sie sich an, um eine Antwort zu verfassen.
14 Antworten zu diesem Thema

#1 JBTB

JBTB

    Member

  • Members
  • PunktPunkt
  • 10 Beiträge

Geschrieben: 08 March 2018 - 07:22

Hello, I'm new to SmartStore development and figuring out how to create by first widget.

I created one but it does not appear on the page where I would expect it. I followed the same approach as in the Paypall plugin.

 

When I put a breakpoint on the constructor of the widget, it never gets there. It looks like the only way to inform SmartStore about the existence of my widget is by adding the DependentWidgets attribute on the Plugin to register it for a provider.

 

My questions:

1. Are there other ways to have SmartStore notice and load the Widget?

2. Where can I find documentation about the concept of the Providers in the context of SmartStore? I'd like to know when to use them. Any information about concepts like Hooks would be really helpful and would lower the barrier to get started deloping plugins.

3. What's the best way to add a new page with a widget without touching the existing SmartStore code (for easy upgrading)?

 

Thanks in advance,

Jeroen

 

PS: Links to the examples on Confluence documentation are broken (all except 1).



#2 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3799 Beiträge

Geschrieben: 08 March 2018 - 14:06

1. The PayPal plugin uses action filters for the widgets. Maybe their registration is missing?
 
2. Some information can be found here. Hooks are used to monitor the data exchange with the database and execute additional code if necessary. They are used for a similar purpose as event consumers.
 
3. Widgets only inject small pieces of HTML, not whole pages. The Dev-Tools plugin has an example of how to integrate a new page in the backend.

Marcus Gesing

Smartstore AG


#3 JBTB

JBTB

    Member

  • Members
  • PunktPunkt
  • 10 Beiträge

Geschrieben: 08 March 2018 - 16:19

Thanks Marcus, didn't know I needed to use an action filter to trigger the loading of a widget. I'll look into that.

I assume I can also integrate a page into the frontend the same way the Developer plugin integrates one in the backend.

 

Kind regards,

Jeroen



#4 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3799 Beiträge

Geschrieben: 08 March 2018 - 16:45

You can also implement IWidget to inject widgets. They can be activated/deactivated in the backend under CMS > Widgets.
If you want to replace a frontend page you can use an ActionFilter.

Marcus Gesing

Smartstore AG


#5 JBTB

JBTB

    Member

  • Members
  • PunktPunkt
  • 10 Beiträge

Geschrieben: 08 March 2018 - 21:52

I already implemented IWidget in a plugin, enabled it in the backend but it does not showup.

[DisplayOrder(-1)]
[SystemName("Widgets.MyWidget")]
[FriendlyName("Connector Product Details")]
public class ConnectorDetailsWidget : IWidget
{
...
}

The problem is that even the breakpoint in the constructor is not hit.

I see a DependencyRegistrar class that has a Load method, calling GetDependentWidgets, and executes this code:

private string[] GetDependentWidgets(Type type)
{
  if (!typeof(IWidget).IsAssignableFrom(type))
  {
...
  }
}

but only for my plugin it skips the if clause since apparently it returns false.

Any suggestions how to fix this?

 

Thanks,

Jeroen

 



#6 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3799 Beiträge

Geschrieben: 09 March 2018 - 12:04

Please go to CMS > Widgets. Is there an entry for your widget? If so, activate it there. What does the rest of the class look like?


Marcus Gesing

Smartstore AG


#7 JBTB

JBTB

    Member

  • Members
  • PunktPunkt
  • 10 Beiträge

Geschrieben: 09 March 2018 - 18:56

Yes, widget showed up and I already installed it.

 

Full code of the sample widget:

namespace MyApp.Test.Widgets
{
	[DisplayOrder(-1)]
	[SystemName("Widgets.MyTest")]
	[FriendlyName("My Test Widget")]
	public class ConnectorDetailsWidget : IWidget
	{
		private readonly HttpContextBase _httpContext;
		public ConnectorDetailsWidget(HttpContextBase httpContext) 
		{
			_httpContext = httpContext;
		}

		public IList<string> GetWidgetZones() => new List<string> { "home_page_top" }; 
		
		public void GetDisplayWidgetRoute(string widgetZone, object model, int storeId, out string actionName, out string controllerName, out RouteValueDictionary routeValues)
		{
			actionName = "Details";
			controllerName = "SampleController";
			routeValues = new RouteValueDictionary { { "Namespaces", "MyApp.Controllers" }, { "area", MyPlugin.SystemName } };
		}
	}
}

I can't figure out why the call to IsAssignableFrom fails for this plugin, especially since it does work for the AmazonPayWidget and I use that as an example (copied and removed unused code).

 

Hope I just missed something really simple here,

 

Thanks,

Jeroen



#8 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3799 Beiträge

Geschrieben: 09 March 2018 - 19:45

It must be something simple. Is the value for "Namespaces" correct, i.e. SampleController is located under "MyApp.Controllers"?


Marcus Gesing

Smartstore AG


#9 JBTB

JBTB

    Member

  • Members
  • PunktPunkt
  • 10 Beiträge

Geschrieben: 10 March 2018 - 08:47

Thanks again for your assistance Marcus. Since none of the code of the widget is currently executed - breakpoint in the Widget constructor is not hit - I would doubt that anything in this Widget can cause the issue.

 

Because I don't know what's exactly required in a plugin for a widget, the issue may also be in one of the other files. Sharing all of them in this forum would be a bit poluting but on the other hand I feel we're now  in a dark and unfamilair room trying to find the lightswitch ;-)

 

Would be really helpful if sourcecode of a sample "Hello World" widget would be available on Github, showing bare minimum code you need to create a working Widget that shows just a raw line of text on the homepage.

 



#10 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3799 Beiträge

Geschrieben: 10 March 2018 - 13:17

I added an example to the Dev-Tools plugin.

  • JBTB gefällt das

Marcus Gesing

Smartstore AG


#11 JBTB

JBTB

    Member

  • Members
  • PunktPunkt
  • 10 Beiträge

Geschrieben: 10 March 2018 - 20:02

Thanks so much! Really helpful to have this starting point, I'll just copy the approach and take it from there.

 

 

EDIT:  I updated from github, cleaned and rebuild all. Still the Hello World text doesn't show up anywhere.

I reinstalled the plugin as well.

 

However, my breakpoint in DevToolsPlugin in GetDisplayWidgetRoute is never hit.

This code in DevToolsController is never executed either.

public ActionResult MyDemoWidget()
{
  return Content("Hello world! This is a sample widget created for demonstration purposes by Dev-Tools plugin.");
}

 

I'm a bit confused why it's still not working and apparently it works for you. Any ideas about this?



#12 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3799 Beiträge

Geschrieben: 11 March 2018 - 14:15

No, except for the above-mentioned things I have no concrete idea. I would debug method DefaultWidgetSelector.GetWidgets in that case.


Marcus Gesing

Smartstore AG


#13 JBTB

JBTB

    Member

  • Members
  • PunktPunkt
  • 10 Beiträge

Geschrieben: 11 March 2018 - 22:02

When loading the homepage I get:

DefaultWizardSelector.GetWidgets

LoadActiveWidgetsByWidgetZone(zone="home_page_top",store=1);

WidgetService.LoadActiveWidgets(store=1)

WidgetService.LoadAllWidgets()

Returns:

Widgets.AmazonPay

Widgets.DevToolsDemo

Widgets.Marketplace

 

return allWigets.Where(p => _widgetSettings.ActiveWidgetSystemNames.Contains(p.Metadata.SystemName, StringComparer.InvariantCultureIgnoreCase)).ToList();

 

Returns ONLY Widgets.AmazonPay because _widgetSettings.ActiveWidgetSystemNames contains only that item

 

My assumption is that I should find a way to have my widget showup in that list as well and that it will then be considered for loading.

 

I expected the Widgets.DevToolsDemo would also show up in the ActiveWidgetSystemNames but it didn't

Reinstalled AmazonPay to see what it does to get into that list but found nothing special.

 

Does this provide additional clues for why the widget does not show up?



#14 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3799 Beiträge

Geschrieben: 12 March 2018 - 10:29

Looks like the activation of widgets is not saved correctly in WidgetSettings.ActiveWidgetSystemName. Please try turning it on and off under Backend > CMS > Widgets. You can find the stored setting value under Configuration > Settings > All settings > Filter Setting Name by widgetsettings.activewidgetsystemnames. The filter should show exactly one setting. You can also try there to set it manually (comma separated system name), for example Widgets.DevToolsDemo,Widgets.AmazonPay

  • JBTB gefällt das

Marcus Gesing

Smartstore AG


#15 JBTB

JBTB

    Member

  • Members
  • PunktPunkt
  • 10 Beiträge

Geschrieben: 12 March 2018 - 20:09

Thanks! In the end I just reinstalled SmartStore and now it all worked like a charm! Apparently I broke something while fiddling with it  :blush: while I still had some errors in the Widget. Now the CMS Activate and Deactivate work as expected again, nice and easy.

 

BTW: While digging around I've seen more of the code and I must say I really like the way it works and the extensibility built into the product. So many layers and ways to extend it without changing the core of it, impressive!

 

Thanks again and keep up the good work!


  • Marcus Gesing gefällt das


Auch markiert mit einem oder mehrerer dieser Schlüsselwörter: widget, documentation