Introduction
Today (June 14, 2021) I answered a question on Stackoverflow regarding the Google Cloud Recommender API that required Python source code. I also created a GitHub Gist to make downloading the code easier. That got me thinking about how to display a Gist on a Laravel page. A Google search showed nothing that I could develop or learn from. This article is the results of experimenting with GitHub Gists and Laravel.
The final result is a one-line directive @gist
that will display a GitHub Gist in a view.
Creating a GitHub Gist with the CLI
It is easy to publish a file as a public Gist. GitHub recently released the GitHub CLI which makes publishing a Gist a single line command.
Command syntax:
1 |
gh gist create [<filename>... | -] [flags] |
Options:
1 2 3 4 |
-d, --desc string A description for this gist -f, --filename string Provide a filename to be used when reading from STDIN -p, --public List the gist publicly (default: private) -w, --web Open the web browser with created gist |
Example:
I put the code for my answer in the file recommender_example.py
and published it with this command:
1 |
gh gist create recommender_example.py --public -d "Python example demonstrating the Google Cloud Compute Recommender list recommendations api" |
Now, I have a public Gist. How do I display it?
Method #1 – Embedded Script
Click on the Gist URL. Above the gist is the option to grab the “Embed” script. For my gist the scripts is:
1 |
<script src="https://gist.github.com/jhanley-com/0aa83779df6fafdacd9fbcc636549d11.js"></script> |
Let’s put that script into a basic HTML file and test. Start with a basic HTML 5 template and modify it as shown below. Notice the script tag at line 10. Save the following HTML as test1.html and display it in your browser. For Windows, from the Command Prompt, start test1.html
1 2 3 4 5 6 7 8 9 10 11 12 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>My Gist</title> <meta name="description" content="My Gist"> <meta name="author" content="www2.jhanley.com"> </head> <body> <script src="https://gist.github.com/jhanley-com/0aa83779df6fafdacd9fbcc636549d11.js"></script> </body> </html> |
Method #2 – Fetch Gist JSON
If you append .json
to the end of a GitHub Gist URL, JSON is returned with details on the Gist. For example, load this URL into your browser:
1 |
https://gist.github.com/03c77114c5fb60c8fbf9dbd3749ca0e1.json |
This returns the following JSON. Note that I have truncated the <div>
portion to make the JSON readable.
1 2 3 4 5 6 7 8 9 10 11 |
{ "description": "Simple GitHub Gist", "public": true, "created_at": "2021-06-15T05:14:55.000Z", "files": [ "simple_gist.txt" ], "owner": "jhanley-com", "div": "<div>CONTENTS TRUNCATED</div>\n", "stylesheet": "https://github.githubassets.com/assets/gist-embed-6fe69c56f04992617d5f1a23949c2605.css" } |
Two of the keys are important:
stylesheet
– This is the CSS markup that GitHub provides to beautify the HTML.div
– This is raw HTML to display on your page.
Let’s write a simple PHP program to read the JSON and output an HTML page. Copy the following code to index.php
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php $url = 'https://gist.github.com/jhanley-com/03c77114c5fb60c8fbf9dbd3749ca0e1.json'; $results = file_get_contents($url, true); $json = json_decode($results, true); $html = '<head>'; $html .= '<link rel="stylesheet" href="' . $json['stylesheet'] . '">'; $html .= '</head>'; $html .= '<body>'; $html .= $json['div']; $html .= '</body>'; echo $html; |
Start the built-in web server:
1 |
php -S localhost:8000 |
Start a web browser and go to http://localhost:8000/
Method #3 – Simple Laravel View Blade
Laravel blades support the @php
directive to support PHP code. Let’s put together a simple view and a route to that view. The GitHub Gist is hardcoded in this example. Save this page to /resources/views/method3.blade.php
. In this example, the Gist is a simple two-line file to simplify testing.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@php $url = 'https://gist.github.com/03c77114c5fb60c8fbf9dbd3749ca0e1.json'; $results = file_get_contents($url, true); $json = json_decode($results, true); echo '<head>'; echo '<link rel="stylesheet" href="' . $json['stylesheet'] . '">'; echo '</head>'; echo '<body>'; echo $json['div']; echo '</body>'; @endphp |
Edit /routes/web.php
and add the following route:
1 2 3 |
Route::get('/method3', function () { return view('method3'); }); |
when developing, clear the route cache after each route change:
1 2 |
php artisan route:clear php artisan route:cache |
Start the Laravel built-in development server:
1 |
php artisan serve |
Start a web browser and go to http://localhost:8000/method3
We can enhance this by passing the gist URL as data to the view:
1 2 3 4 5 6 7 8 9 10 11 |
@php $results = file_get_contents($gist_url, true); $json = json_decode($results, true); echo '<head>'; echo '<link rel="stylesheet" href="' . $json['stylesheet'] . '">'; echo '</head>'; echo '<body>'; echo $json['div']; echo '</body>'; @endphp |
Route:
1 2 3 4 |
Route::get('/method3', function () { $gist_url = 'https://gist.github.com/jhanley-com/0aa83779df6fafdacd9fbcc636549d11.json'; return view('method3', ["gist_url" => $gist_url]); }); |
Method #4 – Custom Directive
You can define your own custom directives using the directive
method. In this example, we will extend Laravel with the @gist
directive.
Edit app/Providers/AppServiceProvider.php
and include the following code:
1 2 3 4 5 6 7 8 9 10 11 12 |
public function boot() { Blade::directive('gist', function($gist_url) { $php = <<<'PHP' $results = file_get_contents($gist_url, true); $json = json_decode($results, true); echo '<link type="text/css" rel="stylesheet" href="' . $json['stylesheet'] . '">'; echo $json['div']; PHP; return "<?php $php ?>"; }); } |
Now you can display a Gist with a directive in the view. Put the following line in a new file /resources/views/method4.blade.php
1 |
@gist($gist_url) |
Create a route:
1 2 3 4 |
Route::get('/method4', function () { $gist_url = 'https://gist.github.com/jhanley-com/0aa83779df6fafdacd9fbcc636549d11.json'; return view('method4', ["gist_url" => $gist_url]); }); |
Each time you modify AppServiceProvider.php
or the view, clear the view cache:
1 |
php artisan view:clear |
Start a web browser and go to http://localhost:8000/method4
Controlling Gist Width and Height
Use the following CSS as a starter for controlling the height and width of a Gist:
1 2 3 4 5 6 7 8 9 10 11 12 |
<style type="text/css"> .gist { overflow:auto; width:400px; } .gist .blob-wrapper.data { max-width:400px; max-height:400px; overflow:auto; } </style> |
Listing a user’s public Gists
GitHub offers an API to list a user’s public Gists. Let’s test this using curl and jq. The API returns a lot of information. We are interested in the public URL. This example sends the JSON output to jq to parse the public URL.
You will need the user’s username. In my case it is jhanley-com
. The username is easy to find. Find a user’s repository or Gist and the username is in the URL. Example for Google: https://github.com/google.
1 |
curl https://api.github.com/users/jhanley-com/gists | jq -r ".[].html_url" |
Example output:
1 2 3 4 5 6 7 8 |
https://gist.github.com/03c77114c5fb60c8fbf9dbd3749ca0e1 https://gist.github.com/0aa83779df6fafdacd9fbcc636549d11 https://gist.github.com/63a2cc54734f18b3b76a42bca4b74e2b https://gist.github.com/3080e82e124406621a8b30018825c632 https://gist.github.com/335a9b949e67d9027590219216279811 https://gist.github.com/3de93b2243cd1ba5fcad6e2c6dc49da3 https://gist.github.com/fdd5d49556505f1b0cc5aa89d83db483 https://gist.github.com/03ba5dd65a0cb9611173dd090c6a80b2 |
Summary
Once you understand how to display a Gist in a view, it is easy to style the Gist by wrapping it with HTML and CSS. You can control placement, width, height, and more easily.
I design software for enterprise-class systems and data centers. My background is 30+ years in storage (SCSI, FC, iSCSI, disk arrays, imaging) virtualization. 20+ years in identity, security, and forensics.
For the past 14+ years, I have been working in the cloud (AWS, Azure, Google, Alibaba, IBM, Oracle) designing hybrid and multi-cloud software solutions. I am an MVP/GDE with several.
Leave a Reply