Custom Event on CDS (Context Driven Services) on Spartacus Storefront - spartacus-storefront

I set the CDS on Spartacus, following the guide on the official Spartacus documentation. But I could not figure out how to set a “View Product Page” event that is triggered when a product is viewed. Any one knows the right way to configure it on Spartacus ?

I am not familiar with CDS, but as far as I know, you can subscribe and react to ProductDetailsPageEvent using Spartacus event service.
Kindly refer to below source code written in your app.module.js:
export class AppModule {
constructor(events: EventService) {
const event$ = events.get(ProductDetailsPageEvent);
event$.subscribe((event) => console.log('ProductDetailsPageEvent is fired: '
+ event));
}
}
details could be found in Spartacus document:
https://sap.github.io/spartacus-docs/event-service/#page-title
Best Regards,
Jerry

Related

How to extend the Spartacus PLP page

In Spartacus PLP page, I am trying to extend PLP page.
Below is module and ts code
ConfigModule.withConfig({
cmsComponents: {
CMSProductGridComponent: {
component: ProductsGridComponent
}
}
} as CmsConfig)
In ts file
export class ProductsGridComponent extends ProductGridItemComponent{}
Issue
The OOTB search call is not happening. When I comment the override in module file OOTB search API is happening. Is there any mistake for extend PLP page ?
Can any help on this?
Look at the CategoryPageMetaResolver. It seems you might have to override the hasProductListComponent check:
You need to create a service that extends CategoryPageMetaResolver.
Override hasProductListComponent so that it will identify your
ProductsGridComponent as a 'ProductListComponent'.
Provide the service in a module -
{provide:CategoryPageMetaResolver,useClass:MyCategoryPageMetaResolver}.

Theming on Multi-Site scenario?

We're trying to implement Spartacus on an existing Project and now facing the issue to provide different styles for each existing base site (for example "electronics", "appearal"). So distinguished by the URL we can access each base sites content (electronics.local:4200 and appearal.local:4200 are served by the same app but have different content).
How to configure different styles like in the accelerator by setting the theme property in CMS (backoffice) for each basesite in Spartacus?
Thanks in advance!
With some kind help from the spartacus slack channel I've came to a solution that is quiet solid but not linked directly to the theme property of a base site from CMS (backoffice). It is just retrieving current BaseSite and according to that adds a class to cx-storefront tag in app.component.
app.component.ts:
export class AppComponent {
public $activeSite: Observable<string> = this.baseSiteService.getActive();
constructor(
private baseSiteService: BaseSiteService
) {
}
}
app.component.html:
<ng-container *ngIf="$activeSite | async as activeSite">
<cx-storefront [ngClass]="activeSite"></cx-storefront>
</ng-container>
Now I've got a css-class equal to current BaseSite UID in the cx-storefront dom element and am able to apply my styles accordingly:
<cx-storefront class="electronics stop-navigating" _ngcontent-ipq-c296="" ng-reflect-ng-class="electronics" tabindex="0">

Testcafe - Selecting an element in Shadowroot is not working

I have this website https://www.storytel.com/sg/en/where I am trying to click on the button (refer to the image) in the Subscription Component which resides in the Shadowroot. I have tried with the following codes but it didn't work. It will be great if someone can help. Thanks in advance.
test('Click inside shadowDOM', async t => {
const shadowBtn = Selector(() => document.querySelector('storytel-subscription').shadowRoot.querySelectorAll('*[data-testid="subscription-card-0-button"]'));
await t
.click(shadowBtn);
});
There seems to be a bug with processing elements in shadow dom. I suggest you create an issue in the TestCafe GitHub repository and describe your scenario there: https://github.com/DevExpress/testcafe/issues/new?template=bug-report.md

How and where to instantiate a custom class that extends the WP_REST_Controller

I have a plugin that I created and I want to use the WP rest api controller pattern in order to extend the api.
<?php
/**
* Plugin Name: myplugin
* Plugin URI: h...
* Description: A simple plugin ...
* Version: 0.1
* Author: Kamran ...
* Author ....
* License: GPL2
function myplugin_register_endpoints(){
require_once 'server/controllers/my_ctrl.php';
$items=new items();
$items->register_routes();
}
add_action('rest_api_init','myplugin_register_endpoints');
.
.
I created a class a folder called server/controllers and inside it my_ctrl.php file with a class that extends WP_REST_Controller that looks like this
// server/controllers/my_ctrl.php
class items extends WP_REST_Controller {
/**
* Register the routes for the objects of the controller.
*/
public function register_routes() {
.....
}
}
However I am receiving the following error in sublime xdebuge call stack:
[Fatal error] Class 'myplugin\WP_REST_Controller' not found
I am not sure how to solve this issue, where to put the files for my custom controller, where to create the instance of the custom class etc?
Stumbled upon this and thought I'd provide my solution in case someone else encounters this.
The idea is to postpone the instantiation of the class extending WP_REST_Controller by not instantiating it until the actual rest_api_init hook is called.
Code example:
add_action( 'rest_api_init', function () {
require_once(plugin_dir_path(__FILE__) . '/VideoImageApi.php');
VideoImageApi::instance()->register_routes();
});
Note the require_once from within the callback.
I have manged to solve the issue,
I checked the wp-content\plugins folder and I couldn't find the \rest-api folder and although I found the folder inside \wp-includes\rest-api it seems that this folder that integrates the "wp rest api" into core doesn't include all the classes that the api can expose (it includes only 3 php files), So it didn't include \wp-content\plugins\rest-api\lib\endpoints\class-wp-rest-controller.php . I installed the "wp rest api" plugin and it was added to wp-content\plugins and now I don't have the error anymore. (It was strange because I don't know when it was deleted from my project)
Thank you Dan your comments really helped me to recheck everything and scan the folders included in my wordpress and realize that the plugin is missing and that the folder \wp-includes\rest-api doesnt contain all the needed classes.

Worklight 6.1: How to add EULA to hybrid app

Environment:
Worklight 6.1.0.2
dojo 1.9.4
We have created a hybrid app using Worklight 6.1 for android, iOS and windows8 platform. Now we would like to add and show End User License Agreement (EULA) window to the user, when the app first time launch. It should have Accept and Decline button. If user tap on Accept button, then he should be able to use the app.
I would like to know, how can we achieve this using Worklight 6.1.
Any help on this, will be much appreciated.
FYI there is nothing specific here to Worklight.
You could implement this in any number of ways w/out ever using any Worklight API whatsoever.
You could achieve it for example like this (untested code - you'll need to experiment):
In main.js create some global variable eulaAccepted:
var eulaAccepted;
// You will need to handle this property using HTML5 Local Storage so that it will persist for the next time the app is launched, and have the app act accordingly.
Then, in wlCommonInit():
function wlCommonInit() {
if (!eulaAccepted) {
displayEula();
} else {
displayApp();
}
}
In displayEula():
function displayEula() {
// either display a dialog using `WL.SimpleDialog`...
// Or maybe custom HTML with "accept" and "not accept" buttons
WL.SimpleDialog.show(
"Eula Agreement", "your-eula-text-here",
[{text: "Accept", handler: acceptEula },
{text: "Reject", handler: rejectEula}]
);
}
Handle the result:
function acceptEula() {
eulaAccepted = true;
... // Some code that will store the `eulaAccepted` variable using HTML5 Local Storage API
displayApp();
}
function rejectEula() {
// Display some other custom HTML instead of your app.
// Maybe also additional logic to try again to accept the Eula...
}