Yii2 - How to include external js and css in view file - yii2

I am trying to include my plugins and custom js files in
frontend/views/layouts/main.php
So I used this code for js and css
<link rel="stylesheet" href="<?= Yii::$app->homeUrl; ?>chosen/chosen.css">
<script type="text/javascript" src="<?= Yii::$app->homeUrl; ?>js/jquery.fancybox.pack.js?v=2.1.5"></script>
but its not working. So what should I include to get my js and css files in view file?

If Your want to include script or css file in specific view you can use this :
$this->registerJsFile("/path/to/your/file/in/web/folder/script.js");
or
$this->registerCssFile("/path/to/your/file/in/web/folder/style.css");

For JS:
<?php
$script = <<< JS
// Js Code Here
JS;
$this->registerJs($script);
For CSS:
<?php $style= <<< CSS
// CSS code here
CSS;
$this->registerCss($style);
?>
This works fine.

Including it like you mentioned is not welcomed and definetely not "Yii style".
There are couple of ways to do that:
1) Use asset bundles. It's not necessarily to place it in AppAsset bundle. By default it's common bundle and included in main layout so all included assets will be published in every view.
You can create your own AssetBundle.
Note that for external assets (that are outside web accessible directory) you need to use sourcePath, otherwise - basePath and baseUrl properties.
With both options all you have to do in common case - fill $js and $css arrays and $depends for setting dependencies if it's needed.
You can read more by the link below.
2) Use registerCssFile() and registerJsFile().
First approach is preferable and recommended in official docs. It gives you dependencies handling and much more.
Official docs:
Assets
yii\web\AssetBundle
yii\web\View registerCssFile()
yii\web\View registerJsFile()

Related

Laravel - Webpack - Generate static HTML file

Would like to:
Create a static HTML file from a view (so it should include all CSS and JS) using the technologies mentioned above (default Laravel installation)
What I tried:
Simply injecting the content of the app.js into the app.blade.php file with the following code (done this for the app.css and it worked) but it only printed out the text of the JS file:
<script defer>
{!! file_get_contents(public_path('js/app.js')) !!}
</script>
static-generator package => It is only for 4.2
Run npm production (instead of npm development) and it will minify the assets, won't leave in comments and stuff and the first solution (simply injecting it into the HTML file will work)

How to avoid repeating same scripts and styles sections in MVC views

I have an MVC 5 project (.NET Framework) where a set of Views have the same set of #section styles and #section scripts blocks.
#section styles {
<link href="~/Content/DataTables/css/jquery.dataTables.css" rel="stylesheet" />
<link href="~/Content/DataTables/css/buttons.dataTables.css" rel="stylesheet" />
}
#section scripts {
<script src="~/Scripts/DataTables/jquery.dataTables.js"></script>
<script src="~/Scripts/DataTables/dataTables.buttons.js"></script>
<script src="~/Scripts/DataTables/buttons.print.js"></script>
<script src="~/Scripts/DataTables/buttons.html5.js"></script>
<script src="~/Scripts/jszip.js"></script>
<script>
$(() => {
// source js file defined in BundleConfig.cs
TableController.init();
});
</script>
}
Just as the one TableController.init() jQuery function rests in a single location and can be called in any View I choose, is there a way I can have only a single definition of this set of <link> and <script> elements be able to call it in any view I choose? The reason I did not put this in the _Layout file is that I might not want it on all Views -- just most of them.
I don't know what this technique is called, or even if it is possible in MVC. I just figured that it would be a useful way to avoid repeating myself. Furthermore, if I wanted to make any tweaks, I would only make a change in one place and not multiple Views.
Is there a technique I can use to achieve this goal?
You can create Bundles for anything you want, You can create a Bundle for an area or a single page.
//scripts
bundles.Add(new ScriptBundle("~/bundles/Custom").Include(
"~/Scripts/Custom.js"));
bundles.Add(new ScriptBundle("~/bundles/Custom2").Include(
"~/Scripts/Custom2.js"));
//styles
bundles.Add(new StyleBundle("~/Content/Custom").Include(
"~/Content/Custom.css"));
bundles.Add(new StyleBundle("~/Content/Custom2").Include(
"~/Content/Custom2.css"));
Now you can separate theese scripts and styles and add them only on page that you need.
Also I suppose it's good to define 2 sections in your _Layout.cshtml in head tag.
<head>
//other scripts and styles here
#RenderSection("scriptslib", required: false)
#RenderSection("csslib", required: false)
</head>
So now in your Views (Cabinet.cshtml and AdminPanel.cshtml) you can place your libs where they suppose to be like this:
#section scriptslib{
#Scripts.Render("~/bundles/Custom")
#Scripts.Render("~/bundles/Custom2")
}
By doing this it allows you to build complete bundles for sections or pages to use how you wish.
**
EDIT: thanks Adrian
**
You can add bundles as folders for future scripts using wildcards so you do not have to recompile, aswell as place a custom.js and custom.css in each folder for future edits or overrides you may want to add.
ADDING A CUSTOM FOLDERS:
Scripts
Custom
YourFiles.js
YourFiles.min.js
Content
Custom
YourFiles.css
YourFiles.min.css
Custom Bundles:
bundles.Add(new ScriptBundle("~/bundles/Custom").Include(
"~/Scripts/Custom/*.js"));
bundles.Add(new ScriptBundle("~/bundles/Custom2").Include(
"~/Scripts/Custom/*.*.js"));
bundles.Add(new StyleBundle("~/Content/Custom").Include(
"~/Content/Custom/*.css"));
bundles.Add(new StyleBundle("~/Content/Custom2").Include(
"~/Content/Custom/*.*.css"));
Now anything you place in those folders will be processed with a IIS App restart, I usually add a function to my applications to be able to perform the App Restart.
Hope this helps
Try the pool pro's idea, it's a great answer. For me I simply prefer to use partial views for referencing it.
Why ?
You need to compile the code again once you modify the c# file and add a another CSS or JS file. If you use partial views you don't need to compile the project again, you can just change views and upload.
Not pretty: You could use partialview and use it in views you want your links.
Put your partialview in your shared folder.
Then call this inside your view #await Html.PartialAsync("_SomeNamePartial")
More beautiful: Put all css in 1 file and all javascript in 1 file.
Best way and as it should be: Your way of doing it, #section is there for a reason.

How to minimize the placements of CDN?

I'm using bootstrap and jQuery CDN for my web app and I'm just wondering is there a way to not having to go to bunch of my files and paste the CDN links and scripts and instead just put it all in one place?
Let's say that I can't save bootstrap or jQuery locally or make the web app a single page web app.
I believe Require.js can do this but I'm not sure how or is there another JavaScript libraries that can do this?
First let me state the obvious, that most CDN's include minified versions already.. but there are several options to do this on your own. See here for others.
I've used this one, JShrink.
Here's an example using a list of CDNs:
To include your scripts..
$scripts = array(
"https://code.jquery.com/jquery-2.1.4.js",
"https://code.jquery.com/ui/1.11.4/jquery-ui.js"
);
foreach($scripts as $script)
echo "<script src='minifier.php?url=".urlencode($script)."'></script>\n";
Then minifier.php looks like this..
<?php
include('vendor/autoload.php');
$minifiedCode = \JShrink\Minifier::minify(file_get_contents($_GET['script']));
header("Content-Type: application/javascript");
echo $minifiedCode;
You can inject any CDN in your page's header using the below Javascript in your javascript file of the app. But you at least need same javascript file linked in all pages with this script.
function loadjscss(filename, filetype){
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref!="undefined"){
document.getElementsByTagName("head")[0].appendChild(fileref)
}
}
loadjscss("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js", "js");
loadjscss("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css", "css");

Yii2 add google font to head

I was wondering how do you add link tag/google font to head in yii2.
I want to add the following
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700' rel='stylesheet' type='text/css'>
I have found this documentation but doesn't mention anything about link/adding google font etc
The correct answer is to create a new AssetBundle.
While you can directly place the HTML for the fonts into the of your main.php file, this isn't the Yii way. If you have tried to load jQuery files this way, you might notice odd behavior when directly putting them into the HTML.
For example: Directly place the HTML tag for Bootstrap CDN into the head of your main.php. Then, somewhere in your code try to use the tooltip. You will get an error in your console that tooltip is not a function. - This is because the way Yii puts all your template files together, and at that time, Bootstrap is not available.
While simply loading a font probably won't cause any problems, it is a good idea to do things the way they were intended. Following MVC rules, properly documenting your code, and following the Yii best practices, will go a long way. Not only will you thank yourself a year later when you have to go back into a project, but the next guy will appreciate it. I can't stand going into systems, and seeing stuff thrown everywhere, chincy hacks, and spaghetti code, and no documentation or comments.
Correct Way:
Create a new AssetBundle. In your assets folder, you probably already have AppAsset.php. Duplicate it, and name it FontAsset.php.
Here is an example from my project, using 3 Google fonts.
FontAsset.php
<?php
namespace app\assets;
use yii\web\AssetBundle;
class FontAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'//fonts.googleapis.com/css?family=Open+Sans:400,700',
'//fonts.googleapis.com/css?family=Ubuntu:400,700',
'//fonts.googleapis.com/css?family=Oswald:400,700'
];
public $cssOptions = [
'type' => 'text/css',
];
}
In your layout, main.php for example. Right under where you see AppAsset::register($this)
main.php
use app\assets\FontAsset;
FontAsset::register($this);
For every layout file that you want to load those fonts, include the FontAsset.
The AssetBundle is basically a bundle of CSS and/or JS files and options. You could add another one for say JWPlayer say named VideoAsset, and add your JS/CSS files for JWPlayer in it.
Point being, you shouldn't be adding these things directly into the HTML of the layouts directly, as it can cause problems. Let the AssetManager handle them by declaring AssetBundles.
It might save you later down the road!
The best way is to create an asset bundle and add the link to the bundle.
You can find a complete guide here:
http://www.yiiframework.com/doc-2.0/guide-structure-assets.html
You can put it directly in the head of the layout (file views/layouts/main.php)

Using dependencies in wp_register_style() for wordpress

I am trying to get a custom css file to load after the plugin stylesheets. I was thinking I could use the $deps parameter of wp_register_style(), but the css file does not load at all when I add the array(). This happens no matter what is included in the $deps array(), ie (array('style')
, array('style.css')).
Is there an issue with the call, or a better way of doing this?
In my functions.php
// Load custom css
add_action('wp_enqueue_scripts', 'prefix_add_my_stylesheet');
function prefix_add_my_stylesheet() {
wp_register_style( 'custom-supersized-styles', get_template_directory_uri(). '/css/custom-supersized-styles.css', array('style','supersized');
wp_enqueue_style( 'custom-supersized-styles' );
}
If you're using the WP Supersized plugin try registering your function like so:
// Load custom css
add_action('wp_enqueue_scripts', 'prefix_add_my_stylesheet', 999);
The dependencies array (the parameter you're attempting to use to add supersized with) depends on supersized having already been registered by WordPress. If you set the priority of your own prefix_add_my_stylesheet to a higher number, it should then load after the plugin has registered and loaded its CSS (and thus will be available).
In addition, you can remove the style as a dependency. (style is never registered by WordPress as a dependency handler, and your enqueued scripts / css should be loading after style.css loads anyway).
Hope that helps!