Enable open in terminal option for elementaryOS file manager

This is how to add an "Open terminal here" entry to the eOS file manager.

Create /usr/share/contractors/openinterminal.contract with these contents:

[Contractor Entry]
Name=Open terminal here
Icon=terminal
Description=Open terminal here
MimeType=inode;application/x-sh;application/x-executable;
Exec=io.elementary.terminal -w %U
Gettext-Domain=io.elementary.terminal

Restart the terminal, and voilla!


Display Blogger feed on HTML site using RSS

This is how to parse and display a blogger feed on your website. Replace the URL of the API-call in the last script tag to change the RSS feed the script pulls. Update the months array to change the language for the date to English.


<script>
let postTitle = new Array();
let postContent = new Array();
let postUrl = new Array();
let postDate = new Array();

let months = [&quot;januari&quot;, &quot;februari&quot;, &quot;maart&quot;, &quot;april&quot;, &quot;mei&quot;, &quot;juni&quot;, &quot;juli&quot;, &quot;augustus&quot;, &quot;september&quot;, &quot;oktober&quot;, &quot;november&quot;, &quot;december&quot;];

let feedSize = 0;

function callback(apiData) {
    function load() {
        if (&quot;entry&quot; in apiData.feed) {
            let feedSize = apiData.feed.entry.length;
            for (let i = 0; i &lt; feedSize; i++) {
                let post = apiData.feed.entry[i];
                console.log(post)

                var p = post.published.$t.substring(5, 7);

                for (var f = 0; f &lt; post.link.length; f++) {
                    if (post.link[f].rel == &quot;alternate&quot;) {
                        postUrl.push(post.link[f].href);
                        break
                    }
                }

                let postDateDay = post.published.$t.substring(8, 10);
                let postDateMonth = months[parseInt(p, 10) - 1];
                let postDateYear = post.published.$t.substring(0, 4);

                postDate.push(`${postDateDay} ${postDateMonth} ${postDateYear}`);

                postTitle.push(post.title.$t);
                postContent.push(post.content.$t);
            }
        }
    }

    function display() {
        let postCount = postTitle.length;
        var currentPost = 0;
        while (currentPost &lt; postCount) {        
            document.write(`
                &lt;article class=&quot;post mt-10&quot;&gt;
                    &lt;div class=&quot;text-center my-7 max-w-xl mx-auto&quot;&gt;
                        &lt;h1 id=&quot;post-${currentPost}&quot; class=&quot;mb-0 text-4xl&quot;&gt;${postTitle[currentPost]}&lt;/h1&gt;
                        &lt;p class=&quot;my-5 bold&quot;&gt;${postDate[currentPost]}&lt;/p&gt;
                    &lt;/div&gt;
    
                    &lt;section&gt;
                        ${postContent[currentPost]}
                    &lt;/section&gt;
                &lt;/article&gt;
    
                &lt;hr class=&quot;my-7 border-none&quot;&gt;
            `);
    
            currentPost++
        }
    }
    
    load();
    display();
}
</script>
<script src="https://webdevelopment-en-meer.blogspot.com/feeds/posts/default?max-results=10&start-index=1&alt=json-in-script&callback=callback"></script>







form.submit() is not a function (JavaScript)

Recently, I tried sending a form using JS. I was sure I didn't make typos and errors in my code. Turns out you can't set the name attribute of an input submit and use the JS function submit() at the same time. JS tries to access submit, finds the button and thinks: "Weird, this isn't a function". So, make sure you didn't set the name attribute of any input to submit. It can conflict with the JS function.



Publish posts using Blogger API in PHP

This is how to create a blogpost using the Google Client Library for PHP.

To setup:

  1. Go to https://console.developers.google.com
  2. Add an project, and tap "Credentials"
  3. Tap "Create data" and create an Client-ID OAuth
  4. Choose the "Webapp" and enter the path to your server in the "Authorized diversion URIs" textbox
  5. Hit "Create", and hit OK
  6. Click on the Client-ID you just generated
  7. Click "Download JSON"
  8. Download the file, and rename it to client_secret.json

Use this script to create and publish posts. Make sure to first enter the path to your client_secret.json.

<?php
// This script creates a post
// Made by Robin Boers

// load Google Api
require_once '../api/vendor/autoload.php';

session_start();

$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];

// Authenticate user with OAuth 
$client = new Google_Client();
$client->setAuthConfig('/path/to/client_secret.json');
$client->setApplicationName('Example App');
$client->setRedirectUri($redirect_uri);
$client->setScopes(array('https://www.googleapis.com/auth/blogger')); 

if (!isset($_SESSION['access_token']) && isset($_GET['code'])) {
    $client->authenticate($_GET['code']);
    $access_token = $client->getAccessToken();
    $_SESSION['access_token'] = $access_token;
}

if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
    
    // First set the accesstoken
    $client->setAccessToken($_SESSION['access_token']);

    $blogger = new Google_Service_Blogger($client);

    // Get blog information
    $blog = $blogger->blogs->getByUrl('http://stupidstuffwastaken.blogspot.com'); // Replace this URI with your blog's URI
    $blogId = $blog->getId();
    $blogName  = $blog->getName();

    $postId = "651261343944639929"; // If you want to update a post

     // Creating post
     $mypost = new Google_Service_Blogger_Post();
     $mypost->setTitle("Example heading");
     $mypost->setContent("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");

     $data = $blogger->posts->insert($blogId, $mypost); // or update post like this: $data = $blogger->posts->update($blogId, $postId, $mypost);
     var_dump($data);
}
?>

Missing depedencies when installing rofi from source on Ubuntu

When installing rofi 1.6.1 from source on Ubuntu, there are some missing dependencies. To install those, enter this command:


sudo apt install libxcb-xkb-dev libxcb-ewmh-dev libxkbcommon-x11-dev libxcb-icccm4-dev libxcb-xinerama0-dev libxcb-xrm-dev build-essential cmake extra-cmake-modules xcb

The check version in the default repos is also outdated, so you need to compile that from source too.


Alternative to Gala taskswitcher using Rofi

I kinda hate the default Alt+Tab switcher in Pantheon, so I use Rofi to fix that. This is how to use rofi as Alt+Tab switcher. Make sure you have rofi version 1.6.1 installed for this to work propperly.

Create a new scriptfile called alttab.sh with this content:

#!/usr/bin/env bash
xdotool mousemove 960 540 && rofi -no-config -theme alttab -kb-cancel "Alt+Escape,Escape" -kb-accept-entry '!Alt-Tab,!Alt+Down,!Alt+ISO_Left_Tab,!Alt+Up,Return,!Alt+Alt_L' -kb-row-down 'Alt-Tab,Alt+Down,Down,ISO_Left_Tab' -kb-row-up 'Alt+ISO_Left_Tab,Alt+Up,Up' -show window -selected-row 1 
exit

Now make it executable:

sudo chmod +x ./alttab.sh

Delete default Alt+Tab shortcut in Switchboard -> Keyboard -> Shortcuts -> Windows
Now link to the file you created earlier and assign it to Alt+Tab.

This looks the best using this custom rofi theme I made: https://github.com/RobinBoers/dotfiles/blob/master/.config/rofi/alttab.rasi



Phoenix Framework doesn't work on Arch Linux due to node-sass

While trying to setup a chat app on Arch Linux using Phoenix Framework I ran into a lot of nodejs related errors. First of all, make sure you're using nodejs 14 or maybe 15. Everything above is absolute hell. I recommend using nvm.

I still got a lot of errors using node-sass. It prevented me from using websockets by crashing the building process. Turns out you can just replace node-sass with sass in package.json

Just remove this line:

"node-sass": "xx.xx.xx"

And replace it with:

"sass": "^1.22.10"

Ta da! All problems fixed. I have no idea why the guys over at Phoenix Framework don't just ship this as the default!

Sources:


Send emails using PHP

This is how to send an email using PHP. For this to work, PHP needs access to the sendmail binary (and permission to use it). You have to set the path to this binary in php.ini (check where it is located using the phpinfo() function). Place it under the line [mail function]. Here's an example:

[mail function]
sendmail_path = /usr/sbin/sendmail

On Windows you also have to set your SMTP server. Here's another example:

[mail function]
SMTP = localhost
smtp_port = 25

sendmail_from = robin@geheimesite.nl

This is a simple script to send emails using PHP:

<?php 
$msg = " Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam et fermentum lorem. Proin tristique tortor in metus mattis euismod. Donec ligula erat, ultrices at dapibus ornare, convallis ut ligula. Nullam aliquet nec enim eget consectetur. Quisque hendrerit, purus quis luctus vestibulum, massa dui commodo lectus, luctus iaculis nisl arcu eu odio. Integer porta ultrices libero, et vestibulum metus lacinia vitae. Etiam ipsum arcu, pharetra ut maximus nec, imperdiet vel ex. Donec ut ligula vel risus pellentesque porttitor. Nam lectus leo, tincidunt et justo pellentesque, dictum hendrerit neque. Pellentesque consectetur, mauris id lobortis sagittis, nisl tortor lacinia est, vel rhoncus lorem libero ut erat. Nam maximus iaculis mollis. Nunc rhoncus sagittis nulla. Nulla porta dolor sit amet ultricies ultrices. ";

$email = "robin@geheimesite.nl";
$subject = "Example email";

$msg = wordwrap($msg,70);

mail($email,$subject,$msg);
?> 

On the PHP documentation there also was a usefull comment (credits to pouletfou at gmail dot com) describing how to use a fakemail binary to check the logs for testing purposes:

#!/usr/bin/php
<?php
//====================================================
// Program : Fake send mail
// Author : pouletfou at gmail
// Description : save this file as /usr/sbin/sendmail
// and you can test your PHP applications using mail
// by looking at the /tmp/fakesendmail.log files.
//====================================================

define('LOGFILE','/tmp/fakesendmail.log');

$log = fopen (LOGFILE,'a+');

fwrite($log,"\n".implode(' ',$argv).
" called on : ".date('Y-m-d H:i:s')."\n");

fwrite($log,file_get_contents("php://stdin"));
fwrite($log,
"\n===========================================================\n");
fclose($log);

?>

Sources:


Assign Rofi to super key in Pantheon

I'm used to use the super key to search, because I used Windows for a long time, so I like to assign Rofi to the super key.

gsettings set org.gnome.mutter overlay-key "'Super_L'"
gsettings set org.pantheon.desktop.gala.behavior overlay-action "rofi -show drun"
You can use any launcher. In this example I'm using Albert:
gsettings set org.gnome.mutter overlay-key "'Super_L'"
gsettings set org.pantheon.desktop.gala.behavior overlay-action "albert"

Enable tray indicators in Pantheon

Some apps use the old system tray. To view them in the elementaryOS tray edit /etc/xdg/autostart/indicator-application.desktop and change this line:

OnlyShowIn=Unity;GNOME;
to
OnlyShowIn=Unity;GNOME;Pantheon;

Now install the old panel indicator from launchpad.net:
http://ppa.launchpad.net/elementary-os/stable/ubuntu/pool/main/w/wingpanel-indicator-ayatana

After relog you should be able to see the icons in wingpanel.





Smaller GTK headerbars on non-CSD windows

This is how to make the titlebars on non-CSD windows in Metacity, Marco, Mutter and Gala smaller using gtk.css

This is mostly for themes like Ambiance that were not designed for these window managers.

Put this in ~/.config/gtk-3.0/gtk.css. This makes the headerbars on non-CSD windows smaller to make them look better.

/*
 Decrease the size of head bars for non-CSD applications
 Gnome 20 (Fedora 24) compatible version
 https://unix.stackexchange.com/questions/276951/how-to-change-the-titlebar-height-in-standard-gtk-apps-and-those-with-headerbars
*/

/* x11 and xwayland windows */
window.ssd headerbar.titlebar {
    padding: 4px; 
    padding-right: 5px;
    min-height: 0;
    /* remove border between titlebar and window */
    border: none;
}

window.ssd headerbar.titlebar button.titlebutton {
    padding: 2px;
    min-height: 0;
    min-width: 0;
}


/* native wayland ssd windows */
.default-decoration {
    padding: 4px;
    padding-right: 5px;
    min-height: 0;
    /* remove border between titlebar and window */
    border: none;
}

.default-decoration .titlebutton {
    padding: 2px;
    min-height: 0;
    min-width: 0;
}