Yii2 jsPosition POS_HEAD not working with Twig - twig

I am use Yii2 advanced with Twig integration. I need include js and css files to head block and use AssetBundle for this.
If I use POS_BEGIN or POS_END it's work. Js and css load to page in current position. But if I set position as POS_HEAD render ignore this and no load files to page.
Please help. What am I doing wrong?
My AssetBundle
namespace frontend\assets;
use yii\web\AssetBundle;
class YandexAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'/css/map.css'
];
public $js = [
'js/map.js',
'js/test.js'
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
public $jsOptions = [ 'position' => \yii\web\View::POS_HEAD ];
}
And connect in Twig template
{{ use('frontend/assets/YandexAsset')}}
{{ register_yandex_asset() }}

From http://www.yiiframework.com/doc-2.0/guide-structure-assets.html :
Asset dependencies are mainly specified through the
yii\web\AssetBundle::$depends property. In the AppAsset example, the
asset bundle depends on two other asset bundles: yii\web\YiiAsset and
yii\bootstrap\BootstrapAsset, which means the CSS and JavaScript files
in AppAsset will be included after those files in the two dependent
bundles.
both assets
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
are included at end of rendered page and your asset cannot be placed before them because they are depended of them.
if you want to include js file in POS_HEAD you can use registerJsFile() in your view or layout file
http://www.yiiframework.com/doc-2.0/yii-web-view.html#registerJsFile()-detail

Related

How to get the data of plugin-config in store-front of shopware6

I succssefully get data in store-front from entity by the following code.
public function addCustomfield(FooterPageletLoadedEvent $event): void
{
$customfieldResponse = $this->customfieldRoute->load(new Criteria(), $event->getSalesChannelContext());
$event->getPagelet()->addExtension('custom_field', $customfieldResponse->getcustomfield());
}
according to above code my custom data add in footer pagelet by api call successfully.
I wnat to get data of my plugin-config data in footer pagelet.
If you have any suggestion then tell me!
You can access the plugin config directly over twig inside the template:
{% set myConfig = config('MyPluginName.config.myConfigValue') %}

Shopware6 Loading options from twig template to Js plugin

I have been following https://developer.shopware.com/docs/guides/plugins/plugins/storefront/add-custom-javascript to create a javascript plugin. But, I am struggling with adding options through twig template. I have something like the following:
Twig file : product.html.twig:
{% set contentModalOptions = {
cmsContentId: "some-hash",
navigationUrl: path('frontend.cms.page'),
failSafeRedirectUrl: '/some-failsafe-url/'
} %}
<div>
<a target="_self" href="#" data-content-modal="true" data-content-modal-options="{{ contentModalOptions|json_encode|escape('html_attr') }}">
help text
</a>
</div>
plugin file : custom-plugin.js:
import Plugin from 'src/plugin-system/plugin.class';
export default class ContentModalPlugin extends Plugin {
static options = {
cmsContentId: '',
navigationUrl: '',
failSafeRedirectUrl: ''
};
init() {
console.log(this);
console.log(this.options); // empty values
}
}
Notes:
In the browser, I see that values set using twig as the HTML attribute.
Plugin has been registered and works with the template.
console.log() in the plugin doesn't print any values that are set from twig. It just shows the options object that has been initialized in the plugin.
Any help is appreciated.
I assume you register the plugin like this:
PluginManager.register('ContentModal', ContentModalPlugin, '[data-content-modal]');
Within the constructor of the Plugin class this.options = this._mergeOptions(options); should then called, which in turn parses the data-${dashedPluginName}-options attribute. It should throw an error if it can't parse the json:
`The data attribute "data-${dashedPluginName}-options" could not be parsed to json: ${e.message}`
Are the any errors when you look at the console of your browsers dev tools?
For further debugging you could also try calling super._mergeOptions(this.options); from your init method.
Now, I see what the problem was. When I registered my plugin, I had the following:
PluginManager.register('ContentModalPlugin', ContentModalPlugin, '[data-content-modal]');
So, I tried passing the options with data-content-modal-options attribute through twig but it seems that the resolved plugin name in _mergeOptions() at src/plugin-system/plugin.class takes the plugin name (i.e the string that is the first argument of the register function) and not the attribute definition in the register method.
So, adding a html attribute as data-content-modal-plugin-options based on my class name resolved the problem.

Highlight links in a Quick Links web part on SharePoint modern page

We have added 4 "Quick Links" web/app part in one section on a SharePoint modern page. We would like to highlight links under "Quick Links web part 2" and "Quick Links web part 4" only. I have added React modern script editor. How do we archive the above requirement using CSS ? If it is not possible in CSS then we would like to introduce JS. I couldn't find a fixed tag name that I can grab and apply CSS except GUID.
You could try to inject CSS by SPFX.
Check the demo shared by hugoabernier.
Main code:
export default class InjectCssApplicationCustomizer
extends BaseApplicationCustomizer<IInjectCssApplicationCustomizerProperties> {
#override
public onInit(): Promise<void> {
Log.info(LOG_SOURCE, `Initialized ${strings.Title}`);
const cssUrl: string = this.properties.cssurl;
if (cssUrl) {
// inject the style sheet
const head: any = document.getElementsByTagName("head")[0] || document.documentElement;
let customStyle: HTMLLinkElement = document.createElement("link");
customStyle.href = cssUrl;
customStyle.rel = "stylesheet";
customStyle.type = "text/css";
head.insertAdjacentElement("beforeEnd", customStyle);
}
return Promise.resolve();
}
}

Orchard and editing page - adding script

I can add a script to a page via the dashboard (by editing the page Content Item as html). The script is added to the page and evaluated, but too early - none of scripts are loaded yet (for example, jQuery).
I don't want to add the script to Layout, as it makes no sense to add this script for all pages.
Is there any way to add a script to a single page's content via the dashboard, so that it can be evaluated properly?
Or should I create a separate module that contains a special content part (to include proper scripts for the view/shape) and add that part to a custom ContentType (that also contains BodyPart and others such as Page Content Items)?
Or should I separate the whole content in such a way that interactive parts are widgets and should not be edited in Page Content Item?
Can you use the Script.Foot() extension method ?
#using(Script.Foot()) {
...
}
Using jQuery from Orchard module page
You can add the script file to the top of the html content like below:
<p>
<script type="text/javascript" src="/*path of the file*/">// <![CDATA[
// ]]></script>
</p>
Steps to add: Dashboard->Content->open the particular page->Html source editor->In the top add the above script with your script file path.
I suggest adding a part for your script, something like:
public class CustomScriptPart : ContentPart<CustomScriptPartRecord>
{
public bool AtFoot
{
get { return Record.AtFoot; }
set { Record.AtFoot = value; }
}
public string Script
{
get { return Record.Script; }
set { Record.Script = value; }
}
}
Views/Parts/CustomScript.cshtml
#if(Model.AtFoot) {
using(Script.Foot()) {
<script type="text/javascript">
#Model.Script
</script>
}
} else {
<script type="text/javascript">
#Model.Script
</script>
}
But probably something similar is already done, by Vandelay Industries for example.

Node.js, Express, Jade - Separate layout files

I'm working on some project with Node.js, Express and Jade, where I'd like to seperate layout files. Inside the main file is already separated header, but I don't know how to do this for sublayout where I need to pass data. In this case I need to pass data to widgets for every view on page, but in the route would be too many things to load data into widgets instead of some easy solution which I'm looking for.
I could do this thing on the way which I described above - to load data in view with every request, but this is somehow time & cpu consuming.
Another way I'm thinking of is to create some sublayout for widgets in which I'd load data once and then would be available all the time without calling data from DB in all requests. What's the best way to do that?
I work with mustache but I think you can use a similar strategy that I do.In most of the mustache templates that I use there is a common header and footer section.Along with the scripts and css files.I have created a separate partials file that exports these partials
.For instance my partial file looks like this.
exports.partials = function (isAuthenticated)
{
var menu;
isAuthenticated ?
menu = {
header: '',
footer: ' '
} :
menu = {
header: '',
footer: ''
}
return menu;
};
exports.staticResources = {
bootstrap :'//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/css/bootstrap-combined.min.css',
fonts : '//netdna.bootstrapcdn.com/font-awesome/3.0/css/font-awesome.css',
jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'
};
I have another method called generatePartials which as the name suggest generate the partials for my templates
exports.generatePartials = function(isAuthenticated){
var menu = resources.partials(isAuthenticated);
var partials = {
header : menu.header,
footer : menu.footer,
bootstrap : resources.staticResources.bootstrap,
fonts :resources.staticResources.fonts,
jquery :resources.staticResources.jquery,
};
return partials;
};
Now while rendering the template all I have to do is this
app.get('/routeName',function (req, res){
var partials = require('../helpers').generatePartials(req.isAuthenticated());
return res.render('viewName.html', partials);
};
And that's it.

Resources