How to remove an asset from a particular view in yii2 - yii2

i have a view called reports where i want to show a bootstrap dropdown.
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
</div>
It is not working only in this view. I found out that in this view there is multiple bootstrap js files.
<script src="/~folder/project/web/theme/bootstrap/js/bootstrap.min.js"></script>
<script src="/~folder/project/web/assets/db70fa5c/js/bootstrap.js"></script>
How can i remove one among these?
I tried creating a new RegisterAsset.php file where i left out the script
<script src="/~folder/project/web/theme/bootstrap/js/bootstrap.min.js"></script>
but still it is being seen in the view. What should i do?

Problem analysis
If everything was specified properly this wouldn't be possible. Yii2 would detect that you are registering the same asset twice and only include it once. In your example the second one (not the minified one) seems registered the right way, while the first one gets registered from a theme folder.
It looks like you are using an extension or some theme which uses its own asset-file (and its own bootstrap file!) being registered from a non-asset folder (web/theme/...). Not really according to the specifications... ;)
Let's solve it!
Find out which asset is registering your second bootstrap-file (the onein the theme folder). Now you can simply override the config of this asset via your global config-file. To do so first read the docs and then do the following in your config/web.php:
'assetManager'=>[
//...
'bundles'=>[
'namespace\to\your\failing\asset\Bundle'=>[
//add all css-files of the bundle except the duplicate one here
'js'=>['js/fileA.js', 'js/fileB.js'],
],
],
//...
],
Now you specify the js-files of the bundle except the one which is duplicate. This does now override the asset-config for this bundle and should therefore solve your problem without excluding something from within the views (which would be against the basic idea of the asset management).
Finding the failing asset bundle should be easy. Simply look for a class in your theme extending yii\web\AssetBundle and having the file bootstrap.min.js in its $js-array.

Related

How to add a plugin to a CKEditor 5?

I am learning how to use CKEditor 5 and how to add plugins to the editor. I have been trying to follow the instructions provide in CKEditor Ecosystem Documentation but i'm getting error while integrating Word Count Plugin
I have downloaded the plugins from GitHub into plugins folder locally.
CKEditor
|---ckeditor.js
|---ckeditor.js.map
|---translations (folder)
|---plugins(folder)
|---ckeditor5-word-count (folder)
|---src (folder)
|---wordcount.js
I don't know exactly how it would be the right way to install this plugin from CKEditor 5 itself locally without having to download it from the internet (with npm install from npm repository). I am well aware that I am doing something wrong, but I cannot identify what it is.
I would appreciate if anyone could give me tips, alternatives, and of course, maybe a solution. I've been trying for a few days now, and I don't know what I can and can't do anymore. I would be really grateful if someone could help me.
$(function() {
var editorTextarea
ClassicEditor.create( document.querySelector( '#cktext' ),{
} )
.then (editor => {
editorTextarea = editor;
})
.catch( error => {
console.error( error );
} );
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.ckeditor.com/ckeditor5/27.1.0/classic/ckeditor.js"></script>
<form class="test-form-horizontal" id="testform" role="form" >
<div class="row">
<div class="col-sm-12">
<label for="ckname">Name*:</label>
<input name="ckname" class="form-control" id="ckname" />
</div>
<div class="col-sm-12"><p> </p></div>
<div class="col-sm-12">
<label for="cktext">CkEditor*:</label>
<textarea class="form-control ckeditor" name="cktext" id="cktext"></textarea>
</div>
<div class="col-sm-12"><p> </p></div>
</div>
<button type="submit" class="btn btn-default btn-success">Submit</button>
</form>
The way CKEditor was designed means that you can not change what plugins appear in your editor just by changing the HTML in your web page.
You need to have a 'build' (a collection of Javascript files) that have all the plugins you need inside them, then you can adjust what parts of that build appears in your web editor by adjusting your HTML.
The default way - Builds
CKEditor5 has five ready-to-use builds. Each is a different type of editor (classic, pop-up, etc.). For each they have chosen which plugins that they think most people will find useful. I'm guessing you used one of these builds above.
Documentation on how to use their builds - https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html
The long way - Framework
To create your own custom build you need to use Node.js and learn how the CKEditor5 'Framework' works. Usually you fork an existing build from GitHub, adjust the configuration to add more plugins in, then build it.
Here is the overview https://ckeditor.com/docs/ckeditor5/latest/builds/guides/development/custom-builds.html
There is a lot of documentation on using the Framework - https://ckeditor.com/docs/ckeditor5/latest/framework/guides/overview.html
The quick way - Online Builder
Luckily they have a middle option. You can choose your plugin options on their website and it will automatically build it for you and give you a ZIP download file - https://ckeditor.com/ckeditor-5/online-builder/
I tried building an editor with the Word Count plugin included. It looks like the code is in the build, but you will need to write some HTML/Javascript to access it (as described in the plugin documentation - https://ckeditor.com/docs/ckeditor5/latest/features/word-count.html )
NB: I recommend removing the CKFinder CKFinder Upload Adapter and Cloud Services plugins as they need a cloud subscription which means you can't download the ZIP file straight away.
Why is it so complex?
Their focus was on building a very flexible system, the downside is that it became quite complex. They talked about their approach when v5 came out in 2017 (near the end) - https://ckeditor.com/blog/CKEditor-5-A-new-era-for-rich-text-editing/

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.

Jekyll istant search

I’m trying to implement the jekyll instant search from /Simple-Jekyll-Search found on Github (sorry can't post more than 2 link at the moment)
I followed all steps, I can see in _site the search.json file, is built correctly and being well formatted.
But no results output in the live site.
I have I tried to add the search code in _layout: default.html, and using a dedicated search.html page
---
layout: page
title: Search
---
<script src="{{ site.baseurl }}/search-script.js" type="text/javascript"></script>
<!-- Configuration -->
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
json: '/search.json'
})
</script>
<!-- Html Elements for Search -->
<div id="search-container">
<input type="text" id="search-input" placeholder="search...">
<ul id="results-container"></ul>
</div>
Inspect console shows this
js error
While I was doing some test, it worked for a while, but I’m not able to reproduce the conditions.
I think I make some mistakes in the structure of pages and the js is not correctly being called
I have a testsite here
realware
I'm quite sure I'm doing something wrong in the templating
Thanks for any help
Solved:
For future reference: the minified version contains some errors, I found a forked repo with a rebuilt version of the js, just remove the big comment block in the end of the file because links to external resources not needed and everything work like a charm
Use this repo, (not the minified versions)
https://github.com/tigerhawkvok/Simple-Jekyll-Search

Using templates for multiple pages in meteor

I was working on a web app prior to finding meteor and to have multiple pages I had things like this (I'm using bootstrap):
signup
In order to have a button for a user to sign up. I'm trying to convert this to a template in order to work with the meteor framework. I made a template that had all the code from my signUp.html file and changed that line of code to look like this:
signup
and this gave me the following error:
INCLUSION template tag is not allowed in an HTML attribute
I changed it again to be like this:
<a {{> signUp}} class="btn btn-lg btn-default">signup</a>
and I got this error:
Reactive HTML attributes must either have a constant
name or consist of a single {{helper}} providing a dictionary of names and
values. A template tag of type INCLUSION is not allowed here.
Any help would be appreciated.
What you really need is a router. Check out iron router
You can add it using
meteor add iron:router
Then, set up the routes for your signup page. (Assuming that you have named the template as "signUp" )
Router.route('/signup', function () {
this.render('signUp');
});
And finally use the link as :
signup

How To Make Reuseable HTML Navigation Menus?

I'm sure this topic comes up all the time,
But I can't seem to fine a concise answer.
I've got a vertical menu bar that I want to reuse in webpages (>20).
The Menu Bar is coded in HTML and uses uses: UL, LI, A, <Div> tags, and CSS. We need this:
Reusable
Maintainable
Scalable
So we don't have to modify all pages every time we add a page.
We'd rather avoid a coding approach if possible. We could live with just one master file that we edit as needed. Since we're using CSS and <div>s, I don't think frames scale for us. What can we do?
Server side includes are the way to go if you don't want to use a programming language.
They take this form:
<!--#include virtual="menu.html" -->
and will be inserted in the page wherever you put that tag in your HTML. It requires server side parsing, so your web server must have server side includes enabled. You can try it out, and if it doesn't work, contact your server host to see if you can get them enabled. If it's Apache, there's a method of enabling them via .htaccess files as well.
In order to do this, you'll have to use some server side technology. For instance you could...
include them in php
put them in the master page in .net
put this in a partial or a layout page in rails
Some reading:
http://us.php.net/manual/en/function.include.php
http://msdn.microsoft.com/en-us/library/wtxbf3hh.aspx
Another solution would be to create all this using Javascript, but please don't do it like that :)
html:
<script type="text/javascript" src="hack.js"></script>
<div id="mymenu">
</div>
hack.js:
function createMenu(){
$("#mymenu").html("all the html of your menu");
}
Without any server side script or Javascript you can use object or iframe tags.
http://www.w3schools.com/tags/tag_object.asp
http://www.w3schools.com/tags/tag_iframe.asp
The only thing to care is to indicate target="parent" in links.
Hope it helps
Using a w3 script..
index.html
<!DOCTYPE html>
<html>
<script src="http://www.w3schools.com/lib/w3data.js"></script>
<body>
<div w3-include-html="header.html"></div>
<div w3-include-html="nav.html"></div>
<script>
w3IncludeHTML();
</script>
</body>
</html>
header.html
<h1>Title</h1>
nav.html
<h2>Your nav</h2>
See also: http://www.w3schools.com/howto/howto_html_include.asp
And don't forget to test this code on your localhost.
I've done this two separate ways - one using server side (PHP) and one using Javascript includes (for demos that need to be able to run without any internet connection or server capabilities).
For PHP includes your pages will have to end with .php rather than .htm or .html, and these are very ideal to replace your header, footer, navigation, etc. Anything that is repeated on multiple pages.
Basically you would create your normal code then copy and paste the code you want to break out - in this example, your navigation - and save it in another file called (for example) inc_navigation.htm (this page can be called .htm).
Then in your actual pages you'd use the following code:
<?php include('inc_navigation.htm') ?>
That would insert your navigation at that point, if you had a change to make you'd make it to the .htm file and it would propagate to any page with that included.
For javascript includes you will have to include the following line at the top of every document where you want to include your navigation:
<script type="text/javascript" src="includes.js"></script>
Then you'll create a document called includes.js.
At the top of this document you'll declare your navigation variable:
var navigation = new Array(); // This is for the navigation.
Then a little ways down in that same document you need to actually outline your navigation code (the line numbers in the square brackets are crucial - keep them in order and start with 0 - you cannot have line breaks in this code so every line of code has to be a new line):
// ==================== Navigation ==================== //
navigation[0] = '<div id="tab_navigation">';
navigation[1] = '<ul id="dropline">';
navigation[2] = '<li><b>Home</b></li>';
navigation[3] = '<li><b>About Us</b></li>';
navigation[4] = '</ul>';
navigation[5] = '</div><!-- Close TAB NAVIGATION -->';
Then a little ways after that you'll actually insert the javascript that will put that code into your page (it doesn't actually put it there but rather makes it accessible in the page without actually altering the code of the .htm page - so if you view source you'll see the reference to the code not the code itself).
function show(i)
{
for (x in i)
{
document.write(i[x]+'\n')
}
}
Finally - in your .htm document, say for your index.htm page, you'll replace your navigation code (that you put in the above block called navigation) with this:
<script type="text/javascript">show(navigation);</script>
Where that name after SHOW and in the parenthesis is the name of your variable (declared earlier).
I have sites showing both methods in use if you'd like to see them just send me a message.
I was facing the same thing. Then, I created a new file for storing the html of the navigation bar.
I created a file navbar.html which had all my navigation bar code.
Then, in your main html file where you want navigation bar, just include this file by using jquery.
$(document).ready(function() {
$('#navigation').load('navbar.html');
});
Then at the place where you want navigation bar, just add this line:
<div id="navigation"></div>
As a modern answer to a six year old question: Web Components are specifically reusable HTML components, and Polymer is possibly the most popular implementation of it at the moment. Currently virtually no browser has native support for Web Components, so at the very least a Javascript polyfill is required.
If you would use PHP, all you have to do is use the include command, no coding beyond this one command.
Also, check out server side includes
So far one of the best solutions I have found is to model the menus after the Son of Suckerfish XHTML/CSS solution that is pretty well documented on the internet now combined with some logic on the server to render the unordered list. By using unordered lists you have a couple different options on how to output the results, but as long as the menu has some basic hierarchy you can generate it. Then for the actual page all you need to do is include a reference to the menu generating function.
I was searching for a way to write a reusable navigation menu that toggled(show/hide) when clicking a button. I want to share a solution that worked for me in case anyone else is looking to do the same. This solution uses jQuery, html, and css.
Add this line of code to your head tag in your main index.html file:
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
Add div for your nav in body tag:
<div id="mySidenav" class="sidenav"></div>
<script>
$(document).ready(function(){
$("button").click(function(){
$("#mySidenav").load("nav.html").toggle().width("400pt");
});
});
</script>
Create a html file that will be where your navigation menu resides. My file is called nav.html and inside the file the contents look like this:
have you found your one true musubi?`
item2
item3