{"id":22163,"date":"2020-09-15T16:53:57","date_gmt":"2020-09-15T16:53:57","guid":{"rendered":"http:\/\/a_cloudinary_enhanced_student_id_app"},"modified":"2023-10-13T09:06:48","modified_gmt":"2023-10-13T16:06:48","slug":"a_cloudinary_enhanced_student_id_app","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app","title":{"rendered":"A Cloudinary-Enhanced Student-ID App"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><ul>\n<li>\n<a href=\"https:\/\/github.com\/cloudinary-training\/student-id\">Student Id App Repo<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/github.com\/cloudinary-training\/badge\">Badge App Repo<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/github.com\/rebeccapeltz\/vue-student-id\">Vue.js Translation Repo<\/a>\n<\/li>\n<\/ul>\n<p>I\u2019m an instructional designer on Cloudinary\u2019s Solutions and Training team. As the COVID-19 pandemic emerged in March, like other global organizations, we pivoted to set up virtual courses. As much as we looked forward to resuming in-person classes in the future, we switched gear to focus on the virtual way of learning.<\/p>\n<p>At the beginning, we taught online through Zoom webinar, which quickly proved to be inadequate because students as a rule enjoy an active classroom in which they can not only hone their technical skills but also network with one another. Plus, the instructors desire to know the students and their background so as to fine-tune the in-class examples. What was direly missing from virtual training was a <strong>virtual ID badge<\/strong>.<\/p>\n<p>So, we immediately embarked on building an app, dubbed the <strong>Student-ID App<\/strong>, leveraging the techniques and code from the <em>Fundamentals for Developers<\/em> course. This post describes the app\u2019s components, configurations, and the like; also its benefits for the Customer Success team and a roadmap.<\/p>\n<p>Read on for the details:<\/p>\n<ul>\n<li>\n<a href=\"#sample-app\">Developing a Sample App<\/a>\n<\/li>\n<li>\n<a href=\"#cs\">Branching Out for Customer Success<\/a>\n<\/li>\n<li>\n<a href=\"#vue\">Transcribing to Vue.js<\/a>\n<\/li>\n<li>\n<a href=\"#evaluate\">Evaluating the App<\/a>\n<\/li>\n<li>\n<a href=\"#move\">Moving On<\/a>\n<\/li>\n<li>\n<a href=\"#scope\">Scoping Out the Resources<\/a>\n<\/li>\n<\/ul>\n<h2 id=\"sample-app\">Developing a Sample App<\/h2>\n<p>The main purpose of the app is to show how <strong>upload presets<\/strong> and <strong>named transformations<\/strong> help deliver a webpage that contains the assets stored in a Cloudinary account.<\/p>\n<h3>Definitions<\/h3>\n<p>An <strong>Upload preset<\/strong> is a named set of instructions, configured as signed or unsigned, that execute during an asset upload. You can call an unsigned preset from the browser without exposing secret credentials.<\/p>\n<p>A <strong>named transformation<\/strong>, a set of abbreviated instructions for asset delivery, acts as a template you can apply to multiple assets to optimize delivery and raise aesthetic appeal.<\/p>\n<p>A key goal is to keep this front-end app simple with no reliance on external servers for rendering, database, or authentication. It\u2019s simply HTML, CSS, and Vanilla JavaScript in the browser communicating with Cloudinary\u2019s APIs.<\/p>\n<p>The picture below shows the app\u2019s badge gallery: a group of students who have enrolled in a class along with their photos, names, organizations, titles, favorite background colors. All the data resides in Cloudinary with the photo\u2019s public ID being the key and the other details stored as metadata.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_400,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/Student_id.jpg\" alt=\"Student ID App\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"400\" height=\"236\"\/>\n<em>All photos are from pexels and associated data is fabricated.<\/em><\/p>\n<p>The data (names, titles, organizations) is stored with the image and delivered through a named transformation that accesses the context metadata.<\/p>\n<h3>Configurations<\/h3>\n<p>For ease of use, configuration is in the form of  query strings, i.e.:<\/p>\n<ul>\n<li>Cloud name (<code>cn<\/code>)<\/li>\n<li>Course title (<code>title<\/code>)<\/li>\n<li>Course date (<code>date<\/code>)<\/li>\n<\/ul>\n<p>The demo page\u2019s URL reads like this:<\/p>\n<p><code>https:\/\/studentid.cloudinary.training\/index.html?cn=&lt;CLOUD_NAME&gt;&amp;title=&lt;TITLE STRING&gt;&amp;date=&lt;DATE STRING&gt;<\/code><\/p>\n<p>Before using the URL above, run two Node.js scripts in the code repo:<\/p>\n<ol>\n<li>Create an <a href=\"https:\/\/github.com\/cloudinary-training\/student-id\/blob\/master\/create-student-id-preset.js\">unsigned upload preset<\/a>, which adds the metadata to the page, placing the data in a folder called <code>student-id<\/code> and tagging it <code>student-id<\/code>. That folder enables the owner (instructor) to quickly locate the uploaded information in the Media Library.  Cloudinary\u2019s <code>list<\/code> API collects the images with the tag for display in the gallery.<\/li>\n<li>Create a <a href=\"https:\/\/github.com\/cloudinary-training\/student-id\/blob\/master\/create-named-badge-xform-color.js\">named transformation<\/a>, which accepts the metadata saved with the image and which creates the badge.<\/li>\n<\/ol>\n<p>Afterwards, create a student ID gallery with the URL.<\/p>\n<p>As announced in the top banner, this configuration allows only one course per Cloudinary account. To ensure privacy, the app creates the account for the virtual class only and deletes it when the class is over\u2014with no data collection whatsoever.<\/p>\n<h3>Banner<\/h3>\n<p>The top banner affirms to the participants that the data will not be saved. Also, an interface there enables them to delete the information or uploaded images through Cloudinary Support.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/studet-id-disclosure.jpg\" alt=\"Top banner\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"201\"\/><\/p>\n<h3>Form<\/h3>\n<p>The form facilitates data entry. Once you\u2019ve filled in all the fields, the Upload Image button is enabled. Clicking it opens the upload widget.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/badge-creation.jpg\" alt=\"Create a badge\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"273\"\/><\/p>\n<h3>Upload Widget<\/h3>\n<p>In the <em>Fundamentals for Developers<\/em> course, students learn the techniques for uploading assets by working through code. In particular, they instantiate and manage with JavaScript the upload widget, a highly configurable, responsive component. Optionally, students can add an upload preset to accept JPEG and PNG assets from various sources: the local file system, the web, Facebook profiles, and the device camera.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_600,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/upload_widget_big.jpg\" alt=\"Upload widget\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"600\" height=\"476.5\"\/><\/p>\n<h3>Face Recognition<\/h3>\n<p>Faces are crucial for this app. Adding Cloudinary\u2019s face-detection capability as an upload-preset instruction generates a report in the upload response on whether the image has a face. Also, you can delete any that\u2019s not a face along with a reminder for the user to upload again.<\/p>\n<p>In the upload request, you can ask Cloudinary for a delete token that\u2019s valid for 10 minutes and store it locally. However, for such a short duration, it\u2019s just as well to leave the token in memory. This is a front-end app so no cookies are involved.<\/p>\n<h3>Unique Data<\/h3>\n<p>Entering unique data is the only other requirement. If you enter a duplicate first name, last name, title, or organization name, the app displays a Toast warning.<\/p>\n<h2 id=\"cs\">Branching Out for Customer Success<\/h2>\n<p>A recent demo of the Student-ID App at Cloudinary\u2019s weekly company caught the eye of a customer success manager (CSM), who asked to use it at an upcoming meetup with new customers. Because the CSM scenario required the gathering of names and titles for a large team at the beginning of a relationship, a couple of tweaks were necessary:<\/p>\n<ul>\n<li>\n<p>We removed the data-deletion step toward the end because the app was to be reused for new customers. That change involved a simple refactoring, whereby we replaced the hard-coded <code>student-id<\/code> for the folder and tag with a <code>badge<\/code> key in the set of query strings. The <code>badge<\/code> value then became the folder and tag name for data storage and queries.<\/p>\n<p>Afterwards, a single account can hold many folders, one for each customer or customer meeting.<\/p>\n<\/li>\n<li>\n<p>We removed the banner because the CSMs could manage the data themselves.<\/p>\n<\/li>\n<\/ul>\n<h2 id=\"vue\">Transcribing to Vue.js<\/h2>\n<p>I like teaching in Vue.js. Once students have mastered coding in  HTML, CSS, and JavaScript in separate files, it\u2019s fun to show them how to write scoped code for all three languages in Vue.js\u2014 in a single file.<\/p>\n<p>Right before the COVID pivot, I attended an in-person Vue.js conference with Cloudinary\u2019s Evangelism team, after which Doron Sherman, our VP of evangelism, asked me, \u201cWould you want to showcase the Student-ID App at a Vue.js conference?\u201d I was intrigued but offered to calibrate the app first.<\/p>\n<p>Fact is, the single JavaScript file for creating the app looked rather naive\u2014just a bunch of listeners and functions that either passed around local data or accessed global data, resulting in confusing scoping. To be sure, the app\u2019s simplicity was ideal for training, but it lacked organization and did not address a few issues that modern JavaScript frameworks might encounter.<\/p>\n<p>The tree diagram below shows four components:<\/p>\n<ul>\n<li>\n<strong>The Banner<\/strong>, which is self-explanatory.<\/li>\n<li>\n<strong>The Form<\/strong>, which pushes and splices data into the data store.<\/li>\n<li>\n<strong>The Gallery<\/strong>, which reads the reactive data store and updates the badges with information that reflects the state of the store.<\/li>\n<li>\n<strong>The App<\/strong>, which registers a Toastify plugin for generating toasts on the status and changes.<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_600,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/student-id-comonent-tree.png\" alt=\"component tree\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1200\" height=\"751\"\/><\/p>\n<p>With the design as background, I\u2019ll explain a few Cloudinary-specific coding requirements in the subsections below.<\/p>\n<h3>The Upload Widget in a Framework<\/h3>\n<p>Cloudinary\u2019s upload widget is styled in jQuery. To incorporate the code library for the widget, add a <code>script<\/code> tag to the project\u2019s <code>index.html<\/code> file:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>script\n     src=&quot;https:\/\/widget.cloudinary.com\/v2.0\/global\/all.js&quot;\n     type=&quot;text\/javascript&quot;\n   &gt;&lt;\/script&gt;\n<\/code><\/pre>\n<p>A callback function in the widget, which generates error and result objects, such as events that show the upload progress in percentages, is called repeatedly during upload. However, callback functions can be problematic in an otherwise modular function because they can block access to the <code>this<\/code> variable, which references the component within which the widget is rendered. That component defines the functions for processing the callback result, but the callback function cannot access the functions in the parent component by default.<\/p>\n<p>Here\u2019s the solution: the standard <code>function()<\/code> syntax makes the <code>this<\/code> reference to the widget; the arrow (<code>=&gt;<\/code>) function syntax makes the <code>this<\/code> reference the global window object. The easiest way to implement component functionality inside the callback is to bind <code>this<\/code> to it. Here, you\u2019re binding to the callback function a reference to the component itself:<\/p>\n<pre class=\"js-syntax-highlighted\"><code> function(error, result) {\n \t\u2026.\n }.bind(this)\n<\/code><\/pre>\n<p>Assigning the component reference with the <code>bind<\/code> function enables you access to all component and imported module functions, as well as the data.<\/p>\n<h3><code>list<\/code> API and Form-Data Processing<\/h3>\n<p>The store defines an action that is called on a page load, fetching the student data with the <code>list<\/code> API, which gathers up all the assets with a tag named in the JSON file it returns. A <code>list<\/code> API call looks like this:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>const dataURL = `https:\/\/res.cloudinary.com\/${cloudname}\/image\/list\/v${Date.now()}\/student-id.json`\n<\/code><\/pre>\n<p>Certain processing must occur before this data can function as variables in the named transformation.<\/p>\n<p>On a successful upload, the upload widget returns similar data, after which we push the data from the <code>list<\/code> API and splice the data from the form upload. All that is to maintain the default order (most recent first) of <code>list<\/code> and to place newly uploaded badges first in the gallery to minimize scrolling.<\/p>\n<p>The <code>list<\/code> API module under <code>src\/util<\/code> contains code that the URL encodes with the variable data that is supplied to the named transformation.<\/p>\n<h3><code>list<\/code> API and Cache Busting<\/h3>\n<p>The <code>list<\/code> API also creates a JSON file on the content delivery network (CDN). <a href=\"https:\/\/cloudinary.com\/glossary\/cdn-caching\">Caching<\/a> is useful if the data remains largely unchanged. To add new members to a list of students, however, you must refresh the JSON file by supplying a version with the epoch date. Hence this code in the URL for the page-load fetch call above:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>v${Date.now()}\n<\/code><\/pre>\n<h3>Responsiveness<\/h3>\n<p>The Student-ID App is device responsive to accommodate that large segment of audience who prefers to interact with apps on their phones.<\/p>\n<h4>Inline Form<\/h4>\n<p>The input form appears inline on a desktop and renders a single line per input on a smaller device.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_400,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/responsive-form.jpg\" alt=\"badge form\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"400\" height=\"681\"\/><\/p>\n<p>The form is in the CSS Flexbox layout, which adopts the mobile-first approach, assuming that only devices with a viewport greater than 800 pixels are served the desktop layout.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center;\n}\n.form-inline label {\n margin: 0;\n font-size: 0.8rem;\n \n.form-inline input {\n vertical-align: middle;\n margin: 0;\n padding: .6rem;\n background-color: #fff;\n border: .3rem solid #ddd;\n}\n.form-inline button {\n padding: .6rem 1.2rem;\n background-color: #0e2f5a;\n border: 1px solid #ddd;\n color: white;\n cursor: pointer;\n}\n.form-inline button:disabled {\n background-color: gray;\n cursor: none;\n}\n.form-inline button:hover {\n background-color: royalblue;\n}\n@media only screen and (min-width: 800px) {\n .form-inline label {\n   margin: .3rem;\n }\n .form-inline button {\n   margin: 0 0 0 .3rem;\n }\n .form-inline button:disabled {\n   background-color: gray;\n   cursor:none;\n }\n .form-inline input {\n   margin: .3rem 0;\n }\n}\n@media (max-width: 800px) {\n \n .form-inline {\n   flex-direction: column;\n   align-items: stretch;\n }\n .form-inline button {\n   margin-top: .3rem;\n }\n<\/code><\/pre>\n<h3>Wrapping Grid<\/h3>\n<p>The gallery is a container in the CSS grid layout, allowing for separation and wrapping of the badges.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_200,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/badge-id.jpg\" alt=\"ID Badge\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"400\" height=\"809\"\/><\/p>\n<p>With the Min\/Max option for grid-template-columns, you can specify the size of the images in the grid with a small phone\u2019s width. The uploaded images are eagerly transformed to that size according to the instructions in the upload preset.<\/p>\n<p>By way of explanation, eager transformations create derived images (or videos) during upload. Even though you can transform media, such as cropping them, on the fly, transforming them eagerly eliminates the wait time for the first derived transformation. Eager transformations are especially desirable for complex modifications or those of large assets like video\u2014in effect, a best practice as part of any upload workflow.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n grid-gap: 1rem;\n}\n<\/code><\/pre>\n<h2 id=\"evaluate\">Evaluating the App<\/h2>\n<p>Instructional designers and educators like to refer to students in the same class or curriculum as cohorts, i.e., the community. The Student-ID App readily identifies community members, serving both as a badge for each individual and as an image of the community. We\u2019ve just started to use the app in our courses. So far, participation has been excellent.<\/p>\n<p>In essence, such an app defines use cases and answers many <em>how<\/em> questions, e.g.:<\/p>\n<ul>\n<li>How is the data input, uploaded, stored, and retrieved?<\/li>\n<li>How is the data displayed on a webpage?<\/li>\n<li>How do users interact with the app?<\/li>\n<\/ul>\n<p>Since numerous students, many of whom are professionals, are interested in use cases for what they\u2019ve learned, the app is intended as a project that students could fork and build on. Courses like ours often come with an expectation that the students will return to work armed with new technical skills. This app can be a starting point for students to build their own app with Cloudinary\u2019s tools, techniques, and coding practices.<\/p>\n<h2 id=\"move\">Moving On<\/h2>\n<p>Following are a few ways you can capitalize on the Student-ID App.<\/p>\n<h3>Rewrite<\/h3>\n<p>This app was developed in three major steps:<\/p>\n<ul>\n<li>Vanilla JavaScript with one app per cloud<\/li>\n<li>Vanilla JavaScript with multiple apps per cloud<\/li>\n<li>Vue.js with one app per cloud<\/li>\n<\/ul>\n<p>To learn the ins and outs, create a new project that builds on it. Next, consolidate the code or rewrite it in React, Angular, Ruby, PHP, Dotnet, Node.js, Java, Android, iOS, whatever you prefer. In fact, if you leave the browser, you can learn from and take advantage of the many capabilities offered by the Cloudinary SDKs.<\/p>\n<h3>Deletion of Badges<\/h3>\n<p>Someone raised a feature request for an easier step to delete a badge, e.g., an OOP button that\u2019s more forgiving than one that leads to an email to tech support. Well, the upload requests contain a delete token in the front end token that\u2019s valid for 10 minutes, which you could use to delete a just-uploaded asset. Currently, the token deletes nonfacial images only, but you could make a button available after an upload that would delete the uploaded image on a click.<\/p>\n<h2 id=\"scope\">Scoping Out the Resources<\/h2>\n<p>Students and  professionals of media development alike who\u2019re keen on implementing a front end for Cloudinary\u2019s assets would find the code shared here useful.  For further reference, have a look at the self-service and virtual training courses in the <a href=\"https:\/\/training.cloudinary.com\/\">Cloudinary Academy<\/a>. Our <a href=\"https:\/\/cloudinary.com\/documentation\">documentation<\/a> and <a href=\"https:\/\/support.cloudinary.com\/hc\/en-us\">Support team<\/a> can also answer questions that might arise.<\/p>\n<p>Above all, check out Cloudinary\u2019s robust <a href=\"https:\/\/cloudinary.com\/documentation\/cloudinary_references\">APIs<\/a>. You\u2019ll be happily surprised at how many nifty features you can build with them with only minimal code.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":22164,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-22163","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>A Cloudinary-Enhanced Student-ID App<\/title>\n<meta name=\"description\" content=\"Learn the components, settings, and coding techniques for the new Student-ID App that leverages Cloudinary&#039;s upload presets and named transformations.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A Cloudinary-Enhanced Student-ID App\" \/>\n<meta property=\"og:description\" content=\"Learn the components, settings, and coding techniques for the new Student-ID App that leverages Cloudinary&#039;s upload presets and named transformations.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-09-15T16:53:57+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-10-13T16:06:48+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1649725791\/Web_Assets\/blog\/Student-ID_22164d8cd9\/Student-ID_22164d8cd9-jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1540\" \/>\n\t<meta property=\"og:image:height\" content=\"847\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"A Cloudinary-Enhanced Student-ID App\",\"datePublished\":\"2020-09-15T16:53:57+00:00\",\"dateModified\":\"2023-10-13T16:06:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app\"},\"wordCount\":4,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725791\/Web_Assets\/blog\/Student-ID_22164d8cd9\/Student-ID_22164d8cd9.jpg?_i=AA\",\"inLanguage\":\"en-US\",\"copyrightYear\":\"2020\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app\",\"url\":\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app\",\"name\":\"A Cloudinary-Enhanced Student-ID App\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725791\/Web_Assets\/blog\/Student-ID_22164d8cd9\/Student-ID_22164d8cd9.jpg?_i=AA\",\"datePublished\":\"2020-09-15T16:53:57+00:00\",\"dateModified\":\"2023-10-13T16:06:48+00:00\",\"description\":\"Learn the components, settings, and coding techniques for the new Student-ID App that leverages Cloudinary's upload presets and named transformations.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725791\/Web_Assets\/blog\/Student-ID_22164d8cd9\/Student-ID_22164d8cd9.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725791\/Web_Assets\/blog\/Student-ID_22164d8cd9\/Student-ID_22164d8cd9.jpg?_i=AA\",\"width\":1540,\"height\":847},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A Cloudinary-Enhanced Student-ID App\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"A Cloudinary-Enhanced Student-ID App","description":"Learn the components, settings, and coding techniques for the new Student-ID App that leverages Cloudinary's upload presets and named transformations.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app","og_locale":"en_US","og_type":"article","og_title":"A Cloudinary-Enhanced Student-ID App","og_description":"Learn the components, settings, and coding techniques for the new Student-ID App that leverages Cloudinary's upload presets and named transformations.","og_url":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app","og_site_name":"Cloudinary Blog","article_published_time":"2020-09-15T16:53:57+00:00","article_modified_time":"2023-10-13T16:06:48+00:00","og_image":[{"width":1540,"height":847,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1649725791\/Web_Assets\/blog\/Student-ID_22164d8cd9\/Student-ID_22164d8cd9-jpg?_i=AA","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app"},"author":{"name":"","@id":""},"headline":"A Cloudinary-Enhanced Student-ID App","datePublished":"2020-09-15T16:53:57+00:00","dateModified":"2023-10-13T16:06:48+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app"},"wordCount":4,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725791\/Web_Assets\/blog\/Student-ID_22164d8cd9\/Student-ID_22164d8cd9.jpg?_i=AA","inLanguage":"en-US","copyrightYear":"2020","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app","url":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app","name":"A Cloudinary-Enhanced Student-ID App","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725791\/Web_Assets\/blog\/Student-ID_22164d8cd9\/Student-ID_22164d8cd9.jpg?_i=AA","datePublished":"2020-09-15T16:53:57+00:00","dateModified":"2023-10-13T16:06:48+00:00","description":"Learn the components, settings, and coding techniques for the new Student-ID App that leverages Cloudinary's upload presets and named transformations.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725791\/Web_Assets\/blog\/Student-ID_22164d8cd9\/Student-ID_22164d8cd9.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725791\/Web_Assets\/blog\/Student-ID_22164d8cd9\/Student-ID_22164d8cd9.jpg?_i=AA","width":1540,"height":847},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/a_cloudinary_enhanced_student_id_app#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"A Cloudinary-Enhanced Student-ID App"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725791\/Web_Assets\/blog\/Student-ID_22164d8cd9\/Student-ID_22164d8cd9.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/22163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=22163"}],"version-history":[{"count":3,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/22163\/revisions"}],"predecessor-version":[{"id":31465,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/22163\/revisions\/31465"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/22164"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=22163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=22163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=22163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}