laravel – 使用 vite 出現 bash: vite: command not found

我在 laradock 中架設 laravel ,預設打 npm run dev 會正常觸發 vite 沒問題,但如果直接打 vite 會發生找不到的情況。因此 vite 安裝到 global 就沒問題了

npm i -g vite

TinyMCE 讓編輯器可以放置有 script 的媒體方法

最近遇到一個案子需要在 TinyMCE 中嵌入如 TikTok 的媒體。

例如

<blockquote class="tiktok-embed" cite="https://www.tiktok.com/@barbin1106/video/7313145378650574085" data-video-id="7313145378650574085" style="max-width: 605px;min-width: 325px;" > <section> <a target="_blank" title="@barbin1106" href="https://www.tiktok.com/@barbin1106?refer=embed">@barbin1106</a> <p>变装再来一次</p> <a target="_blank" title="♬ 原声 - 百变的芭比👯👯 - 芭比💃💃" href="https://www.tiktok.com/music/原声-百变的芭比👯👯-7313145397211024133?refer=embed">♬ 原声 - 百变的芭比👯👯 - 芭比💃💃</a> </section> </blockquote> <script async src="https://www.tiktok.com/embed.js"></script>

在預設的狀態下 script 與裡面的一些 attributes 會被 TinyMCE 基於系統安全過濾掉。因此參考網友方法:https://stackoverflow.com/questions/24614301/script-tags-in-tinymce-fields-are-not-saving-correctly

增加以下三個參數就解決了

tinymce.init({
            // ....
            allow_script_urls: true,
            valid_elements: '*[*]',
            extended_valid_elements: 'script[language|type|src]',

參考官方說明

laravel – livewire 3 – dispatch 給 JS 出現錯誤:Uncaught TypeError: Illegal invocation

如果在前端設置監聽 wire 的事件並取名為 message 瀏覽器會出現下列錯誤警告。

    Uncaught TypeError: Illegal invocation
    at l._onMessage (<anonymous>:1:60569)
    at dispatchEvent (livewire.js?id=f121a5df:4505:12)
    at dispatch3 (livewire.js?id=f121a5df:4472:5)
    at livewire.js?id=f121a5df:8815:9
    at Array.forEach (<anonymous>)
    at dispatchEvents (livewire.js?id=f121a5df:8809:16)
    at Array.<anonymous> (livewire.js?id=f121a5df:8786:5)
    at trigger (livewire.js?id=f121a5df:433:34)
    at Component.processEffects (livewire.js?id=f121a5df:4392:7)
    at handleResponse (livewire.js?id=f121a5df:3990:24)

這是我的程式碼,使用了 $this->dispatch("message", ...)

我的前端 JS

如圖片所述,不要使用 “message” 我猜應該是 livewire 已經內定名稱了,但是錯誤沒有被 livewire 友善的捕獲。建議名稱換掉就解決這個問題。

livewire – 從 JavaScript 向後端 dispatch 某個方法

假設我有一個運費的 livewire component

// app/Livewire/Cart/ShippingMethod.php

namespace App\Livewire\Cart;
use Livewire\Component;

class ShippingMethod extends Component
{

    public function myName()
    {
        dd("從前端向後端請求成功");
    }

    //...
}

在 livewire 的 view 透過點擊,打算呼叫後端 ShippingMethod::myName()

狀況一:直接使用 <script> 的方式

{{-- resources/views/livewire/cart/shipping-method.blade.php --}}

@script
<script>
    $(".click-me").on("click", function () {
        $wire.myName()
    });
</script>
@endscript
<button type="button" class="click-me">ClickMe</button>

這裡要注意:

  • 如果不是使用 @vite 而是直接寫在 view 裡面的 JS 務必添加 @script (參考官方)
  • 可以透過 @wire 直接呼叫 Server-side 的方法

狀況二:使用 @vite 的方式

{{-- resources/views/livewire/cart/shipping-method.blade.php --}}

@vite('resources/js/foreground/cart/shippingMethod')
<button type="button" class="click-me">ClickMe</button>

// resources/js/foreground/cart/shippingMethod.js

$(function () {
    $(".click-me").on("click", function () {
        var wire = Livewire.getByName("cart.shipping-method")[0];

        // 這裡就可以直接 dispatch Server-side Methods
        wire.myName()
    });
})
  • 這裡會透過全域的 Livewire 取得你的 component 名稱,通常我們都會用路徑分類 components 因此注意,如果我的 Livewire 『app/Livewire/Cart/ShippingMethod.php』那麼依照官方的命名,名稱會是 『cart.shipping-method』
  • 依照官方說法,全域 Livewire 一律會返回 $wire 對象。這裡用 getByName 因為會是 [Proxy(Object)] 因此記得要用陣列 0 來取回。可以參考

Laravel – Sitemap 超簡單生成方式

為了 SEO 我們須要在 public/sitemap.xml 自動生成。可以藉由第三方套件 https://github.com/spatie/laravel-sitemap

安裝

composer require spatie/laravel-sitemap

建立 command

這裡的方法,採用爬蟲自行前往訪問你的網站,就不須要手動指定每個網址。做好 command 指令以後,只須要放到 \App\Console\Kernel::schedule 指定什麼時候定時生成就可以了

public function handle()
{

    $file = public_path("sitemap.xml");
    $url = config("app.url");

    /**
     * 這裡須要用這個方法才能有效自動爬蟲。
     * 參考我的留言:{@link https://github.com/spatie/laravel-sitemap/discussions/505#discussioncomment-7299333}
     * 注意,config("app.url") 必須要是可以被真實訪問的網址,可以借用 ngrok 來測試。
     */
    SitemapGenerator::create($url)
            ->hasCrawled(function (Url $url) {
                // 選用生成時間   
                $url->setLastModificationDate(Carbon::today());
                return $url;
            })
            ->shouldCrawl(function (UriInterface $url) {
                // 排除掉不需要爬蟲的路徑。排除的路徑建議同步到 robots.txt 中。
                $path = $url->getPath();

                return (strpos($path, '/login-with-google') === false) and
                    (strpos($path, '/login-with-line') === false);
            })->configureCrawler(function (Crawler $crawler) {
                $crawler->ignoreRobots();
            })->writeToFile($file);
}