How to add a plugin to a CKEditor 5? - html

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/

Related

How to use requirejs on your client side code

So recently I was making a website and I added a login page. I wanted to check if the username and password entered existed in the database and if not it would give an alert saying invalid username or password. My code is:
<form>
<label>Enter Username:</label>
<input type="text" id="username">
<br>
<label>Enter Password:</label>
<input type="password" id="password">
<br>
<input type="submit" onclick="submitLoginInfo()">
</form>
and the js is
const { LoginSchemaModel } = require('./dbconfig.js')
// import { LoginSchemaModel } from './dbconfig'
requirejs()
function submitLoginInfo () {
let usernameElement = document.querySelector('#username')
let passwordElement = document.querySelector('#password')
console.log(`Username Element is HTMLElement: ${usernameElement instanceof HTMLElement}`);
console.log(`Username Element is HTMLElement: ${passwordElement instanceof HTMLElement}`);
alert(`usernameElement = ${usernameElement}`);
alert(`passwordElement = ${passwordElement}`);
alert(`username = ${usernameElement.value}`);
alert(`password = ${passwordElement.value}`);
}
Now the problem is with the require because that is not supported. So I decided to use imports instead and added "type"="module" to my package.json but was still getting an error in the console saying I can't use it. Then I used requirejs and ran into this issue where I couldn't import requirejs without using the require function. When I tried to add
var requirejs = require('requirejs')
requirejs.config({
nodeRequire: require
});
it would say that I couldn't use require(). When I tried to do it in a seperate file I realized I had to require that file to use requirejs which wouldn't work. I have no idea on how to fix this, I have been searching stack overflow and other websites but nothing mentions this. I want to know if there is a different way which I have just been missing this whole time.
I will assume that you are just declaring the js in some HTML with a script that will run in the client. Like that <script src="./myscript.js"></script>
Why you couldn't use require
require is the way we import modules in Node.js(an engine that runs javascript outside the browser) or any other javascript engine that adopts the CommonJs modules pattern. Browsers uses what is called ESModules.
Why did changing type="module" in package.json didn't solve this problem?
The package.json file is completely ignored by the browser, it doesn't affect anything in the javascript you import from the script tag. package.json is file used by node.js(and other engines). And type="module" is used in Node.js to use import instead of require, so wouldn't fix even if the browser read it.
How can we import things in browser javascript
Firstly I have to say that browsers usually expect people to use some bundling tool like webpack. (bundler is just a program that transforms all your .js files into a single .js file) instead of importing modules directly, but if you want to do it only using a web-browser and nothing more you can:
Add the type="module" in the script tag.
<script type="module" src="./myscript.js"></script>
Use something like the live server extension of vscode
Because, browsers cannot give .html files to have full access to your files, so you need to simulate a server in a folder.
So now you can simple use import {thing} from "./myscript.js" that will work.
How to use the require.js lib in the browser.
I have to say that you shouldn't use it, it is used by people that want some packages made for node.js to work on browser. But if one would want to use requires only using the browser they would have to remember that when we do npm i requirejs it creates downloads it into the node_modules folder, so we would have to import from there. But again, you shouldn't do that to solve your problem. Stick to the import.

Razor component button #onclick not calling c# method

I'm looking to start creating a new website and I came across blazor/razor for asp.net. I'll say just looking at it, this has me very excited to get away from all of the javascript frameworks. However, like many others, I'm having issues getting a simple #onclick to work, and the more research I do into blazor/razor, the more I get confused. As others have noted, everything seems to keep changing, so the resources I find keep contradicting themselves.
To start, I'm trying to create a simple Razor component (.razor extension) in an ASP.NET Core Web App. I watched the "Introducing Razor Components in ASP.NET Core 3.0 - Daniel Roth" video on youtube as a starting guide, and came up with this:
<div class="">
<input type="text" placeholder="Search..." #bind="#searchValue">
<button #onclick="Search">Search</button>
</div>
#count
#code {
string searchValue;
int count;
void Search()
{
var x = searchValue;
count++;
}
}
My problem is, the button #onclick isn't calling the Search method. I've seen several different variations on this syntax and I've tried them all. The video I mentioned had it as
<button onclick="#Search">Search</btton>
but I've found that the # symbol is now required in front of onclick. I've seen the # symbol included and not included in front of the method name. If I don't include it, it compiles and runs, but the button doesn't do anything. If I do include it, I get the error message:
Cannot convert method group 'Search' to non-delegate type 'object'. Did you intend to invoke the method?
I found this BlazorFiddle (https://blazorfiddle.com/s/aoa87v05) as a quick testing ground and found that adding both:
<button #onclick="#SomeAction">Click Me</button>
<button #onclick="SomeAction">Click Me</button>
worked fine. So I'm not sure what I'm doing wrong here. (Perhaps this blazor fiddle is on an older version?)
Any help would be greatly appreciated.
For reference, here is the .cshtml page calling this:
#page
#using WebPortal.ComponentLibrary.Common
#model WebPortal.Pages.Reporting.ReportingModel
#{
ViewData["Title"] = "Reports";
}
<div class="text-center">
<h1 class="display-4">Welcome to the Web Portal</h1>
<component type="typeof(SearchBar)" render-mode="static" />
</div>
I've tried each of the options for the render-mode with no luck.
I've also already added "services.AddServerSideBlazor()" and "endpoints.MapBlazorHub();" to the Startup.cs page.
PS: As a side note question, not a big deal, I saw some references to components being called with the syntax
<SearchBar />
, but that's not working for me. Has that been removed? I like that syntax better as it seems cleaner.
You seem to be mixing up Razor and Service Side Pages with Blazor. What do you want to develop? If it's Blazor, watch an up to date Blazor video and start with deploying the standard Blazor Template. Your code works in a BLAZOR page.

Google model-viewer - how to set max zoom?

I'm very happy about what I'm able to do using Google model-viewer. It's relatively configurable, but there's more I'd like to be able to do with the camera-- for instance, setting a max zoom/min distance from the target. I've found code that seems to suggest how to modify this, but I don't know how to override the script delivered via the CDN. Is my only option to download using npm?
Excuse my naivete!
You can see this issue Zoom in/out #1172
Now it's possible to use camera control settings:
max-camera-orbit
min-camera-orbit
max-field-of-view
min-field-of-view
model-viewer(
src="https://cwervo.com/assets/3D-models/logo.glb" ios-
src="https://cwervo.com/assets/3D-models/logo-3m-scaled.usdz"
auto-rotate
camera-controls
min-camera-orbit='auto auto 100%'
max-camera-orbit='auto auto 100%'
min-field-of-view='110deg'
max-field-of-view='110deg'
)
Source: https://codepen.io/schmidtsonian/pen/VwvEwVw
I'm the maintainer of the <model-viewer> project. You aren't crazy; we haven't added the ability to control this yet.
But don't worry! We are planning to add this feature to a release very soon (currently planned for v0.7.0). Please track https://github.com/GoogleWebComponents/model-viewer/issues/458 for progress!
[edit] Also to answer your question about NPM: you can download the module from NPM and assemble a customized version of the pieces that make up <model-viewer>. Also, you could fork the project and patch it that way. I don't necessarily recommend these things, but they are options if you are desperate. If you go this route, I highly recommend asking questions on our Github project page. We are friendly and responsive to everyone.

How to export Apiary Blueprint as PDF, stand-alone HTML or similar "deliverable"?

We need to export our Apiary Blueprint for task assignment purposes as a self containing "deliverable" like PDF or ZIP or similar. I'm aware of the feature request and the discussion below. Is it possible to "hack" something better than the poor html exporter? Maybe by injecting some css style into the page with chrome? Has somebody found a "good-enough" solution?
Ján Sáreník mentioned aglio, you can make it work locally by the following steps.
Save your API definition markdown (e.g. myfile.md)
Install aglio npm install aglio -g
Start aglio server aglio -i myfile.md -s
Open localhost:3000 and download the HTML file
Hack the HTML by commenting out the <div id="localFile" ...>...</div> warning
Hack the HTML by replacing http://localhost:3000/ with empty string everywhere
Aaand it's done.
You can use https://github.com/danielgtaylor/aglio to render API Blueprint into static HTML files which can be zipped (or maybe also PDF-exported, but I haven't tried).

How can I figure out what this frontpage extension code is supposed to do?

I was asked to assist with troubleshooting a problem. Functionality on a site "stopped working" and I was asked to figure out what is wrong. The following is the error:
FrontPage Error.
User: please report details to this site's webmaster.
Webmaster: please see the server's application event log for more details.
On the page I'm seeing the following:
<!--webbot BOT="GeneratedScript" endspan --><form method="POST" action="../_vti_bin/shtml.dll/index.html" name="FrontPage_Form1" onsubmit="return FrontPage_Form1_Validator(this)" language="JavaScript" webbot-action="--WEBBOT-SELF--">
<!--webbot bot="SaveResults" startspan
U-File="/results.csv" S-Format="TEXT/CSV"
S-Label-Fields="FALSE" B-Reverse-Chronology="FALSE" S-Builtin-Fields
S-Form-Fields="TYPE NAME ADDRESS CITY STATE ZIP "
U-Confirmation-Url="confirmation.html" --><input TYPE="hidden" NAME="VTI-GROUP" VALUE="0"><!--webbot
bot="SaveResults" endspan i-checksum="43374" -->
<div align="center">
...
I look at the directory structure and find that even after forcing display of hidden directories/files, _vti_bin is GONE. It's nonexistent. After a little research this leads me to believe that this code is using frontpage extensions, and they have apparently been removed. Does that look accurate?
I'm completely inexperienced with frontpage extensions. Is what this is doing is it's using another file called shtml.dll and calling it on the path /index.html, basically just doing a postback?
I'm looking at the webbot part which seems to be what it's trying to accomplish. Is it merely appending the form results to a CSV and that is all?
I see a few other bits like this but they all refer to validators which I should be able to handle in javascript just fine.
I ended up looking at the server configuration and finding that as far as the server was concerned, frontpage extensions were still installed. I then told it to re-install and in the morning it was working again.