External markdown file in WordPress

If you want keep an external markdown file and include it in a WordPress page, you can follow these steps:

  • add a js file, such as md-block.js, in your js theme folder (typically /wp-content/themes/your-theme/js/ )
  • modify the functions.php file, in your root theme folder,. adding this code:
// per markdown BEGIN

function carica_md_block() {
    wp_enqueue_script(
        'md-block',
        get_stylesheet_directory_uri() . '/js/md-block.js',
        array(),
        null,
        true
    );
}
add_action('wp_enqueue_scripts', 'carica_md_block');

add_filter('script_loader_tag', function($tag, $handle, $src) {
    if ($handle === 'md-block') {
        return '<script type="module" src="' . esc_url($src) . '"></script>';
    }
    return $tag;
}, 10, 3);

function shortcode_scheda_md($atts) {
    $atts = shortcode_atts(array(
        'file' => ''
    ), $atts);

    $file = basename($atts['file']);

    if (empty($file) || pathinfo($file, PATHINFO_EXTENSION) !== 'md') {
        return '';
    }

    $url = content_url('/uploads/some-path/' . rawurlencode($file));

    return '<md-block src="' . esc_url($url) . '"></md-block>';
}
add_shortcode('scheda_md', 'shortcode_scheda_md');

// per markdown END
  • you can put your md files in the path above set: /uploads/some-path/ . Note that the folder some-path could be a symlinked one, from your local PC.
  • in the wordpress page when you want include a md file you can write, using HTML (customized), [scheda_md file="the-name-of-the-file.md"], where that file, obviously, should be in /some-path/ folder.

Modify several symlinks at once

adding ../ to the target path

If you have to add the same property, i.g. ../ to several symlinks in the same folder, you can use this code:

#!/bin/bash

for f in *; do 
  [ -L "$f" ] || continue
  [ -e "$f" ] && continue   # skip the valid ones

  target=$(readlink "$f")
  [[ "$target" != /* ]] && ln -snf ../"$target" "$f"
done

You can either save this code in a bash file, or paste it directly in a terminal.

another case: replace the name of the target file

If you have now target files renamed with “-” instead of space ” “, you can use this code:

for f in *; do
  [ -L "$f" ] || continue
  [ -e "$f" ] && continue

  target=$(readlink "$f")
  newtarget=${target// /-}

  [[ "$target" != "$newtarget" ]] && ln -snf "$newtarget" "$f"
done

wp plugins

wp users

An useful wp plugin is wp users that allow you to collect subscriptions from the readers of your blog.

It has add-ons such as captcha that, linked with Google captcha, allow you to select humans from robots (and spam).

Be careful however to set v2 rather than v3, both in Google and in your wp plugin settings, otherwise you couldn’t be more able to login.

Avidemux, a good video editor

If you don’t need a sophisticated video editing, but a linear editing one, Avidemux can be still a good option.

However it has not an official updated release (for Ubunutu) since 2022. An alternative to get it updated is flatpack, but with flatpack Avidemux uses a very huge quantity of disk space.

Another good linear video editing app would be Lesslosscut, but it is an app even bigger (and sucking ram) than Avidemux. Not to speak of installation problems with wayland.

So I resolved to:

  • uninstall avidemux flatpack and so free an huge space on disk:
flatpak uninstall org.avidemux.Avidemux
flatpak uninstall --unused
  • download a Nightly automated build and install it. In this way: I unpacked the files and do this command:
sudo dpkg -i *.deb

and I fixed missing dependencies

sudo apt update
sudo apt install libqt6core6 libqt6gui6 libqt6widgets6 libqt6network6 libqt6openglwidgets6
sudo apt install libfaac0

sudo apt –fix-broken install

Now I have an updated Avidemux app, with a fair space usage.

Regex in Kate

It could be very difficult using regex in Kate, if you have php files that have still an html (and not php) as content structure.

In this case you can try to use, al filter, not *.php, but *.*.

Moreover it could be necessary to use this regex code for multiline tags :

<style type="text/css">((.|\n)*?)</style>

or

<script type="text/javascript">((.|\n)*?)</script>

and so on.

Permalink in local wordpress

It could happen that wordpress in localhost doesn’t see textual permalink, such as the article name, or the like, and see only ”simple” permalink with a final suffix such as ?p=123.

The problem is an apache problem. To fix it, you have to:

  • modifying the apache config file, with a name such as apache2.conf or another name, depending of your S.O., by adding something like
<Directory /var/www/your-wordpress-path/>
	Options Indexes FollowSymLinks
	AllowOverride all
	Require all granted
</Directory>
  • then you have to do these bash commands  (in a terminal):
sudo a2enmod rewrite
sudo systemctl restart apache2
  • then you have to put in your (root wordpress) folder an .htaccess file with a content like:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /your-wordpress-path/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /your-wordpress-path/index.php [L]
</IfModule>

your-wordpress-path is the path following http://localhost, so don't have to write http://localhost

At this point you should be able to set a textual permalink, after setting it, save it, and try.

mysql multiple tables rename

To rename many mysql/mariadb tables with a same prefix, you can uso this script (in a terminal)

mysql -u root -p -N -e " SELECT CONCAT('RENAME TABLE \', table_name, '\ TO \', REPLACE(table_name, 'oldprefix_', 'newprefix_'), '\;') FROM information_schema.tables WHERE table_schema = 'your-database' AND table_name LIKE 'oldprefix_%'; " > renamed.sql 

In this way will created the file renamed.sql (same tables, with different names), that you then can use to replace your database, with

mysql -u root -p yourdatabase < renamed.sql

If you have a wordpress database you have also to check options and meta tables, removing oldprefixes, with:

UPDATE oldprefix_options
SET option_name = REPLACE(option_name, 'oldprefix_', 'newprefix_')
WHERE option_name LIKE 'oldprefix\_%';

and

UPDATE abc_usermeta
SET meta_key = REPLACE(meta_key, 'oldprefix_', 'newprefix_')
WHERE meta_key LIKE 'oldprefix\_%';

And finally, you could check if there are any oldprefix, in options with

SELECT option_name FROM newprefix_options WHERE option_name LIKE 'oldprefix\_%';

same for meta:

SELECT meta_key FROM newprefix_usermeta WHERE meta_key LIKE 'oldprefix\_%';

Automatically link youtube videos

You could try with a php function the following:

<?php
function getYouTubeVideosByTag($tag, $maxResults = 6) {
    $apiKey = '[your youtube API key]';
    $channelId = '[your-youtube-channel-ID';

    // Forza formato hashtag
    $query = urlencode('#' . $tag);

    $url = "https://www.googleapis.com/youtube/v3/search?part=snippet&type=video&order=date&maxResults=$maxResults&q=$query&channelId=$channelId&key=$apiKey";

    $response = file_get_contents($url);

    if ($response === FALSE) {
        return [];
    }

    $data = json_decode($response, true);

    $videos = [];

    if (!empty($data['items'])) {
        foreach ($data['items'] as $item) {
            if (!isset($item['id']['videoId'])) continue;

            $videos[] = [
                'title' => $item['snippet']['title'],
                'videoId' => $item['id']['videoId'],
                'description' => $item['snippet']['description'],
                // 'thumbnail' => $item['snippet']['thumbnails']['medium']['url']
            ];
        }
    }

    return $videos;
}
?>

Obviously you have to link this function in every web page you want links your videos, and in these pages you can call that function by a code like this:

<?php
if (!empty($youtubetag)) {

    if (is_array($youtubetag)) {
        $query = implode(' OR ', array_map(fn($t) => '#' . $t, $youtubetag));
        $videos = getYouTubeVideos($query, 5);
    } else {
        $videos = getYouTubeVideosByTag($youtubetag, 3);
    }

    if (!empty($videos)) {
        ?>

        <section class="youtube-videos">
        <h2>🎙️ Our podcast (YouTube)</h2>

            <ul>
                <?php foreach ($videos as $video): ?>
                    <li class="podcast">🎙️
                        <a href="https://www.youtube.com/watch?v=<?= $video['videoId'] ?>"><strong><?= htmlspecialchars($video['title']) ?></strong></a>:
                       <?= htmlspecialchars(substr($video['description'], 0, 120), ENT_QUOTES | ENT_HTML5, 'UTF-8', false) ?>
                    </li>
                <?php endforeach; ?>
            </ul>
        </section>

        <?php
    }
}
?>

Finally, you should define, possibly in the head of each php page, where you want to link youtube videos, the variable $youtubetag:

$youtubetag="my tag";
or 
$youtubetag="['mytag1', 'mytag2']";

Disable Caps Lock

It could happen that you inadvertently press and it turn out all the word you write are are UPPERCASE.
To avoid this, in Linux, you can

  • go to System Settings > Input Devices > Keyboard -> Key bindigs
  • in Key bindings -> Configure Keybord options -> Caps Lock behavior -> Caps Lock disabled.
  • and then, always in Configure Keybord options -> switching to another layout -> select both
    • Both Shifts together
    • Caps Lock.

In this way your Caps Lock will be usually disabled, but you can use it by pressing both the shift keys.

BUT…
If you have wayland and espanso the upper configuration can give problems.
So the simpler way is:

  • to disable (permanently) caps lock : Key bindings -> Configure Keybord options -> Caps Lock behavior -> Make Caps Lock an additional Ctrl

How to toggle the opened <details>

If you have two <details> tags, and you want to close one, when you open the other, you can use this short js:

<script>
const details = document.querySelectorAll("details");

details.forEach(d => {
  d.addEventListener("toggle", () => {
    if (d.open) {
      details.forEach(other => {
        if (other !== d) {
          other.removeAttribute("open");
        }
      });
    }
  });
});
</script>