CINXE.COM
Steve Baskauf's blog: April 2023
<!DOCTYPE html> <html class='v2' dir='ltr' lang='en'> <head> <link href='https://www.blogger.com/static/v1/widgets/3566091532-css_bundle_v2.css' rel='stylesheet' type='text/css'/> <meta content='width=1100' name='viewport'/> <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/> <meta content='blogger' name='generator'/> <link href='http://baskauf.blogspot.com/favicon.ico' rel='icon' type='image/x-icon'/> <link href='http://baskauf.blogspot.com/2023/04/' rel='canonical'/> <link rel="alternate" type="application/atom+xml" title="Steve Baskauf's blog - Atom" href="http://baskauf.blogspot.com/feeds/posts/default" /> <link rel="alternate" type="application/rss+xml" title="Steve Baskauf's blog - RSS" href="http://baskauf.blogspot.com/feeds/posts/default?alt=rss" /> <link rel="service.post" type="application/atom+xml" title="Steve Baskauf's blog - Atom" href="https://www.blogger.com/feeds/5299754536670281996/posts/default" /> <!--Can't find substitution for tag [blog.ieCssRetrofitLinks]--> <meta content='http://baskauf.blogspot.com/2023/04/' property='og:url'/> <meta content='Steve Baskauf's blog' property='og:title'/> <meta content='' property='og:description'/> <title>Steve Baskauf's blog: April 2023</title> <style id='page-skin-1' type='text/css'><!-- /* ----------------------------------------------- Blogger Template Style Name: Simple Designer: Blogger URL: www.blogger.com ----------------------------------------------- */ /* Content ----------------------------------------------- */ body { font: normal normal 12px 'Trebuchet MS', Trebuchet, Verdana, sans-serif; color: #666666; background: #ffffff none repeat scroll top left; padding: 0 0 0 0; } html body .region-inner { min-width: 0; max-width: 100%; width: auto; } h2 { font-size: 22px; } a:link { text-decoration:none; color: #8832ff; } a:visited { text-decoration:none; color: #bb2188; } a:hover { text-decoration:underline; color: #33aaff; } .body-fauxcolumn-outer .fauxcolumn-inner { background: transparent none repeat scroll top left; _background-image: none; } .body-fauxcolumn-outer .cap-top { position: absolute; z-index: 1; height: 400px; width: 100%; } .body-fauxcolumn-outer .cap-top .cap-left { width: 100%; background: transparent none repeat-x scroll top left; _background-image: none; } .content-outer { -moz-box-shadow: 0 0 0 rgba(0, 0, 0, .15); -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, .15); -goog-ms-box-shadow: 0 0 0 #333333; box-shadow: 0 0 0 rgba(0, 0, 0, .15); margin-bottom: 1px; } .content-inner { padding: 10px 40px; } .content-inner { background-color: #ffffff; } /* Header ----------------------------------------------- */ .header-outer { background: transparent none repeat-x scroll 0 -400px; _background-image: none; } .Header h1 { font: normal normal 40px 'Trebuchet MS',Trebuchet,Verdana,sans-serif; color: #000000; text-shadow: 0 0 0 rgba(0, 0, 0, .2); } .Header h1 a { color: #000000; } .Header .description { font-size: 18px; color: #000000; } .header-inner .Header .titlewrapper { padding: 22px 0; } .header-inner .Header .descriptionwrapper { padding: 0 0; } /* Tabs ----------------------------------------------- */ .tabs-inner .section:first-child { border-top: 0 solid #dddddd; } .tabs-inner .section:first-child ul { margin-top: -1px; border-top: 1px solid #dddddd; border-left: 1px solid #dddddd; border-right: 1px solid #dddddd; } .tabs-inner .widget ul { background: transparent none repeat-x scroll 0 -800px; _background-image: none; border-bottom: 1px solid #dddddd; margin-top: 0; margin-left: -30px; margin-right: -30px; } .tabs-inner .widget li a { display: inline-block; padding: .6em 1em; font: normal normal 12px 'Trebuchet MS', Trebuchet, Verdana, sans-serif; color: #000000; border-left: 1px solid #ffffff; border-right: 1px solid #dddddd; } .tabs-inner .widget li:first-child a { border-left: none; } .tabs-inner .widget li.selected a, .tabs-inner .widget li a:hover { color: #000000; background-color: #eeeeee; text-decoration: none; } /* Columns ----------------------------------------------- */ .main-outer { border-top: 0 solid transparent; } .fauxcolumn-left-outer .fauxcolumn-inner { border-right: 1px solid transparent; } .fauxcolumn-right-outer .fauxcolumn-inner { border-left: 1px solid transparent; } /* Headings ----------------------------------------------- */ div.widget > h2, div.widget h2.title { margin: 0 0 1em 0; font: normal bold 11px 'Trebuchet MS',Trebuchet,Verdana,sans-serif; color: #000000; } /* Widgets ----------------------------------------------- */ .widget .zippy { color: #999999; text-shadow: 2px 2px 1px rgba(0, 0, 0, .1); } .widget .popular-posts ul { list-style: none; } /* Posts ----------------------------------------------- */ h2.date-header { font: normal bold 11px Arial, Tahoma, Helvetica, FreeSans, sans-serif; } .date-header span { background-color: #bbbbbb; color: #ffffff; padding: 0.4em; letter-spacing: 3px; margin: inherit; } .main-inner { padding-top: 35px; padding-bottom: 65px; } .main-inner .column-center-inner { padding: 0 0; } .main-inner .column-center-inner .section { margin: 0 1em; } .post { margin: 0 0 45px 0; } h3.post-title, .comments h4 { font: normal normal 22px 'Trebuchet MS',Trebuchet,Verdana,sans-serif; margin: .75em 0 0; } .post-body { font-size: 110%; line-height: 1.4; position: relative; } .post-body img, .post-body .tr-caption-container, .Profile img, .Image img, .BlogList .item-thumbnail img { padding: 2px; background: #ffffff; border: 1px solid #eeeeee; -moz-box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); -webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); } .post-body img, .post-body .tr-caption-container { padding: 5px; } .post-body .tr-caption-container { color: #666666; } .post-body .tr-caption-container img { padding: 0; background: transparent; border: none; -moz-box-shadow: 0 0 0 rgba(0, 0, 0, .1); -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, .1); box-shadow: 0 0 0 rgba(0, 0, 0, .1); } .post-header { margin: 0 0 1.5em; line-height: 1.6; font-size: 90%; } .post-footer { margin: 20px -2px 0; padding: 5px 10px; color: #666666; background-color: #eeeeee; border-bottom: 1px solid #eeeeee; line-height: 1.6; font-size: 90%; } #comments .comment-author { padding-top: 1.5em; border-top: 1px solid transparent; background-position: 0 1.5em; } #comments .comment-author:first-child { padding-top: 0; border-top: none; } .avatar-image-container { margin: .2em 0 0; } #comments .avatar-image-container img { border: 1px solid #eeeeee; } /* Comments ----------------------------------------------- */ .comments .comments-content .icon.blog-author { background-repeat: no-repeat; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9sLFwMeCjjhcOMAAAD+SURBVDjLtZSvTgNBEIe/WRRnm3U8RC1neQdsm1zSBIU9VVF1FkUguQQsD9ITmD7ECZIJSE4OZo9stoVjC/zc7ky+zH9hXwVwDpTAWWLrgS3QAe8AZgaAJI5zYAmc8r0G4AHYHQKVwII8PZrZFsBFkeRCABYiMh9BRUhnSkPTNCtVXYXURi1FpBDgArj8QU1eVXUzfnjv7yP7kwu1mYrkWlU33vs1QNu2qU8pwN0UpKoqokjWwCztrMuBhEhmh8bD5UDqur75asbcX0BGUB9/HAMB+r32hznJgXy2v0sGLBcyAJ1EK3LFcbo1s91JeLwAbwGYu7TP/3ZGfnXYPgAVNngtqatUNgAAAABJRU5ErkJggg==); } .comments .comments-content .loadmore a { border-top: 1px solid #999999; border-bottom: 1px solid #999999; } .comments .comment-thread.inline-thread { background-color: #eeeeee; } .comments .continue { border-top: 2px solid #999999; } /* Accents ---------------------------------------------- */ .section-columns td.columns-cell { border-left: 1px solid transparent; } .blog-pager { background: transparent url(//www.blogblog.com/1kt/simple/paging_dot.png) repeat-x scroll top center; } .blog-pager-older-link, .home-link, .blog-pager-newer-link { background-color: #ffffff; padding: 5px; } .footer-outer { border-top: 1px dashed #bbbbbb; } /* Mobile ----------------------------------------------- */ body.mobile { background-size: auto; } .mobile .body-fauxcolumn-outer { background: transparent none repeat scroll top left; } .mobile .body-fauxcolumn-outer .cap-top { background-size: 100% auto; } .mobile .content-outer { -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, .15); box-shadow: 0 0 3px rgba(0, 0, 0, .15); } .mobile .tabs-inner .widget ul { margin-left: 0; margin-right: 0; } .mobile .post { margin: 0; } .mobile .main-inner .column-center-inner .section { margin: 0; } .mobile .date-header span { padding: 0.1em 10px; margin: 0 -10px; } .mobile h3.post-title { margin: 0; } .mobile .blog-pager { background: transparent none no-repeat scroll top center; } .mobile .footer-outer { border-top: none; } .mobile .main-inner, .mobile .footer-inner { background-color: #ffffff; } .mobile-index-contents { color: #666666; } .mobile-link-button { background-color: #8832ff; } .mobile-link-button a:link, .mobile-link-button a:visited { color: #ffffff; } .mobile .tabs-inner .section:first-child { border-top: none; } .mobile .tabs-inner .PageList .widget-content { background-color: #eeeeee; color: #000000; border-top: 1px solid #dddddd; border-bottom: 1px solid #dddddd; } .mobile .tabs-inner .PageList .widget-content .pagelist-arrow { border-left: 1px solid #dddddd; } --></style> <style id='template-skin-1' type='text/css'><!-- body { min-width: 960px; } .content-outer, .content-fauxcolumn-outer, .region-inner { min-width: 960px; max-width: 960px; _width: 960px; } .main-inner .columns { padding-left: 0px; padding-right: 190px; } .main-inner .fauxcolumn-center-outer { left: 0px; right: 190px; /* IE6 does not respect left and right together */ _width: expression(this.parentNode.offsetWidth - parseInt("0px") - parseInt("190px") + 'px'); } .main-inner .fauxcolumn-left-outer { width: 0px; } .main-inner .fauxcolumn-right-outer { width: 190px; } .main-inner .column-left-outer { width: 0px; right: 100%; margin-left: -0px; } .main-inner .column-right-outer { width: 190px; margin-right: -190px; } #layout { min-width: 0; } #layout .content-outer { min-width: 0; width: 800px; } #layout .region-inner { min-width: 0; width: auto; } body#layout div.add_widget { padding: 8px; } body#layout div.add_widget a { margin-left: 32px; } --></style> <link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=5299754536670281996&zx=d22989f0-9133-4003-89d9-fe7c5d7e0799' media='none' onload='if(media!='all')media='all'' rel='stylesheet'/><noscript><link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=5299754536670281996&zx=d22989f0-9133-4003-89d9-fe7c5d7e0799' rel='stylesheet'/></noscript> <meta name='google-adsense-platform-account' content='ca-host-pub-1556223355139109'/> <meta name='google-adsense-platform-domain' content='blogspot.com'/> </head> <body class='loading variant-simplysimple'> <div class='navbar section' id='navbar' name='Navbar'><div class='widget Navbar' data-version='1' id='Navbar1'><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/platform.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar/5299754536670281996?origin\x3dhttp://baskauf.blogspot.com', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe" }); } }); </script><script type="text/javascript"> (function() { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = '//pagead2.googlesyndication.com/pagead/js/google_top_exp.js'; var head = document.getElementsByTagName('head')[0]; if (head) { head.appendChild(script); }})(); </script> </div></div> <div class='body-fauxcolumns'> <div class='fauxcolumn-outer body-fauxcolumn-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <div class='content'> <div class='content-fauxcolumns'> <div class='fauxcolumn-outer content-fauxcolumn-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <div class='content-outer'> <div class='content-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left content-fauxborder-left'> <div class='fauxborder-right content-fauxborder-right'></div> <div class='content-inner'> <header> <div class='header-outer'> <div class='header-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left header-fauxborder-left'> <div class='fauxborder-right header-fauxborder-right'></div> <div class='region-inner header-inner'> <div class='header section' id='header' name='Header'><div class='widget Header' data-version='1' id='Header1'> <div id='header-inner'> <div class='titlewrapper'> <h1 class='title'> <a href='http://baskauf.blogspot.com/'> Steve Baskauf's blog </a> </h1> </div> <div class='descriptionwrapper'> <p class='description'><span> </span></p> </div> </div> </div></div> </div> </div> <div class='header-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </header> <div class='tabs-outer'> <div class='tabs-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left tabs-fauxborder-left'> <div class='fauxborder-right tabs-fauxborder-right'></div> <div class='region-inner tabs-inner'> <div class='tabs no-items section' id='crosscol' name='Cross-Column'></div> <div class='tabs no-items section' id='crosscol-overflow' name='Cross-Column 2'></div> </div> </div> <div class='tabs-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='main-outer'> <div class='main-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left main-fauxborder-left'> <div class='fauxborder-right main-fauxborder-right'></div> <div class='region-inner main-inner'> <div class='columns fauxcolumns'> <div class='fauxcolumn-outer fauxcolumn-center-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='fauxcolumn-outer fauxcolumn-left-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='fauxcolumn-outer fauxcolumn-right-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <!-- corrects IE6 width calculation --> <div class='columns-inner'> <div class='column-center-outer'> <div class='column-center-inner'> <div class='main section' id='main' name='Main'><div class='widget Blog' data-version='1' id='Blog1'> <div class='blog-posts hfeed'> <div class="date-outer"> <h2 class='date-header'><span>Wednesday, April 12, 2023</span></h2> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI7S3dkvhn2dcO8D53dzVT67AXBSppkV9Njmlsr0beXRjz1WWpWJqNSWaO34aYErSaMCI5g7Ip2FM6Gsj6zQhvpZvG7meMfJ0kp5D1VJOHSNp98UrQxqcvP98aoSI-ke60uAhQ8VKgNgxEzo2rr6ZDeeQaJYKlkyhdlYPnaHe2A8UvpekmM0et75Qr/w640-h510/madonna_child_diagram.png' itemprop='image_url'/> <meta content='5299754536670281996' itemprop='blogId'/> <meta content='4857171635771705909' itemprop='postId'/> <a name='4857171635771705909'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='http://baskauf.blogspot.com/2023/04/structured-data-in-commons-and-wikibase.html'>Structured Data in Commons and wikibase software tools</a> </h3> <div class='post-header'> <div class='post-header-line-1'></div> </div> <div class='post-body entry-content' id='post-body-4857171635771705909' itemprop='description articleBody'> <p></p><div style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI7S3dkvhn2dcO8D53dzVT67AXBSppkV9Njmlsr0beXRjz1WWpWJqNSWaO34aYErSaMCI5g7Ip2FM6Gsj6zQhvpZvG7meMfJ0kp5D1VJOHSNp98UrQxqcvP98aoSI-ke60uAhQ8VKgNgxEzo2rr6ZDeeQaJYKlkyhdlYPnaHe2A8UvpekmM0et75Qr/s1158/madonna_child_diagram.png"><img alt="VanderBot workflow to Commons" border="0" data-original-height="923" data-original-width="1158" height="510" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI7S3dkvhn2dcO8D53dzVT67AXBSppkV9Njmlsr0beXRjz1WWpWJqNSWaO34aYErSaMCI5g7Ip2FM6Gsj6zQhvpZvG7meMfJ0kp5D1VJOHSNp98UrQxqcvP98aoSI-ke60uAhQ8VKgNgxEzo2rr6ZDeeQaJYKlkyhdlYPnaHe2A8UvpekmM0et75Qr/w640-h510/madonna_child_diagram.png" title="VanderBot workflow to Commons" width="640" /></a></div> <br /><p></p><p>In my <a href="https://baskauf.blogspot.com/2022/09/" target="_blank">last blog post</a>, I described a tool (<a href="https://github.com/HeardLibrary/linked-data/blob/master/commonsbot/README.md" target="_blank">CommonsTool</a>) that I created for uploading art images to Wikimedia Commons. One of the features of that Python script was to create <a href="https://commons.wikimedia.org/wiki/Commons:Structured_data" target="_blank">Structured Data in Commons</a> (SDoC) statements about the artwork that was being uploaded, such as "depicts" (P180) and "main subject" (P921) and "digital representation of" (P6243), necessary <a href="https://commons.wikimedia.org/wiki/Commons:Structured_data/Modeling/Visual_artworks" target="_blank">to "magically" populate the Commons page with extensive metadata about the artwork from Wikidata</a>. The script also added "created" (P170) and "inception" (P571) statements, which are important for providing the required attribution when the work is under copyright.</p><h3 style="text-align: left;">Structured Data on Commons "depicts" statements<br /></h3><p>These properties serve important roles, but one of the key purposes of SDoC is to make it possible for potential users of the media item to find it by providing richer metadata about what is depicted in the media. SDoC depict statements go into the data that is indexed by the Commons search engine, which otherwise is primarily dependent on words present in the filename. My CommonsTool script does write one "depicts" statement (that the image depicts the artwork itself) and that's important for the semantics of understanding what the media item represents. However, from the standpoint of searching, that single depicts statement doesn't add much to improve discovery since the artwork title in Wikidata is probably similar to the filename of the media item -- neither of which necessarily describe what is depicted IN the artwork. </p><p>Of course, one can add depicts statements manually, and there are also some tools that can be used to help with the process. But if you aspire to add multiple depicts statements to hundreds or thousands of media items, this could be very tedious and time consuming. If we are clever, we can take advantage of the fact that Structured Data in Commons is actually just another instance of a wikibase. So generally any tools that can make it easier to work with a wikibase can also make it easier to work with Wikimedia Commons</p><p>In February, I gave a <a href="https://drive.google.com/file/d/1VH47ej63-sEYNCD8DL25SeerW8Y9f7di/view" target="_blank">presentation</a> about using <a href="http://vanderbi.lt/vanderbot" target="_blank">VanderBot</a> (a tool that I wrote to write data to Wikidata) to write to any wikibase. As part of that presentation, I put together <a href="https://heardlibrary.github.io/digital-scholarship/lod/wikibase/sdoc/" target="_blank">some information about how to use VanderBot to write statements to SDoC using the Commons API</a>, and <a href="https://heardlibrary.github.io/digital-scholarship/lod/wikibase/sdoc/#querying" target="_blank">how to use the Wikimedia Commons Query Service (WCQS) to acquire data programatically via Python</a>. In this blog post, I will highlight some of the key points about interacting with Commons as a wikibase and link out to the details required to actually do the interacting.</p><h3 style="text-align: left;">Media file identifiers (M IDs)</h3><p>Wikimedia Commons media files are assigned a unique identifier that is analogous to the Q IDs used with Wikidata items. They are known as "M IDs" and they are required to interact with the Commons API or the Wikimedia Commons Query Service programmatically as I will describe below. </p><p>It is not particularly straightforward to find the M ID for a media file. The easiest way is probably to find the <span style="font-family: courier;">Concept URI</span> link in the left menu of a Commons page, right-click on the link, and then paste it somewhere. The M ID is the last part of that link. Here's an example: <a href="https://commons.wikimedia.org/entity/M113161207">https://commons.wikimedia.org/entity/M113161207</a> . If the M ID for a media file is known, you can load its page using a URL of this form. </p><p>If you are automating the upload process as I described in my last post, CommonsTool records the M ID when it uploads the file. I also have a <a href="https://github.com/HeardLibrary/linked-data/blob/3d77805318cc0b8f8533c00d582dd0f81af9c4ca/commonsbot/commonstool.py#L659-L686" target="_blank">Python function</a> that can be used to get the M ID from the Commons API using the media filename. </p><h3 style="text-align: left;">Properties and values in Structured Data on Commons come from Wikidata<br /></h3><p>Structured Data on Commons does not maintain its own system of properties. It exclusively uses properties from Wikidata, identified by P IDs. Similarly, the values of SDoC statements are nearly always Wikidata items identified by Q IDs (with dates being an exception). So one could generally represent a SDoC statement (subject property value) like this:</p><p>MID PID QID. </p><h3 style="text-align: left;">Captions</h3><p>Captions are a feature of Commons that allows multilingual captions to be applied to media items. They show up under the "File information" tab.<br /></p><p></p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga4dqNE610Fk5w-ZF_fE5DdcEGMQq7JTVJdpwvX_Q5sLNGPa0G1b8C1AucwfvoDXuiPB6U8VS2TPixg47UUCxZZ4FYgCOyfX-RtHIvHRFDOsTic1ZpdlvOerlye-tqHNdjCKRlfJDJjJMKEKJz20qhvdFnqNketf94t3nY3Lpzga9cjgyTe0txMU0Y/s1056/caption_screenshot.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="523" data-original-width="1056" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga4dqNE610Fk5w-ZF_fE5DdcEGMQq7JTVJdpwvX_Q5sLNGPa0G1b8C1AucwfvoDXuiPB6U8VS2TPixg47UUCxZZ4FYgCOyfX-RtHIvHRFDOsTic1ZpdlvOerlye-tqHNdjCKRlfJDJjJMKEKJz20qhvdFnqNketf94t3nY3Lpzga9cjgyTe0txMU0Y/w640-h316/caption_screenshot.png" width="640" /></a></p> Although captions can be added or edited using the graphical interface, under the hood the captions are the multilingual labels for the media items in the Commons wikibase. So they can be added or edited as wikibase labels via the Commons API using any tool that can edit wikibases.<p></p><p></p><h2 style="text-align: left;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlCYqPm6Lt6ByXQnpKBs_kbssIeV5s4bE8H8yilyjZCyI-pbXFi-Rh3uBcjFG59BJCfDpN62LMrwUvvW8Y7Gc5kUgqYLl4waIDqmuJrQZS3dAuSDBRU6LTf2kNsjOoJCN2TdtHmc2nLbgkiM1QeIUIeP_Oq8Iicjpd4mhKDBLjPEvyl57ltWkG6Xv5/s830/components_diagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="522" data-original-width="830" height="402" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlCYqPm6Lt6ByXQnpKBs_kbssIeV5s4bE8H8yilyjZCyI-pbXFi-Rh3uBcjFG59BJCfDpN62LMrwUvvW8Y7Gc5kUgqYLl4waIDqmuJrQZS3dAuSDBRU6LTf2kNsjOoJCN2TdtHmc2nLbgkiM1QeIUIeP_Oq8Iicjpd4mhKDBLjPEvyl57ltWkG6Xv5/w640-h402/components_diagram.png" width="640" /></a></div></h2><h2 style="text-align: left;">Writing statements to the Commons API with VanderBot<br /></h2><p></p><p>VanderBot uses tabular data (spreadsheets) as a data source when it creates statements in a wikibase. One key piece of required information is the Q ID of the subject item that the statements are about and that is generally the first column in the table. When writing to Commons, the subject M ID is substituted for a Q ID in the table. </p><p>Statement values for a particular property are placed in one column in the table. Since all of the values in a column are assumed to be for the same property, the P ID doesn't need to be specified as data in the row. VanderBot just needs to know what P ID is associated with that column and that mapping of column with property is made separately. So at a minimum, to write a single kind of statement to Commons (like <span style="font-family: courier;">Depicts</span>), VanderBot needs only two columns of data (one for the M ID and one for the Q ID of the value of the property). </p><p> Here is <a href="https://github.com/HeardLibrary/linked-data/blob/master/commonsbot/depicts/depicts.csv" target="_blank">an example of a table with depicts data</a> to be uploaded to Commons by VanderBot:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio5kICrZgnPT0uajA7mhB3EhhnWpNeu7rSQGYoI6Z21OhWbi_84Fqxg8FK7RpkWURCwbHGdaHIAEkAm2kSy1IGd_imqEfOvUyBkUPYGg_1pUe5mhGCkE0kC9mQmURcom-Uq3Xhy2X53pJOl31_ty4NmRZuM89Flv7xq46TTUMfS0-E7B217TwVvPMn/s1096/csv.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="163" data-original-width="1096" height="96" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio5kICrZgnPT0uajA7mhB3EhhnWpNeu7rSQGYoI6Z21OhWbi_84Fqxg8FK7RpkWURCwbHGdaHIAEkAm2kSy1IGd_imqEfOvUyBkUPYGg_1pUe5mhGCkE0kC9mQmURcom-Uq3Xhy2X53pJOl31_ty4NmRZuM89Flv7xq46TTUMfS0-E7B217TwVvPMn/w640-h96/csv.png" width="640" /></a></div><p>The <span style="font-family: courier;">qid</span> column contains the subject M ID identifiers (for <a href="https://commons.wikimedia.org/wiki/File:Madonna_and_Child_with_St._Elizabeth_and_infant_John_the_Baptist_-_Vanderbilt_Fine_Arts_Gallery_-_1979.0321P_copy.tif" target="_blank">this media file</a>). The <span style="font-family: courier;">depicts</span> column contains the Q IDs of the values (the things that are depicted in the media item). The other three columns serve the following purposes:</p><p>- <span style="font-family: courier;">depicts_label</span> is ignored by the script. It's just a place to put the label of the otherwise opaque Q ID for the depicted item so that a human looking at the spreadsheet has some idea about what's being depicted.</p><p>- <span style="font-family: courier;">label_en</span> is the language-tagged caption/wikibase label. VanderBot has an option to either overwrite the existing label in the wikibase with the value in the table or ignore the label column and leave the label in Wikibase the same. In this example, we are not concerning ourselves with editing the captions, so we will use the "ignore" option. But if one wanted to add or update captions, VanderBot could be used for that.</p><p>- <span style="font-family: courier;">depicts_uuid</span> stores the unique statement identifier after the statement is created. It is empty for statements that have not yet been uploaded.</p><p>I mentioned before that the connection between the property and the column that contains its values was made separately. This mapping is done in <a href="https://github.com/HeardLibrary/linked-data/blob/master/commonsbot/depicts/config.yaml" target="_blank">a YAML file that</a> describes the columns in the table:</p><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihMOgpmLINcZbUQuMdXOKEQQ9AOYovg1ea8hUYJTB5kSatb4Mhd2FruqwYHUom_inb45tPSVJU-x2SqtZ3Z8lWfLZuXM80b5IAo8l6IU1DcHozfhhO_D7tQWJ4fPHUFHBIYK6mRZJQ5P1pAeWwByxNy0nU-ItVQP_26FU1W4peoiY18lZDGqlC0KDl/s381/config_yaml.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="381" data-original-width="346" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihMOgpmLINcZbUQuMdXOKEQQ9AOYovg1ea8hUYJTB5kSatb4Mhd2FruqwYHUom_inb45tPSVJU-x2SqtZ3Z8lWfLZuXM80b5IAo8l6IU1DcHozfhhO_D7tQWJ4fPHUFHBIYK6mRZJQ5P1pAeWwByxNy0nU-ItVQP_26FU1W4peoiY18lZDGqlC0KDl/s320/config_yaml.png" width="291" /></a></div><p>The details of this file structure are given <a href="https://github.com/HeardLibrary/linked-data/blob/master/vanderbot/convert-config.md" target="_blank">elsewhere</a>, but a few key details are obvious. The <span style="font-family: courier;">depicts_label</span> column is designated as to be ignored. In the properties list, the header for a column is given as value of the <span style="font-family: courier;">variable</span> key, with a value of <span style="font-family: courier;">depicts</span> in this example. That column has <span style="font-family: courier;">item</span> as its value type and <span style="font-family: courier;">P180</span> as its property. <br /></p><p>As a part of the VanderBot workflow, this mapping file is converted into a JSON metadata description file and that file along with the CSV are all that are needed by VanderBot to create the SDoC <span style="font-family: courier;">depicts</span> statements.<br /></p><p>If you have used VanderBot to create new items in Wikidata, uploading to Commons is more restrictive than what you are used to. When writing to Wikidata, if the Q ID column for a row in a CSV is empty, Vanderbot will create a new item and if it's not, it edits an existing one. Creating new items directly via the API is not possible in Commons, because new items in the Commons wikibase are only created as a result of media uploads. So when VanderBot interacts with the Commons API, the <span style="font-family: courier;">qid</span> column must contain an existing M ID. </p><p>After writing the SDoC statements, they will show up under the "Structured data" tab for <a href="https://commons.wikimedia.org/wiki/File:Madonna_and_Child_with_St._Elizabeth_and_infant_John_the_Baptist_-_Vanderbilt_Fine_Arts_Gallery_-_1979.0321P_copy.tif" target="_blank">the media item</a>, like this:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimg29jEed0SnXnn4lF6M7Yv33R1vpogI6y8pTx2-knh5YB6JvUE-KpH6YAj51TUpq_XebfjNuVj9_A3HA-BbT2a_LlEvrYaW45eMGni8C-_1RgtMv4zaCJB0qSldMf-QVi76h_a6bABfnWVVLY5Tdr-XqNEj28gGUSDX1zS38p3K-xEwP_BrVbvKpl/s575/structured_data.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="349" data-original-width="575" height="388" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimg29jEed0SnXnn4lF6M7Yv33R1vpogI6y8pTx2-knh5YB6JvUE-KpH6YAj51TUpq_XebfjNuVj9_A3HA-BbT2a_LlEvrYaW45eMGni8C-_1RgtMv4zaCJB0qSldMf-QVi76h_a6bABfnWVVLY5Tdr-XqNEj28gGUSDX1zS38p3K-xEwP_BrVbvKpl/w640-h388/structured_data.png" width="640" /></a></div><p>Notice that the Q IDs for the depicts values have been replaced by their labels.</p><p>This is a very abbreviated overview of the process and is intended to make the point that once you have the system set up, all you need to write a large number of SDoC <span style="font-family: courier;">depicts</span> statement is a spreadsheet with column for the M IDs of the media items and a column with the Q IDs of what is depicted in that media item. There are more details with linkouts to how to use VanderBot to write to Commons on <a href="https://heardlibrary.github.io/digital-scholarship/lod/wikibase/sdoc/" target="_blank">a webpage that I made for the Wikibase Working Hour presentation</a>.<br /></p><h2 style="text-align: left;">Acquiring Structured Data on Commons from the Wikimedia Commons Query Service<br /></h2><p>A lot of people know about the Wikidata Query Service (WQS), which can be used to query Wikidata using SPARQL. Fewer people know about the <a href="https://commons.wikimedia.org/wiki/Commons:SPARQL_query_service" target="_blank">Wikimedia Commons Query Service</a> (WCQS) because it's newer and interests a narrower audience. You can access the WCQS at <a href="https://commons-query.wikimedia.org/">https://commons-query.wikimedia.org/</a> . It is still under development and is a bit fragile, so it is sometimes down or undergoing maintenance. </p><p>If you are working with SDoC, the WCQS is a very effective way to retrieve information about the current state of the structured data. For example, it's a very simple query to discover all media items that depict a particular item, as shown in the example below. There are quite a few <a href="https://commons.wikimedia.org/wiki/Commons:SPARQL_query_service/queries/examples" target="_blank">examples of queries</a> that you can run to get a feel for how the WCQS might be used.<br /></p><p>It is actually quite easy to query the Wikidata Query Service programmatically, but there are additional challenges to using the WCQS because it requires authentication. I have struggled through reading the developer instructions for accessing the WCQS endpoint via Python and the result is <a href="https://github.com/HeardLibrary/linked-data/blob/master/commonsbot/wcqs/wcqs_query.py" target="_blank">functions and example code</a> that you can use to query the WCQS in your Python scripts. <b>One important warning: the authentication is done by setting a cookie on your computer. </b>So you must be careful not to save this cookie in any location that will be exposed, such as in a GitHub repository. Anyone who gets a copy of this cookie can act as if they were you until the cookie is revoked. To avoid this, the script saves the cookie in your home directory by default. <br /></p><p>The code for querying is very simple with the functions I provide:</p><pre><code>user_agent = 'TestAgent/0.1 (mailto:username@email.com)' # put your own script name and email address here endpoint_url = 'https://commons-query.wikimedia.org/sparql' session = init_session(endpoint_url, retrieve_cookie_string()) wcqs = Sparqler(useragent=user_agent, endpoint=endpoint_url, session=session)</code></pre><pre><code>query_string = '''PREFIX sdc: <https://commons.wikimedia.org/entity/> PREFIX wd: <http://www.wikidata.org/entity/> PREFIX wdt: <http://www.wikidata.org/prop/direct/> SELECT DISTINCT ?depicts WHERE { sdc:M113161207 wdt:P180 ?depicts. }'''</code></pre><p></p><pre><code>data = wcqs.query(query_string) print(json.dumps(data, indent=2))</code></pre><p></p><p>The query is set in the multi-line string assigned in the line that begins <span style="font-family: courier;">query_string =</span>. One thing to notice is that in WCQS queries, you must define the prefixes <span style="font-family: courier;">wdt:</span> and <span style="font-family: courier;">wd:</span> using <span style="font-family: courier;">PREFIX</span> statements in the query prologue. Those prefixes can be used in WQS queries without making <span style="font-family: courier;">PREFIX</span> statements. In addition, you must define the Commons-specific <span style="font-family: courier;">sdc:</span> prefix and use it with M IDs. </p><p>This particular query simply retrieves all of the depicts statements that we created in the example above for <code>M113161207 </code>. The resulting JSON is</p><pre><code>[ { "depicts": { "type": "uri", "value": "http://www.wikidata.org/entity/Q103304813" } }, { "depicts": { "type": "uri", "value": "http://www.wikidata.org/entity/Q302" } }, { "depicts": { "type": "uri", "value": "http://www.wikidata.org/entity/Q345" } }, { "depicts": { "type": "uri", "value": "http://www.wikidata.org/entity/Q40662" } }</code><code>, { "depicts": { "type": "uri", "value": "http://www.wikidata.org/entity/Q235849" } }</code><code> ]</code></pre><p></p><p>The Q IDs can easily be extracted from these results using a list comprehension:</p><p><span style="font-family: courier;"> qids = [ item['depicts']['value'].split('/')[-1] for item in data ]</span></p><p>resulting in this list:</p><p><span style="font-family: courier;">['Q103304813', 'Q302', 'Q345', 'Q40662', 'Q235849']</span><br /> <br /></p><p>Comparison with the example table shows the same four Q IDs that we wrote to the API, plus the depicts value for the artwork (Q103304813) that was created by CommonsTool when the media file was uploaded. When adding new depicts statements, having this information about the ones that already exist can be critical to avoid creating duplicate statements.<br /></p><p>For more details about how the code works, see the <a href="https://heardlibrary.github.io/digital-scholarship/lod/wikibase/sdoc/" target="_blank">informational web page</a> I made for the Wikibase Working Hour presentation.</p><h2 style="text-align: left;">Conclusion<br /></h2><p>I hope that this code will help make it possible to ramp up the rate at which we can add depicts statements to Wikimedia Commons media files. In the Vanderbilt Libraries, we are currently experimenting with using Google Cloud Vision to do object detection and we would like to combine that with artwork title analysis to be able to partially automate the process of describing what is depicted in the <a href="https://www.library.vanderbilt.edu/gallery/" target="_blank">Vanderbilt Fine Arts Gallery</a> works whose <a href="https://www.wikidata.org/wiki/Wikidata:WikiProject_Vanderbilt_Fine_Arts_Gallery" target="_blank">images have been uploaded to Commons</a>. I plan to report on that work in a future post.</p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><br /> <div style='clear: both;'></div> </div> <div class='post-footer'> <div class='post-footer-line post-footer-line-1'> <span class='post-author vcard'> Posted by <span class='fn' itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <meta content='https://www.blogger.com/profile/01896499749604153763' itemprop='url'/> <a class='g-profile' href='https://www.blogger.com/profile/01896499749604153763' rel='author' title='author profile'> <span itemprop='name'>Steve Baskauf</span> </a> </span> </span> <span class='post-timestamp'> at <meta content='http://baskauf.blogspot.com/2023/04/structured-data-in-commons-and-wikibase.html' itemprop='url'/> <a class='timestamp-link' href='http://baskauf.blogspot.com/2023/04/structured-data-in-commons-and-wikibase.html' rel='bookmark' title='permanent link'><abbr class='published' itemprop='datePublished' title='2023-04-12T13:45:00-07:00'>1:45 PM</abbr></a> </span> <span class='post-comment-link'> <a class='comment-link' href='http://baskauf.blogspot.com/2023/04/structured-data-in-commons-and-wikibase.html#comment-form' onclick=''> No comments: </a> </span> <span class='post-icons'> <span class='item-control blog-admin pid-95103704'> <a href='https://www.blogger.com/post-edit.g?blogID=5299754536670281996&postID=4857171635771705909&from=pencil' title='Edit Post'> <img alt='' class='icon-action' height='18' src='https://resources.blogblog.com/img/icon18_edit_allbkg.gif' width='18'/> </a> </span> </span> <div class='post-share-buttons goog-inline-block'> <a class='goog-inline-block share-button sb-email' href='https://www.blogger.com/share-post.g?blogID=5299754536670281996&postID=4857171635771705909&target=email' target='_blank' title='Email This'><span class='share-button-link-text'>Email This</span></a><a class='goog-inline-block share-button sb-blog' href='https://www.blogger.com/share-post.g?blogID=5299754536670281996&postID=4857171635771705909&target=blog' onclick='window.open(this.href, "_blank", "height=270,width=475"); return false;' target='_blank' title='BlogThis!'><span class='share-button-link-text'>BlogThis!</span></a><a class='goog-inline-block share-button sb-twitter' href='https://www.blogger.com/share-post.g?blogID=5299754536670281996&postID=4857171635771705909&target=twitter' target='_blank' title='Share to X'><span class='share-button-link-text'>Share to X</span></a><a class='goog-inline-block share-button sb-facebook' href='https://www.blogger.com/share-post.g?blogID=5299754536670281996&postID=4857171635771705909&target=facebook' onclick='window.open(this.href, "_blank", "height=430,width=640"); return false;' target='_blank' title='Share to Facebook'><span class='share-button-link-text'>Share to Facebook</span></a><a class='goog-inline-block share-button sb-pinterest' href='https://www.blogger.com/share-post.g?blogID=5299754536670281996&postID=4857171635771705909&target=pinterest' target='_blank' title='Share to Pinterest'><span class='share-button-link-text'>Share to Pinterest</span></a> </div> </div> <div class='post-footer-line post-footer-line-2'> <span class='post-labels'> </span> </div> <div class='post-footer-line post-footer-line-3'> <span class='post-location'> </span> </div> </div> </div> </div> </div></div> </div> <div class='blog-pager' id='blog-pager'> <span id='blog-pager-newer-link'> <a class='blog-pager-newer-link' href='http://baskauf.blogspot.com/' id='Blog1_blog-pager-newer-link' title='Newer Posts'>Newer Posts</a> </span> <span id='blog-pager-older-link'> <a class='blog-pager-older-link' href='http://baskauf.blogspot.com/search?updated-max=2023-04-12T13:45:00-07:00&max-results=7' id='Blog1_blog-pager-older-link' title='Older Posts'>Older Posts</a> </span> <a class='home-link' href='http://baskauf.blogspot.com/'>Home</a> </div> <div class='clear'></div> <div class='blog-feeds'> <div class='feed-links'> Subscribe to: <a class='feed-link' href='http://baskauf.blogspot.com/feeds/posts/default' target='_blank' type='application/atom+xml'>Posts (Atom)</a> </div> </div> </div></div> </div> </div> <div class='column-left-outer'> <div class='column-left-inner'> <aside> </aside> </div> </div> <div class='column-right-outer'> <div class='column-right-inner'> <aside> <div class='sidebar section' id='sidebar-right-1'><div class='widget BlogArchive' data-version='1' id='BlogArchive1'> <h2>Blog Archive</h2> <div class='widget-content'> <div id='ArchiveList'> <div id='BlogArchive1_ArchiveList'> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2025/'> 2025 </a> <span class='post-count' dir='ltr'>(1)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2025/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> ▼  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2023/'> 2023 </a> <span class='post-count' dir='ltr'>(2)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2023/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> ▼  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2023/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> <ul class='posts'> <li><a href='http://baskauf.blogspot.com/2023/04/structured-data-in-commons-and-wikibase.html'>Structured Data in Commons and wikibase software t...</a></li> </ul> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2022/'> 2022 </a> <span class='post-count' dir='ltr'>(4)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2022/09/'> September </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2022/06/'> June </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2022/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2022/01/'> January </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2021/'> 2021 </a> <span class='post-count' dir='ltr'>(4)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2021/03/'> March </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2020/'> 2020 </a> <span class='post-count' dir='ltr'>(5)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2020/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2020/02/'> February </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2019/'> 2019 </a> <span class='post-count' dir='ltr'>(9)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2019/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2019/06/'> June </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2019/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2019/04/'> April </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2019/03/'> March </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2018/'> 2018 </a> <span class='post-count' dir='ltr'>(1)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2018/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2017/'> 2017 </a> <span class='post-count' dir='ltr'>(6)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2017/07/'> July </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2017/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2017/03/'> March </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2017/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2016/'> 2016 </a> <span class='post-count' dir='ltr'>(15)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2016/11/'> November </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2016/10/'> October </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2016/04/'> April </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2016/03/'> March </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2016/02/'> February </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2015/'> 2015 </a> <span class='post-count' dir='ltr'>(6)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2015/09/'> September </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2015/07/'> July </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2014/'> 2014 </a> <span class='post-count' dir='ltr'>(7)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2014/05/'> May </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://baskauf.blogspot.com/2014/04/'> April </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> </div> </div> <div class='clear'></div> </div> </div><div class='widget Profile' data-version='1' id='Profile1'> <h2>About Me</h2> <div class='widget-content'> <a href='https://www.blogger.com/profile/01896499749604153763'><img alt='My photo' class='profile-img' height='80' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVm8jF34Q3Q0IttRnG66Z3cjplIPwTfYeVwoznPhxbTRnbtkuN5ekrcV1MNxedjGsgnImAIr_OAT_USbVVyX6pK_xy2GWTQDofBY9K7fiMj9DBOK4_dORjPC0UTaHIvP0/s220/profile-pic-carmen-small.jpg' width='80'/></a> <dl class='profile-datablock'> <dt class='profile-data'> <a class='profile-name-link g-profile' href='https://www.blogger.com/profile/01896499749604153763' rel='author' style='background-image: url(//www.blogger.com/img/logo-16.png);'> Steve Baskauf </a> </dt> </dl> <a class='profile-link' href='https://www.blogger.com/profile/01896499749604153763' rel='author'>View my complete profile</a> <div class='clear'></div> </div> </div></div> </aside> </div> </div> </div> <div style='clear: both'></div> <!-- columns --> </div> <!-- main --> </div> </div> <div class='main-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <footer> <div class='footer-outer'> <div class='footer-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left footer-fauxborder-left'> <div class='fauxborder-right footer-fauxborder-right'></div> <div class='region-inner footer-inner'> <div class='foot no-items section' id='footer-1'></div> <table border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'> <tbody> <tr> <td class='first columns-cell'> <div class='foot no-items section' id='footer-2-1'></div> </td> <td class='columns-cell'> <div class='foot no-items section' id='footer-2-2'></div> </td> </tr> </tbody> </table> <!-- outside of the include in order to lock Attribution widget --> <div class='foot section' id='footer-3' name='Footer'><div class='widget Attribution' data-version='1' id='Attribution1'> <div class='widget-content' style='text-align: center;'> Simple theme. Powered by <a href='https://www.blogger.com' target='_blank'>Blogger</a>. </div> <div class='clear'></div> </div></div> </div> </div> <div class='footer-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </footer> <!-- content --> </div> </div> <div class='content-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <script type='text/javascript'> window.setTimeout(function() { document.body.className = document.body.className.replace('loading', ''); }, 10); </script> <script type="text/javascript" src="https://www.blogger.com/static/v1/widgets/60983134-widgets.js"></script> <script type='text/javascript'> window['__wavt'] = 'AOuZoY5TDWf-FM8YkXDwkib1hlyfb5BUGg:1739773235806';_WidgetManager._Init('//www.blogger.com/rearrange?blogID\x3d5299754536670281996','//baskauf.blogspot.com/2023/04/','5299754536670281996'); _WidgetManager._SetDataContext([{'name': 'blog', 'data': {'blogId': '5299754536670281996', 'title': 'Steve Baskauf\x27s blog', 'url': 'http://baskauf.blogspot.com/2023/04/', 'canonicalUrl': 'http://baskauf.blogspot.com/2023/04/', 'homepageUrl': 'http://baskauf.blogspot.com/', 'searchUrl': 'http://baskauf.blogspot.com/search', 'canonicalHomepageUrl': 'http://baskauf.blogspot.com/', 'blogspotFaviconUrl': 'http://baskauf.blogspot.com/favicon.ico', 'bloggerUrl': 'https://www.blogger.com', 'hasCustomDomain': false, 'httpsEnabled': true, 'enabledCommentProfileImages': true, 'gPlusViewType': 'FILTERED_POSTMOD', 'adultContent': false, 'analyticsAccountNumber': '', 'encoding': 'UTF-8', 'locale': 'en', 'localeUnderscoreDelimited': 'en', 'languageDirection': 'ltr', 'isPrivate': false, 'isMobile': false, 'isMobileRequest': false, 'mobileClass': '', 'isPrivateBlog': false, 'isDynamicViewsAvailable': true, 'feedLinks': '\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Steve Baskauf\x26#39;s blog - Atom\x22 href\x3d\x22http://baskauf.blogspot.com/feeds/posts/default\x22 /\x3e\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/rss+xml\x22 title\x3d\x22Steve Baskauf\x26#39;s blog - RSS\x22 href\x3d\x22http://baskauf.blogspot.com/feeds/posts/default?alt\x3drss\x22 /\x3e\n\x3clink rel\x3d\x22service.post\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Steve Baskauf\x26#39;s blog - Atom\x22 href\x3d\x22https://www.blogger.com/feeds/5299754536670281996/posts/default\x22 /\x3e\n', 'meTag': '', 'adsenseHostId': 'ca-host-pub-1556223355139109', 'adsenseHasAds': false, 'adsenseAutoAds': false, 'boqCommentIframeForm': true, 'loginRedirectParam': '', 'view': '', 'dynamicViewsCommentsSrc': '//www.blogblog.com/dynamicviews/4224c15c4e7c9321/js/comments.js', 'dynamicViewsScriptSrc': '//www.blogblog.com/dynamicviews/f6e0cc369f0f1a05', 'plusOneApiSrc': 'https://apis.google.com/js/platform.js', 'disableGComments': true, 'interstitialAccepted': false, 'sharing': {'platforms': [{'name': 'Get link', 'key': 'link', 'shareMessage': 'Get link', 'target': ''}, {'name': 'Facebook', 'key': 'facebook', 'shareMessage': 'Share to Facebook', 'target': 'facebook'}, {'name': 'BlogThis!', 'key': 'blogThis', 'shareMessage': 'BlogThis!', 'target': 'blog'}, {'name': 'X', 'key': 'twitter', 'shareMessage': 'Share to X', 'target': 'twitter'}, {'name': 'Pinterest', 'key': 'pinterest', 'shareMessage': 'Share to Pinterest', 'target': 'pinterest'}, {'name': 'Email', 'key': 'email', 'shareMessage': 'Email', 'target': 'email'}], 'disableGooglePlus': true, 'googlePlusShareButtonWidth': 0, 'googlePlusBootstrap': '\x3cscript type\x3d\x22text/javascript\x22\x3ewindow.___gcfg \x3d {\x27lang\x27: \x27en\x27};\x3c/script\x3e'}, 'hasCustomJumpLinkMessage': false, 'jumpLinkMessage': 'Read more', 'pageType': 'archive', 'pageName': 'April 2023', 'pageTitle': 'Steve Baskauf\x27s blog: April 2023'}}, {'name': 'features', 'data': {}}, {'name': 'messages', 'data': {'edit': 'Edit', 'linkCopiedToClipboard': 'Link copied to clipboard!', 'ok': 'Ok', 'postLink': 'Post Link'}}, {'name': 'template', 'data': {'name': 'Simple', 'localizedName': 'Simple', 'isResponsive': false, 'isAlternateRendering': false, 'isCustom': false, 'variant': 'simplysimple', 'variantId': 'simplysimple'}}, {'name': 'view', 'data': {'classic': {'name': 'classic', 'url': '?view\x3dclassic'}, 'flipcard': {'name': 'flipcard', 'url': '?view\x3dflipcard'}, 'magazine': {'name': 'magazine', 'url': '?view\x3dmagazine'}, 'mosaic': {'name': 'mosaic', 'url': '?view\x3dmosaic'}, 'sidebar': {'name': 'sidebar', 'url': '?view\x3dsidebar'}, 'snapshot': {'name': 'snapshot', 'url': '?view\x3dsnapshot'}, 'timeslide': {'name': 'timeslide', 'url': '?view\x3dtimeslide'}, 'isMobile': false, 'title': 'Steve Baskauf\x27s blog', 'description': '', 'url': 'http://baskauf.blogspot.com/2023/04/', 'type': 'feed', 'isSingleItem': false, 'isMultipleItems': true, 'isError': false, 'isPage': false, 'isPost': false, 'isHomepage': false, 'isArchive': true, 'isLabelSearch': false, 'archive': {'year': 2023, 'month': 4, 'rangeMessage': 'Showing posts from April, 2023'}}}]); _WidgetManager._RegisterWidget('_NavbarView', new _WidgetInfo('Navbar1', 'navbar', document.getElementById('Navbar1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HeaderView', new _WidgetInfo('Header1', 'header', document.getElementById('Header1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogView', new _WidgetInfo('Blog1', 'main', document.getElementById('Blog1'), {'cmtInteractionsEnabled': false, 'lightboxEnabled': true, 'lightboxModuleUrl': 'https://www.blogger.com/static/v1/jsbin/918196653-lbx.js', 'lightboxCssUrl': 'https://www.blogger.com/static/v1/v-css/1964470060-lightbox_bundle.css'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogArchiveView', new _WidgetInfo('BlogArchive1', 'sidebar-right-1', document.getElementById('BlogArchive1'), {'languageDirection': 'ltr', 'loadingMessage': 'Loading\x26hellip;'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_ProfileView', new _WidgetInfo('Profile1', 'sidebar-right-1', document.getElementById('Profile1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_AttributionView', new _WidgetInfo('Attribution1', 'footer-3', document.getElementById('Attribution1'), {}, 'displayModeFull')); </script> </body> </html>