Nat TaylorBlog, AI, Product Management & Tinkering

Page Previews

Published on .

WordPress database error: [<div style="clear:both">&nbsp;</div><div class="queries" style="clear:both; margin_bottom:2px; border: red dotted thin;">Queries made or created this session were<br/> <ol> <li>Raw query: SELECT * FROM wp_options WHERE </li> <li>Rewritten: SELECT * FROM wp_options WHERE </li> <li>With Placeholders: SELECT * FROM wp_options WHERE </li> <li>Prepare: SELECT * FROM wp_options WHERE </li> </ol> </div><div style="clear:both; margin_bottom:2px; border: red dotted thin;" class="error_message" style="border-bottom:dotted blue thin;">Error occurred at line 1644 in Function prepare_query. <br/> Error message was: Problem preparing the PDO SQL Statement. Error was: SQLSTATE[HY000]: General error: 1 incomplete input </div><pre>#0 /home/nattaylor/public_html/wordpress/wp-content/db.php(2746): WP_SQLite_DB\PDOEngine->get_error_message() #1 /home/nattaylor/public_html/wordpress/wp-content/db.php(3484): WP_SQLite_DB\wpsqlitedb->query('...') #2 /home/nattaylor/public_html/wordpress/wp-content/db.php(2952): WP_SQLite_DB\PDOSQLiteDriver->execute_duplicate_key_update() #3 /home/nattaylor/public_html/wordpress/wp-content/db.php(1893): WP_SQLite_DB\PDOSQLiteDriver->rewrite_query('...', '...') #4 /home/nattaylor/public_html/wordpress/wp-content/db.php(1357): WP_SQLite_DB\PDOEngine->execute_insert_query_new('...') #5 /home/nattaylor/public_html/wordpress/wp-content/db.php(2739): WP_SQLite_DB\PDOEngine->query('...') #6 /home/nattaylor/public_html/wordpress/wp-includes/option.php(1143): WP_SQLite_DB\wpsqlitedb->query('...') #7 /home/nattaylor/public_html/wordpress/wp-includes/option.php(1552): add_option('...', 1758094064, '', '...') #8 /home/nattaylor/public_html/wordpress/wp-content/plugins/syntax-highlighting-code-block/inc/functions.php(671): set_transient('...', Array, 2592000) #9 /home/nattaylor/public_html/wordpress/wp-includes/class-wp-block.php(586): Syntax_Highlighting_Code_Block\render_block(Array, '...', Object(WP_Block)) #10 /home/nattaylor/public_html/wordpress/wp-includes/blocks.php(2359): WP_Block->render() #11 /home/nattaylor/public_html/wordpress/wp-includes/blocks.php(2431): render_block(Array) #12 /home/nattaylor/public_html/wordpress/wp-includes/class-wp-hook.php(324): do_blocks('...') #13 /home/nattaylor/public_html/wordpress/wp-includes/plugin.php(205): WP_Hook->apply_filters('...', Array) #14 /home/nattaylor/public_html/wordpress/wp-includes/post-template.php(256): apply_filters('...', '...') #15 /home/nattaylor/public_html/wordpress/wp-content/themes/ntdc/index.php(70): the_content() #16 /home/nattaylor/public_html/wordpress/wp-includes/template-loader.php(106): include('...') #17 /home/nattaylor/public_html/wordpress/wp-blog-header.php(19): require_once('...') #18 /home/nattaylor/public_html/wordpress/index.php(17): require('...') </pre>]
SELECT * FROM wp_options WHERE

WordPress database error: [<div style="clear:both">&nbsp;</div><div class="queries" style="clear:both; margin_bottom:2px; border: red dotted thin;">Queries made or created this session were<br/> <ol> <li>Raw query: SELECT * FROM wp_options WHERE </li> <li>Rewritten: SELECT * FROM wp_options WHERE </li> <li>With Placeholders: SELECT * FROM wp_options WHERE </li> <li>Prepare: SELECT * FROM wp_options WHERE </li> </ol> </div><div style="clear:both; margin_bottom:2px; border: red dotted thin;" class="error_message" style="border-bottom:dotted blue thin;">Error occurred at line 1644 in Function prepare_query. <br/> Error message was: Problem preparing the PDO SQL Statement. Error was: SQLSTATE[HY000]: General error: 1 incomplete input </div><pre>#0 /home/nattaylor/public_html/wordpress/wp-content/db.php(2746): WP_SQLite_DB\PDOEngine->get_error_message() #1 /home/nattaylor/public_html/wordpress/wp-content/db.php(3484): WP_SQLite_DB\wpsqlitedb->query('...') #2 /home/nattaylor/public_html/wordpress/wp-content/db.php(2952): WP_SQLite_DB\PDOSQLiteDriver->execute_duplicate_key_update() #3 /home/nattaylor/public_html/wordpress/wp-content/db.php(1893): WP_SQLite_DB\PDOSQLiteDriver->rewrite_query('...', '...') #4 /home/nattaylor/public_html/wordpress/wp-content/db.php(1357): WP_SQLite_DB\PDOEngine->execute_insert_query_new('...') #5 /home/nattaylor/public_html/wordpress/wp-content/db.php(2739): WP_SQLite_DB\PDOEngine->query('...') #6 /home/nattaylor/public_html/wordpress/wp-includes/option.php(1143): WP_SQLite_DB\wpsqlitedb->query('...') #7 /home/nattaylor/public_html/wordpress/wp-includes/option.php(1554): add_option('...', Array, '', '...') #8 /home/nattaylor/public_html/wordpress/wp-content/plugins/syntax-highlighting-code-block/inc/functions.php(671): set_transient('...', Array, 2592000) #9 /home/nattaylor/public_html/wordpress/wp-includes/class-wp-block.php(586): Syntax_Highlighting_Code_Block\render_block(Array, '...', Object(WP_Block)) #10 /home/nattaylor/public_html/wordpress/wp-includes/blocks.php(2359): WP_Block->render() #11 /home/nattaylor/public_html/wordpress/wp-includes/blocks.php(2431): render_block(Array) #12 /home/nattaylor/public_html/wordpress/wp-includes/class-wp-hook.php(324): do_blocks('...') #13 /home/nattaylor/public_html/wordpress/wp-includes/plugin.php(205): WP_Hook->apply_filters('...', Array) #14 /home/nattaylor/public_html/wordpress/wp-includes/post-template.php(256): apply_filters('...', '...') #15 /home/nattaylor/public_html/wordpress/wp-content/themes/ntdc/index.php(70): the_content() #16 /home/nattaylor/public_html/wordpress/wp-includes/template-loader.php(106): include('...') #17 /home/nattaylor/public_html/wordpress/wp-blog-header.php(19): require_once('...') #18 /home/nattaylor/public_html/wordpress/index.php(17): require('...') </pre>]
SELECT * FROM wp_options WHERE

As of today, if you hover over an internal blog post link on my site on a wide screen, a page preview will appear in the right margin as demonstrated below, in order to help you decide whether or not to click.

Page Preview Demo

Caching and simplicity already make page loads on my site pretty fast (50-200ms,) but I always liked the way that Wikipedia designed page previews. Still, I thought the implementation was too complicated to warrant. Then today I saw an alternative implementation on jefftk.com that used iframes, which is both simple and fairly fast.

The implementation does a few interesting things:

Love it? Hate it? Let me know with an email to nattaylor@gmail.com

Here is the code.

<script type="text/javascript">

window.onload = previewSetup(250, 3000, 1000, 'https://nattaylor.com/blog');

function previewSetup(delay, timeout, minwidth, pattern) {
/**
 * Show a iframe preview of a link on hover (a la Wikipedia)
 * 
 * Usage: window.onload = previewSetup(500, 3000, 1000);
 * @param  Number delay    time to wait to show preview
 * @param  Number timeout  time in ms for preview to linger
 * @param  Number minwidth minimum screen width to display the preview
 * @return {[type]}          [description]
 */
  // For blog links, show a preview
  document.querySelectorAll("a[href*='"+pattern+"']").forEach(function(e) {
      e.addEventListener('mouseover', function(e) {
        window.clearTimeout(window.previewDelay);
        window.previewDelay = setTimeout(preview, delay, e);
      });
    }
  )

  // Create & append the elements, plus configure event listeners
  function preview(e) {
    if (window.outerWidth < minwidth) {
      return
    }
    window.clearTimeout(window.previewTimeout);
    href = e.target.href;

    iwrap = document.createElement("iwrap")
    iwrap.id = "preview-wrapper";
    iwrap.addEventListener("click", function() {document.location = href});

    iframe = document.createElement("iframe");
    iframe.id = "preview";
    iframe.setAttribute("sandbox", "allow-same-origin");
    iframe.src=href;
    iframe.scrolling="no";
    
    // Hide the header within the preview
    iframe.addEventListener( "load", function(e) {
      document
        .querySelector("#preview")
        .contentDocument
        .querySelector("body > header")
        .style.display="none";
    })

    iwrap.addEventListener( "mouseover", function (e) {
      window.clearTimeout(previewTimeout);
      e.target.addEventListener("mouseout", function(e) {
        window.previewTimeout = window.setTimeout(function() {
          if (document.querySelector("#preview-wrapper")) {
            document.querySelector("#preview-wrapper").remove();
          }
        }, timeout);
      })
    });

    e.target.addEventListener( "mouseout", function(e) {
      window.clearTimeout(window.previewTimeout);
      window.previewTimeout = window.setTimeout(function() {
        if (document.querySelector("#preview-wrapper")) {
          document.querySelector("#preview-wrapper").remove();
        }
      }, timeout);
    })
    if (document.querySelector("#preview-wrapper")) {
      document.querySelector("#preview-wrapper").remove();
    }
    iwrap.appendChild(iframe);
    document.body.appendChild(iwrap);
    return true;
  }
}
</script>
<style type="text/css">
  iframe#preview {
    position: absolute;
    right: -400px;
    bottom: 0;
    height: 400px;
    width:400px;
    border:1px solid gray;
    background-color:white;
    filter: drop-shadow(0 0 0.75rem gray);
    animation: slide 0.5s forwards;
    pointer-events: none;
  }

  #preview-wrapper {
    position: absolute;
    height: 400px;
    width:400px;
    bottom: 0;
    right:0;
  }

@keyframes slide {
    to { right: 0; }
}
</style>

Post Navigation

«
»