Code Monkey home page Code Monkey logo

Comments (13)

slavarazum avatar slavarazum commented on May 29, 2024

How do you use a custom plugin with Vue Froala Wysiwyg ?

from nova-froala-field.

jeffreyzant avatar jeffreyzant commented on May 29, 2024

Hey, thanks for replying. I suppose by adding them to the webpack file. But that would mean i'll have to fork this and change the package. There has to be a better way to do this? I've looked in the repo you mentioned but I could not find any helpful examples.

I've tried a couple of things to make it work, but maybe i'm just missing out on a small piece.

from nova-froala-field.

slavarazum avatar slavarazum commented on May 29, 2024

To help with this question, I need to know how you created a custom plugin and use it without Nova. Maybe you used specific tutorial etc.
In Nova you can add additional scripts and styles like this:

Nova::serving(function (ServingNova $event) {
       Nova::style('custom-styles', public_path('css/nova/custom-styles.css'));
       Nova::script('custom-script', public_path('js/nova/custom-script.js'));
});

from nova-froala-field.

jeffreyzant avatar jeffreyzant commented on May 29, 2024

I am trying to use this plugin:
https://github.com/ecoach-lms/froala-audio

I have tried adding the .css and .js after I ran the javascript through webpack to add jQuery. But I am receiving a JS error that the Froala Editor is not found (or not accessible).

froala-audio-script:87 Uncaught TypeError: Cannot read property 'POPUP_TEMPLATES' of undefined
    at froala-audio-script:87
    at Object.<anonymous> (froala-audio-script:815)
    at Object.405 (froala-audio-script:816)
    at __webpack_require__ (froala-audio-script:20)
    at Object.404 (froala-audio-script:71)
    at __webpack_require__ (froala-audio-script:20)
    at froala-audio-script:63
    at froala-audio-script:66
  $.extend($.FE.POPUP_TEMPLATES, {
    'audio.insert': '[_BUTTONS_][_BY_URL_LAYER_][_UPLOAD_LAYER_][_PROGRESS_BAR_]',
    'audio.edit': '[_BUTTONS_]'
  });

I'm using the following code:

mix.styles('node_modules/froala-audio/froala-audio.css', 'public/css/vendor/froala_audio.min.css');
mix.js('node_modules/froala-audio/froala-audio.js', 'public/js/vendor/froala_audio.min.js')
   .autoload({
       jquery: ['$', 'jQuery', 'jquery', 'window.jQuery'],
   });`
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();

        Nova::serving(function (ServingNova $event) {
            Nova::style('froala-audio-styles', public_path('css/vendor/froala_audio.min.css'));
            Nova::script('froala-audio-script', public_path('js/vendor/froala_audio.min.js'));
        });
    }

from nova-froala-field.

slavarazum avatar slavarazum commented on May 29, 2024

Looks like this plugin not working properly with vue-froala-wysiwyg. I have tried to include it directly into the nova-froala-field package (which use vue-froala-wysiwyg) and it crashed with TypeError: $ is undefined. It depends on jQuery without any checks.

from nova-froala-field.

jeffreyzant avatar jeffreyzant commented on May 29, 2024

That's cause within your webpack.mix.js you are only including jQuery on $ and on jQuery. But this plugin requires it as window.jQuery. You'll only have to add that to your Webpack file to make that part (jQuery) work..

from nova-froala-field.

jeffreyzant avatar jeffreyzant commented on May 29, 2024

Just npm install froala-audio
Add this to the PluginsLoader.js

     await import(
            'froala-audio/froala-audio'
     )

Change the webpack file to:

           new webpack.ProvidePlugin({
               $: "jquery",
               jQuery: "jquery",
               "window.jQuery": "jquery",
           })

npm run production

And it will work.

from nova-froala-field.

slavarazum avatar slavarazum commented on May 29, 2024

You are right. But as I can see webpack has some limitations for dynamic imports to be able to easy import of custom plugins without changing PluginsLoader.js directly.

Will investigate this question deeper and welcome any implementation ideas here or in PR.

from nova-froala-field.

jeffreyzant avatar jeffreyzant commented on May 29, 2024

I've thought about a couple of solutions, but I don't think it's doable without compiling the assets outside the package. Would using an Artisan command to (re)compile the assets and publishing them to the /public folder be a likeable solution?

  • NPM plugins to install could be added to the config/froala-field.php
  • Webpack file needs to add the other jQuery bindings
  • Artisan command
    -- To install npm plugins
    -- Run the webpack file
    -- Publish the vendor assets to the public folder with the existing command
    -- Copy the generated field.js and the generated field.css
  • ServiceProvider looks for these dependencies in the public folder before using the local one for generated dependencies

from nova-froala-field.

slavarazum avatar slavarazum commented on May 29, 2024

@jeffreyzant Will try to find a less complex solution

from nova-froala-field.

klimov-paul avatar klimov-paul commented on May 29, 2024

There is no way for simple integration of the 3rd party or hand-made plugin.
You'll have to re-compile the assets of this extension with manual adjustments.

I have developed the following console command to do so:

<?php

namespace App\Nova\Extensions\Froala\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;

/**
 * BuildFroalaAssets builds custom assets for "froala/nova-froala-field" extension.
 *
 * Unfortunally this is the only way to apply custom plugins to the Froala editor.
 *
 * ```php
 * class NovaServiceProvider extends NovaApplicationServiceProvider
 * {
 *     public function boot()
 *     {
 *         parent::boot();
 *
 *         Nova::serving(function (ServingNova $event) {
 *             Nova::script('nova-froala-field', storage_path('nova/froala/dist/js/field.js'));
 *         });
 *     }
 *
 *     public function register()
 *     {
 *         $this->commands([
 *             BuildFroalaAssets::class,
 *         ]);
 *     }
 * }
 * ```
 *
 * @see https://novapackages.com/packages/froala/nova-froala-field
 */
class BuildFroalaAssets extends Command
{
    /**
     * {@inheritdoc}
     */
    protected $signature = 'nova:build-froala-assets';

    /**
     * {@inheritdoc}
     */
    protected $description = 'Build custom assets for Nova Froala editor field';

    /**
     * @var string path to the Nova Froala field extension.
     */
    protected $srcPath;

    /**
     * @var string path used for the assets build.
     */
    protected $buildPath;

    /**
     * {@inheritdoc}
     */
    public function __construct()
    {
        parent::__construct();

        $this->srcPath = base_path('vendor/froala/nova-froala-field');
        $this->buildPath = storage_path('nova/froala');
    }

    public function handle()
    {
        $this->info('Building Froala assets...');

        $this->prepareSourceFiles();

        $this->patchSourceFiles();

        $this->buildAssets();

        $this->info('...complete.');
    }

    protected function prepareSourceFiles()
    {
        $this->info('Prepare source files...');

        if (! file_exists($this->buildPath)) {
            File::makeDirectory($this->buildPath, 0775, true);
        }

        $names = [
            'resources',
            '.babelrc',
            'package.json',
            'webpack.mix.js',
        ];

        foreach ($names as $name) {
            $srcName = $this->srcPath.DIRECTORY_SEPARATOR.$name;
            $dstName = $this->buildPath.DIRECTORY_SEPARATOR.$name;
            if (is_dir($srcName)) {
                File::copyDirectory($srcName, $dstName);
            } else {
                File::copy($srcName, $dstName);
            }
        }

        $resourcePath = realpath(__DIR__.'/../..');

        $names = [
            'resources/js/custom-plugins.js',
        ];

        foreach ($names as $name) {
            File::copy($resourcePath.DIRECTORY_SEPARATOR.$name, $this->buildPath.DIRECTORY_SEPARATOR.$name);
        }

        $this->info('...done.');
    }

    protected function patchSourceFiles()
    {
        $this->info('Patching source files...');

        $fieldSrcFile = $this->buildPath.'/resources/js/field.js';
        $patchContent = "\n\nrequire('./custom-plugins');";

        file_put_contents($fieldSrcFile, file_get_contents($fieldSrcFile).$patchContent);

        $this->info('...done.');
    }

    protected function buildAssets()
    {
        $this->info('Building assets...');

        passthru('(cd '.escapeshellarg($this->buildPath).'; yarn install; yarn run prod;)');
    }
}

Custom plugin JS code placed at 'custom-plugins.js' may look like following:

/**
 * @see https://www.froala.com/wysiwyg-editor/docs/concepts/custom/button
 */
import FroalaEditor from 'froala-editor';

FroalaEditor.DefineIcon('insert', {NAME: 'plus', SVG_KEY: 'add'});
FroalaEditor.RegisterCommand('insert', {
    title: 'Insert HTML',
    focus: true,
    undo: true,
    refreshAfterCallback: true,
    callback: function () {
        this.html.insert('My New HTML');
    }
});

from nova-froala-field.

slavarazum avatar slavarazum commented on May 29, 2024

Great! I think it will be useful If you need to integrate a custom plugin.

from nova-froala-field.

klimov-paul avatar klimov-paul commented on May 29, 2024

See https://github.com/illuminatech/override-build

from nova-froala-field.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.