Author Archives: Chris
Protected: Whale Watching
Welcome to the Gutenberg Editor
Of Mountains & Printing Presses
What you are reading now is a text block, the most basic block of all. The text block has its own controls to be moved freely around the post…
The goal of this new editor is to make adding rich content to WordPress simple and enjoyable. This whole post is composed of pieces of content—somewhat similar to LEGO bricks—that you can move around and interact with. Move your cursor around and you’ll notice the different blocks light up with outlines and arrows. Press the arrows to reposition blocks quickly, without fearing about losing things in the process of copying and pasting.
… like this one, which is right aligned.
Headings are separate blocks as well, which helps with the outline and organization of your content.
A Picture is worth a Thousand Words
Handling images and media with the utmost care is a primary focus of the new editor. Hopefully, you’ll find aspects of adding captions or going full-width with your pictures much easier and robust than before.

Try selecting and removing or editing the caption, now you don’t have to be careful about selecting the image or other text by mistake and ruining the presentation.
The Inserter Tool
Imagine everything that WordPress can do is available to you quickly and in the same place on the interface. No need to figure out HTML tags, classes, or remember complicated shortcode syntax. That’s the spirit behind the inserter—the (+)
button you’ll see around the editor—which allows you to browse all available content blocks and add them into your post. Plugins and themes are able to register their own, opening up all sort of possibilities for rich editing and publishing.
Go give it a try, you may discover things WordPress can already add into your posts that you didn’t know about. Here’s a short list of what you can currently find there:
- Text & Headings
- Images & Videos
- Galleries
- Embeds, like YouTube, Tweets, or other WordPress posts.
- Layout blocks, like Buttons, Hero Images, Separators, etc.
- And Lists like this one of course 🙂
Visual Editing
A huge benefit of blocks is that you can edit them in place and manipulate your content directly. Instead of having fields for editing things like the source of a quote, or the text of a button, you can directly change the content. Try editing the following quote:
The editor will endeavour to create a new page and post building experience that makes writing rich posts effortless, and has “blocks” to make it easy what today might take shortcodes, custom HTML, or “mystery meat” embed discovery.
Matt Mullenweg, 2017
The information corresponding to the source of the quote is a separate text field, similar to captions under images, so the structure of the quote is protected even if you select, modify, or remove the source. It’s always easy to add it back.
Blocks can be anything you need. For instance, you may want to add a subdued quote as part of the composition of your text, or you may prefer to display a giant stylized one. All of these options are available in the inserter.
You can change the amount of columns in your galleries by dragging a slider in the block inspector in the sidebar.
Media Rich
If you combine the new wide and full-wide alignments with galleries, you can create a very media rich layout, very quickly:

Sure, the full-wide image can be pretty big. But sometimes the image is worth it.
The above is a gallery with just two images. It’s an easier way to create visually appealing layouts, without having to deal with floats. You can also easily convert the gallery back to individual images again, by using the block switcher.
Any block can opt into these alignments. The embed block has them also, and is responsive out of the box:
You can build any block you like, static or dynamic, decorative or plain. Here’s a pullquote block:
Code is Poetry
The WordPress community
If you want to learn more about how to build additional blocks, or if you are interested in helping with the project, head over to the GitHub repository.
Thanks for testing Gutenberg!
3d scanning notes
laser
time
light
detector
time-of-flight
ToF
infrared laser beam
sweep
pixel
round-trip flight time of the photons
count individual photons
Optics Express
CT scan
Evan Doney
Journal of Visualized Experiments
xray computed tomography mode
xray CT datasets
CT = computed tomography
point cloud (.fls) to STL
NetFabb studio
slic3r
Photon 3D scanner
affordable 3d scanner
point cloud -> mesh
Next Engine, Leica, and FARO Focus 3D.
Rapidform XOR
Agisoft Photoscan model
retopology in 3ds max
Maps extraction in Zbrush
Faro Focus 3D
Artec Eva
Creaforms Maxscan
Faro Focus 3D
Agisoft Photoscan
Cubify Capture
My3DScanner
Models, Mobile 3d Laser Scanner
skin a point cloud
SKANECT Kinect
watertight models
software to add detail
software to calculate watertight gaps-closed version
applying textures to 3D model
Artec 3D Scanners
Artec Studio + Kinect
David Scanner
photogrammetry method c
photometric stereo
meshing point clouds
3ds max
rapidform 3d scanning
rapidform XOR
point cloud file converter
3d laser mapping
A new spin on rotators
This time, I am trying to keep it very general purpose and not assume any GUI in the spinner object itself. http://jsbin.com/epefiw/4/edit?live
Prettier PHP Debug Messages continued
Continuation to Prettier PHP Debug Messages. This version is self-styling and also accepts a label parameter.
<?php if (!function_exists('pp')) { //Pretty Print function pp($obj,$label = '') { $data = json_encode(print_r($obj,true)); ?> <style type="text/css"> #bsdLogger { position: absolute; top: 0px; right: 0px; border-left: 4px solid #bbb; padding: 6px; background: white; color: #444; z-index: 999; font-size: 1.25em; width: 400px; height: 800px; overflow: scroll; } </style> <script type="text/javascript"> var doStuff = function(){ var obj = <?php echo $data; ?>; var logger = document.getElementById('bsdLogger'); if (!logger) { logger = document.createElement('div'); logger.id = 'bsdLogger'; document.body.appendChild(logger); } ////console.log(obj); var pre = document.createElement('pre'); var h2 = document.createElement('h2'); pre.innerHTML = obj; h2.innerHTML = '<?php echo addslashes($label); ?>'; logger.appendChild(h2); logger.appendChild(pre); }; window.addEventListener ("DOMContentLoaded", doStuff, false); </script> <?php } } ?> |
Amber Smalltalk on Shared Hosting Provider
I’m having a lot of fun learning Amber Smalltalk. It’s great having an IDE right inside the browser. My code changes in the IDE save and commit back to the webserver via WebDAV or NodeJS.
I also own a few shared hosting accounts which don’t offer WebDAV or NodeJS. They also forbid HTTP PUT. But I’d still like to be able to develop Amber projects on those sites too.
So I decided to modify Amber’s Browser>>commitPackage method to upload files as FormData via regular HTTP POST.
FormData is a newer XMLHttpRequest interface, so your browser compatibility may be an issue.
I made a few modifications to the Browser class (under the IDE package).
First, I created a helper method which uses the FormData object.
commitPackageAsFormDataToPath: path withFileData: fileData | formData apiKey| apiKey := self class commitAPIKey. < formData = new FormData(); formData.append('path',path); formData.append('fileData',fileData); formData.append('commitAPIKey',apiKey); >. selectedPackage ifNotNil: [ jQuery ajax: #{ #url -> self class commitScriptURL. #type -> 'POST'. #data -> formData. #contentType -> false. #processData -> false. #success -> [ :data | console log: data ] }. ] |
Next, commitPackageAsFormData will call the helper method defined above.
commitPackageAsFormData | d path fileData | self commitPackageAsFormDataToPath: (self class commitPathJs, '/', selectedPackage, '.js') withFileData: (Exporter new exportPackage: selectedPackage). self commitPackageAsFormDataToPath: (self class commitPathJs, '/', selectedPackage, '.deploy.js') withFileData: (StrippedExporter new exportPackage: selectedPackage). self commitPackageAsFormDataToPath: (self class commitPathSt, '/', selectedPackage, '.st') withFileData: (ChunkExporter new exportPackage: selectedPackage). |
Now I override the standard commitPackage method (Since this is a destructive edit, you may want to first rename it to something else)
commitPackage
self commitPackageAsFormData |
Almost done… I still need to define a few class-side methods and then make the server-side commit script.
commitScriptURL
^'/amber/commit.php' |
For security, I will prompt for a key to be sent to the server-side commit script
commitAPIKey | key | commitAPIKey ifNil: [ <key = prompt('Enter the API Key');>. commitAPIKey := key. ]. ^ commitAPIKey |
I need to create the class-side instance variable to store the key I prompted for
Browser class instanceVariableNames: 'commitAPIKey' |
Finally, I need to create the server-side commit.php script
<?php $all = Array(); $all = array_merge($all,$_POST); $all = array_merge($all,$_GET); $correct_apikey = "Sometimes I Doubt Your Commitment to Sparkle Motion"; //make this your own $root = dirname(__FILE__); $path = $all['path']; $data = $all['fileData']; $data = stripslashes($data); $fullpath = $root . '/' . $path; $allowed = preg_match('/^js/',$path) || preg_match('/^st/',$path); if (!$allowed) { die('invalid path ' . $path); } if ($all['commitAPIKey'] != $correct_apikey) { die('invalid API key, not allowed to commit'); } if (empty($data)) { die('empty data'); } $fp = fopen($fullpath, "w"); $written = fwrite($fp, $data); fclose($fp); echo "OK, " . $written . " bytes written"; ?> |
And there we go. Hacking Amber on a Shared Hosting Provider using HTTP POST and FormData.
EDIT: I updated the code relating to commitAPIKey
WP Rotator
A new WordPress plugin I’ve been working on with the help of Bill Erickson. Rotates through featured images of a custom query whose query args are configurable by the administrator. Animates by sliding or cross-fading. Adjustable animation speeds. Hoping to share it soon in the WordPress Plugin Directory.
-
Taj Mahal 3
Dusk View. Or is it dawn? Continue reading
UPDATE: Here it is in the Plugin Directory
Code Snippets
Not sure if something like this already exists in WP
function get_post_ids_satisfying_taxonomy_terms($taxterms) { $first_pass = true; foreach($taxterms as $taxonomy => $term_slug) { $the_term = get_term_by('slug',$term_slug,$taxonomy); //pp($the_term); $object_ids = get_objects_in_term($the_term->term_id,Array($taxonomy)); if ($first_pass) { $results = $object_ids; $first_pass = false; } else { //accumulate the post ids which satisfy all taxonomy => term pairs (AND, not OR) $results = array_intersect($results,$object_ids); } } $results = empty($results) ? Array(-1) : $results; //the post__in query_var gets ignored on an empty array, so return an invalid post id in an array return $results; } |
This snippet will change all categories above 3 to be sub-categories of 3
require_once(ABSPATH . 'wp-admin/includes/taxonomy.php'); pp(get_categories('hide_empty=0')); foreach (get_categories('hide_empty=0') as $c) { if ($c->term_id > 3) { $result = wp_insert_category( Array( 'cat_ID' => $c->term_id, 'category_parent' => 3, 'cat_name' => $c->name ),true); pp($result); } } |
WordPress plugin: Query Tester
@fienen came up with a good idea for a WordPress plugin today. He wants to be able to type in a sample parameter string for query_posts and see which posts will result, given that string. I decided that’s something I want too so I don’t have to hack up a template on the fly if I don’t want to.
Here’s a quick and dirty plugin which should do the trick. It installs itself into Dashboard > Settings > Query Tester
query-tester