These are the slides for the "Dynamic websites for Artists" workshop.
It's a workshop on quick-and-dirty dynamic websites for artists. The workshop covers how to build and host a basic website that accepts user data, saves it, manipulates it, and displays it back.
The workshop covers the basics of using Sinatra, Redis, and Heroku. It uses the Dropbox integration feature of Heroku to deploy sites quickly (and without using git).
Basic HTML knowledge is required, and a passing familiarity with the command line will be very useful.
For the code, see https://github.com/workergnome/dynamic-workshop
The Carnegie Museum of Art is attempting to structure provenance data so curators, scholars, and software developers can create visualizations that answer questions that would be difficult or impossible to answer without computer assistance. Provenance, the written description of the history of ownership and custody of art, is typically written as a list of the periods, places, and owners of an artwork. It captures the current best understanding of this history in a succinct and precise manner, and illustrates the gaps and uncertainties that still remain. Provenance is typically written as semi-structured text, following an institution-defined format. It would be useful to have a structured, computer-readable format for this data, allowing for search, visualization, and aggregated research.
The American Alliance of Museums suggested standard, widely used across museums, is not defined with enough specificity to allow automated extraction of the structured data contained within provenance texts. Also, the provenance record model in collection management systems (CMS) is often not designed for structured data or does not provide a way to verify that the provenance text matches the structured data. A comprehensive text-based provenance standard, paired with a software library that can parse records written using this standard and convert them into structured data, would allow existing workflows to remain in place while allowing structured data to be automatically extracted from provenance records. The records could continue to be stored within existing CMS databases but contain machine-readable data for use in research and visualization. Outside of data itself, the stories these objects hold are often moving and sometimes astonishing. This ability to ask impossible questions and receive answers previously inaccessible across a museum’s collection and (eventually) across many museums’ collections is a resource art historians and scholars will find extremely valuable.
As part of the leadup to the Carnegie Museum of Art's Distant Feel Exhibit, the Gulf Tower, a landmark building in downtown Pittsburgh became a giant mood ring for Pittsburgh.
Using the Instagram API, I collected photos from across the Pittsburgh metropolitan area and analyzed them for their general mood. This was used to calculate a positive and negative score for the entire city.
This score was then used to create a giant data visualization using the architectural lighting on the Gulf Tower in Downtown Pittsburgh, PA.
For more information, see http://www.workergnome.com/work/gulf-tower/
For a video of the presentation, see: https://www.youtube.com/watch?v=xrlGhRMaKuc
Data Visualization for Journalists and MediaDavid Newbury
These are the slides for a presentation given through Code & Supply on how to think about data visualization:
Are you interested in making your stories more dynamic, but not sure how to do it? This four hour workshop will explore basic workflows and techniques for using data to tell stories. We will also be using data to generate maps and charts that are dynamic and generated from real civic data provided in partnership with Pittsburgh OpenData, our Code for America brigade. We will also explore ways to take the visualizations created and place them online!
This was presented with support from the Knight-Mozilla OpenNews project, ONA Pittsburgh, and War Streets Media
21st Century Provenance: Lessons Learned Building Art TracksDavid Newbury
This talk, given at the Yale Center for British Art on February 27th, 2017, discusses how Art Tracks, CMOA’s National Endowment for the Humanities-funded digital provenance project, was formed through the combined efforts of technologists, curators, and provenance researchers. We provided an overview of the project, discussed our current research of the Northbrook Collection, and shared insights about the collaboration that resulted from this cross-disciplinary project.
Video is available at http://britishart.yale.edu/multimedia-video/27/4261
The investor presentation we used to raise 2 million dollarsMikael Cho
The investor presentation we used to raise 2 million dollars for ooomf.com (now pickcrew.com)
View the online version here: https://pickcrew.com/investors/
The Carnegie Museum of Art is attempting to structure provenance data so curators, scholars, and software developers can create visualizations that answer questions that would be difficult or impossible to answer without computer assistance. Provenance, the written description of the history of ownership and custody of art, is typically written as a list of the periods, places, and owners of an artwork. It captures the current best understanding of this history in a succinct and precise manner, and illustrates the gaps and uncertainties that still remain. Provenance is typically written as semi-structured text, following an institution-defined format. It would be useful to have a structured, computer-readable format for this data, allowing for search, visualization, and aggregated research.
The American Alliance of Museums suggested standard, widely used across museums, is not defined with enough specificity to allow automated extraction of the structured data contained within provenance texts. Also, the provenance record model in collection management systems (CMS) is often not designed for structured data or does not provide a way to verify that the provenance text matches the structured data. A comprehensive text-based provenance standard, paired with a software library that can parse records written using this standard and convert them into structured data, would allow existing workflows to remain in place while allowing structured data to be automatically extracted from provenance records. The records could continue to be stored within existing CMS databases but contain machine-readable data for use in research and visualization. Outside of data itself, the stories these objects hold are often moving and sometimes astonishing. This ability to ask impossible questions and receive answers previously inaccessible across a museum’s collection and (eventually) across many museums’ collections is a resource art historians and scholars will find extremely valuable.
As part of the leadup to the Carnegie Museum of Art's Distant Feel Exhibit, the Gulf Tower, a landmark building in downtown Pittsburgh became a giant mood ring for Pittsburgh.
Using the Instagram API, I collected photos from across the Pittsburgh metropolitan area and analyzed them for their general mood. This was used to calculate a positive and negative score for the entire city.
This score was then used to create a giant data visualization using the architectural lighting on the Gulf Tower in Downtown Pittsburgh, PA.
For more information, see http://www.workergnome.com/work/gulf-tower/
For a video of the presentation, see: https://www.youtube.com/watch?v=xrlGhRMaKuc
Data Visualization for Journalists and MediaDavid Newbury
These are the slides for a presentation given through Code & Supply on how to think about data visualization:
Are you interested in making your stories more dynamic, but not sure how to do it? This four hour workshop will explore basic workflows and techniques for using data to tell stories. We will also be using data to generate maps and charts that are dynamic and generated from real civic data provided in partnership with Pittsburgh OpenData, our Code for America brigade. We will also explore ways to take the visualizations created and place them online!
This was presented with support from the Knight-Mozilla OpenNews project, ONA Pittsburgh, and War Streets Media
21st Century Provenance: Lessons Learned Building Art TracksDavid Newbury
This talk, given at the Yale Center for British Art on February 27th, 2017, discusses how Art Tracks, CMOA’s National Endowment for the Humanities-funded digital provenance project, was formed through the combined efforts of technologists, curators, and provenance researchers. We provided an overview of the project, discussed our current research of the Northbrook Collection, and shared insights about the collaboration that resulted from this cross-disciplinary project.
Video is available at http://britishart.yale.edu/multimedia-video/27/4261
The investor presentation we used to raise 2 million dollarsMikael Cho
The investor presentation we used to raise 2 million dollars for ooomf.com (now pickcrew.com)
View the online version here: https://pickcrew.com/investors/
Rudi Engelbrecht explores Maglev in a hands on tutorial. Topics such as transparent object persistence, concurrency, multiple Ruby VM's accessing the same objects, persisting Ruby procs and Continuations are illustrated. Source code is on https://github.com/rle
Frontera распределенный робот для обхода веба в больших объемах / Александр С...Ontico
В этом докладе я собираюсь поделиться нашим опытом обхода испанского интернета. Мы поставили перед собой задачу обойти около 600 тысяч веб-сайтов в зоне .es с целью сбора статистики об узлах и их размерах. Я расскажу об архитектуре робота, хранилища, проблемах, с которыми мы столкнулись при обходе, и их решении.
Наше решение доступно в форме open source фреймворка Frontera. Фреймворк позволяет построить распределенного робота для скачивания страниц из Интернета в больших объемах в реальном времени. Также он может быть использован для построения сфокусированных роботов для выкачивания подмножества заранее известных веб-сайтов.
Фреймворк предлагает: настраиваемое хранилище URL документов (RDBMS или Key Value), управление стратегиями обхода, абстракцию транспортного уровня, абстракцию модуля загрузки.
Доклад построен в увлекательной форме: описание проблемы, решение и проблемы, которые возникли в ходе разработки решения.
Can be used as a introductory presentation to web security basics. Contains intro on Attacks to Preventions Tips, organized neatly.
http://codeinmybug.wordpress.com/2007/10/12/the-web-is-broken/
Are you creative? Do you internet? Would you like to internet better? Do you wish that you knew how to get started building things for and on the internet?
I'd love to show you how to internet in a single afternoon, but that's impossible. So I'm going to give you a overview of the technologies used on the internet, how they're used, why they're valuable, and how they fit together.
I will teach you the "Magic Words™": what a Node is (and isn't), what belongs in Flask, where Sinatra fits in. I'll demo some of the technologies, and, most importantly, I'll tell you what you *don't* need to know.
This will provide enough of map that you'll be able to Stack Overflow your way to internet success!
Presented at the University of Denver, Emergent Digital Practices on February 17th, 2016
Congrats! You and your coworkers love Docker. Docker has become an increasingly helpful tool when it comes to devops. We can now build smaller, more robust local development setups with the promise of mirroring production. One thing that still plagues many situations is how to get those containers into production and update them over time. We will explore different tools for setting up, configuring, and maintaining containers as they go live.
Ruby is just over 20 years old. It's no longer young or hip, and that’s a good thing! In the last decade, Ruby has matured as a web technology. It's being used in many successful companies out there such as Hulu, GitHub, and Bloomberg. The ecosystem is comprised of many stable libraries and tools to handle most common web tasks, allowing you to focus on adding features to improve your product and better serve your customers. We'll talk about how you can build scalable and reliable software, but still maintain fast development turnaround by leveraging the maturity and creativity of the Ruby community.
Making Glance tasks work for you - OpenStack Summit May 2015 VancouverBrian Rosmaita
It's not widely known that the OpenStack Images API v2 contains an implementation of a "tasks" API that can be customized by operators to enable asynchronous processing of long-running operations. For example, a deployer might want to enable end users to upload their own custom images ... but only after such images have been approved by some thorough, computation-intensive validation process. The Glance tasks API provides a common interface across OpenStack installations, but allows the implementation of tasks to be customizable to a particular cloud environment. Join Brian Rosmaita, Compute Control Plane Product Manager at Rackspace to see how Glance tasks are being used at Rackspace and to learn how you can use Glance tasks in your OpenStack cloud.
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
Presented at the Coalition of Networked Information (CNI) Spring 2024 Project Briefings.
Over the past six years, Getty has been engaged in a project to transform and unify its complex digital infrastructure for cultural heritage information. One of the project’s core goals was to provide validation of the impact and value of the use of linked data throughout this process. With museum, archival, media, and vocabularies in production and others underway, this sessions shares some of the practical implications (and pitfalls) of this work—particularly as it relates to interoperability, discovery, staffing, stakeholder engagement, and complexity management. The session will also share examples of how other organizations can streamline their own, similar work going forward.
The LOD Gateway: Open Source Infrastructure for Linked DataDavid Newbury
Presented at the CIDOC conference in Mexico City, 2023, this talk provides a walkthrough of the digital infrastructure behind the LOD Gateway, a critical part of Getty's digital API infrastructure.
It discusses the difference between graphs, documents, and how both are important for different use cases.
As part of MuseWeb 2023 in Washington, DC, this presentation walks through the basics of Linked Data, and then discusses the six levels of implementation of Linked Data, using the Getty's work as examples.
Rudi Engelbrecht explores Maglev in a hands on tutorial. Topics such as transparent object persistence, concurrency, multiple Ruby VM's accessing the same objects, persisting Ruby procs and Continuations are illustrated. Source code is on https://github.com/rle
Frontera распределенный робот для обхода веба в больших объемах / Александр С...Ontico
В этом докладе я собираюсь поделиться нашим опытом обхода испанского интернета. Мы поставили перед собой задачу обойти около 600 тысяч веб-сайтов в зоне .es с целью сбора статистики об узлах и их размерах. Я расскажу об архитектуре робота, хранилища, проблемах, с которыми мы столкнулись при обходе, и их решении.
Наше решение доступно в форме open source фреймворка Frontera. Фреймворк позволяет построить распределенного робота для скачивания страниц из Интернета в больших объемах в реальном времени. Также он может быть использован для построения сфокусированных роботов для выкачивания подмножества заранее известных веб-сайтов.
Фреймворк предлагает: настраиваемое хранилище URL документов (RDBMS или Key Value), управление стратегиями обхода, абстракцию транспортного уровня, абстракцию модуля загрузки.
Доклад построен в увлекательной форме: описание проблемы, решение и проблемы, которые возникли в ходе разработки решения.
Can be used as a introductory presentation to web security basics. Contains intro on Attacks to Preventions Tips, organized neatly.
http://codeinmybug.wordpress.com/2007/10/12/the-web-is-broken/
Are you creative? Do you internet? Would you like to internet better? Do you wish that you knew how to get started building things for and on the internet?
I'd love to show you how to internet in a single afternoon, but that's impossible. So I'm going to give you a overview of the technologies used on the internet, how they're used, why they're valuable, and how they fit together.
I will teach you the "Magic Words™": what a Node is (and isn't), what belongs in Flask, where Sinatra fits in. I'll demo some of the technologies, and, most importantly, I'll tell you what you *don't* need to know.
This will provide enough of map that you'll be able to Stack Overflow your way to internet success!
Presented at the University of Denver, Emergent Digital Practices on February 17th, 2016
Congrats! You and your coworkers love Docker. Docker has become an increasingly helpful tool when it comes to devops. We can now build smaller, more robust local development setups with the promise of mirroring production. One thing that still plagues many situations is how to get those containers into production and update them over time. We will explore different tools for setting up, configuring, and maintaining containers as they go live.
Ruby is just over 20 years old. It's no longer young or hip, and that’s a good thing! In the last decade, Ruby has matured as a web technology. It's being used in many successful companies out there such as Hulu, GitHub, and Bloomberg. The ecosystem is comprised of many stable libraries and tools to handle most common web tasks, allowing you to focus on adding features to improve your product and better serve your customers. We'll talk about how you can build scalable and reliable software, but still maintain fast development turnaround by leveraging the maturity and creativity of the Ruby community.
Making Glance tasks work for you - OpenStack Summit May 2015 VancouverBrian Rosmaita
It's not widely known that the OpenStack Images API v2 contains an implementation of a "tasks" API that can be customized by operators to enable asynchronous processing of long-running operations. For example, a deployer might want to enable end users to upload their own custom images ... but only after such images have been approved by some thorough, computation-intensive validation process. The Glance tasks API provides a common interface across OpenStack installations, but allows the implementation of tasks to be customizable to a particular cloud environment. Join Brian Rosmaita, Compute Control Plane Product Manager at Rackspace to see how Glance tasks are being used at Rackspace and to learn how you can use Glance tasks in your OpenStack cloud.
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
Presented at the Coalition of Networked Information (CNI) Spring 2024 Project Briefings.
Over the past six years, Getty has been engaged in a project to transform and unify its complex digital infrastructure for cultural heritage information. One of the project’s core goals was to provide validation of the impact and value of the use of linked data throughout this process. With museum, archival, media, and vocabularies in production and others underway, this sessions shares some of the practical implications (and pitfalls) of this work—particularly as it relates to interoperability, discovery, staffing, stakeholder engagement, and complexity management. The session will also share examples of how other organizations can streamline their own, similar work going forward.
The LOD Gateway: Open Source Infrastructure for Linked DataDavid Newbury
Presented at the CIDOC conference in Mexico City, 2023, this talk provides a walkthrough of the digital infrastructure behind the LOD Gateway, a critical part of Getty's digital API infrastructure.
It discusses the difference between graphs, documents, and how both are important for different use cases.
As part of MuseWeb 2023 in Washington, DC, this presentation walks through the basics of Linked Data, and then discusses the six levels of implementation of Linked Data, using the Getty's work as examples.
USE ME: progressive integration of IIIF with new software services at the GettyDavid Newbury
Two years into the launch of an institution-wide IIIF delivery system and the related ETL pipelines to generate IIIF master images and manifests, two ongoing challenges have been unfolding in the broader Getty Digital development plans: making use of these IIIF services by default, and consequently, improving those services in a continuous fashion.
This 20-minute presentation will offer an overview of the integration of various Getty software development projects with the existing IIIF and Linked Open Data infrastructure, including our public LOD access endpoints, data analysis and annotation projects, and public-facing websites and research tools. The goal is to highlight how Getty Digital has come past the initial investment of building infrastructure and beginning to reap the long-term benefits of such investment.
IIIF Across Platforms | IIIF Community Call, January 2021David Newbury
David Newbury, Head of Software at Getty, presents on Getty's work using the IIIF APIs to provide access to images from the Ed Ruscha Streets of Los Angeles Archive in multiple interfaces, meeting the needs of different audiences, and shares lessons learned in the development of both projects:
https://12sunsets.getty.edu and https://www.getty.edu/research/collections
Thinking through the implications of treating the IIIF canvas as a resource in itself, not just as an internal building block of a IIIF Manifest.
Presented at the Fall 2020 IIIF Working group on December 2nd.
Have you ever wished that IIIF was just a little bit MORE complicated?
While the IIIF specifications provide lots of clever features, sometimes you need to do something outside what the specifications describe. Maybe that's adding "date modified" or "date created" to your Manifests, maybe it's doing palette analysis of your Canvases, or maybe you need to add structured metadata about the objects represented in the image.
These all seem like they should be possible in IIIF, but it can be hard to figure out the correct way to add this kind of custom information using IIIF, particularly if you think other people might want to do the same thing. In the upcoming IIIF 3.0 specifications, we've clarified the various ways that you can extend IIIF.
In this presentation, I'll walk through the extension mechanisms in IIIF: services, extensions, seeAlso, and rendering links. I'll provide examples and guidelines, as well as explain some of the reasoning behind the various mechanisms.
NDSR Learning Enrichment: Data Models and Linked DataDavid Newbury
Webinar, Feb. 20, 2018. David Newbury discusses how data is modeled and presented in memory institutions. He talks about his experiences with Art Tracks, Linked Art, the American Art collaboration, and other projects, discussing how those experiences helped him better understand data modeling and how we can represent objects.
With apologies to Clifford Simak, time is *never* the simplest thing. One of the most common issues with dealing with cultural data is time. The humanities are almost always interested in that which takes place over time, but the way that humanists think about time and dates is fuzzy—full of imprecision, approximations, and generalities.
Unfortunately, while humans are fully capable of dealing with that ambiguity, computers are not: existing software needs a level of temporal precision that is impractical for cultural data. To bridge this gap, we need to precisely express the fuzziness of our dates. Over the past decades, tools and techniques such as Allen's Interval algebra, the Library of Congress's Extended Date Time Format, and the CIDOC CRM's time-span model have been developed to help model this fuzziness, but they are often so complex as to appear unusable by both humanists and technologists.
In this paper, I will present a technique developed as part of the Art Tracks project at the Carnegie Museum of Art for converting natural language statements such as "sometime after the 1970s" or "until at least the 17th century" into precisely defined expressions of temporal fuzziness usable by computers, technologists, and humanists alike.
Art Tracks: From Provenance to Structured DataDavid Newbury
This keynote presentation was given by David Newbury and Louise Lippincott as part of the Smithsonian Provenance Research Institute's PREP program at the Metropolitan Museum of Art in New York on February 7th, 2017
This is an Ignite talk given at MCN 2016 on my views and opinions around Linked Data in the museum field.
This talk was recorded and is available on YouTube: https://www.youtube.com/watch?v=0RysOdsZtf8
These are slides for a workshop on D3 given at the Studio for Creative Inquiry at Carnegie Mellon University on October 28th, 2016.
For more context, see http://d3.workergnome.com
This presentation was given as part of the 2016 Digital Provenance Symposium at the Carnegie Museum of Art on October 14th, 2016.
It describes the current state of the technology of the Art Tracks project, a digital standard for museum provenance in Linked Data.
Using Linked Data: American Art Collaborative, Oct. 3, 2016David Newbury
Linked Data is a interesting topic in museums, but how do we actually use it? This talk profiles several ways the Carnegie Museum of Art uses Linked Data, and talks about when and where Linked Data can be useful.
Data 101: Making Charts from SpreadsheetsDavid Newbury
The fundamental tools of data visualization are the spreadsheet and the chart. Modern spreadsheet software like Microsoft Excel or Google Sheets make generating charts easy, but there are so many types of charts and ways to configure them that it can be difficult to know how to get started, or how to choose the best chart to help tell your story. In this workshop, we will explore the types of charts available, describe the differences between them, when each is appropriate, and work through creating and customizing a chart to help tell a specific story.
This workshop is designed for people with basic spreadsheet skills, but no previous experience with making charts is required. If you’re comfortable reading and entering data using spreadsheet software like Excel or Google Sheets, you are ready for this workshop!
Given August 30th at the East Liberty Branch of the Pittsburgh Public Library
APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024APNIC
Ellisha Heppner, Grant Management Lead, presented an update on APNIC Foundation to the PNG DNS Forum held from 6 to 10 May, 2024 in Port Moresby, Papua New Guinea.
Italy Agriculture Equipment Market Outlook to 2027harveenkaur52
Agriculture and Animal Care
Ken Research has an expertise in Agriculture and Animal Care sector and offer vast collection of information related to all major aspects such as Agriculture equipment, Crop Protection, Seed, Agriculture Chemical, Fertilizers, Protected Cultivators, Palm Oil, Hybrid Seed, Animal Feed additives and many more.
Our continuous study and findings in agriculture sector provide better insights to companies dealing with related product and services, government and agriculture associations, researchers and students to well understand the present and expected scenario.
Our Animal care category provides solutions on Animal Healthcare and related products and services, including, animal feed additives, vaccination
1.Wireless Communication System_Wireless communication is a broad term that i...JeyaPerumal1
Wireless communication involves the transmission of information over a distance without the help of wires, cables or any other forms of electrical conductors.
Wireless communication is a broad term that incorporates all procedures and forms of connecting and communicating between two or more devices using a wireless signal through wireless communication technologies and devices.
Features of Wireless Communication
The evolution of wireless technology has brought many advancements with its effective features.
The transmitted distance can be anywhere between a few meters (for example, a television's remote control) and thousands of kilometers (for example, radio communication).
Wireless communication can be used for cellular telephony, wireless access to the internet, wireless home networking, and so on.
Meet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdfFlorence Consulting
Quattordicesimo Meetup di Milano, tenutosi a Milano il 23 Maggio 2024 dalle ore 17:00 alle ore 18:30 in presenza e da remoto.
Abbiamo parlato di come Axpo Italia S.p.A. ha ridotto il technical debt migrando le proprie APIs da Mule 3.9 a Mule 4.4 passando anche da on-premises a CloudHub 1.0.
Understanding User Behavior with Google Analytics.pdfSEO Article Boost
Unlocking the full potential of Google Analytics is crucial for understanding and optimizing your website’s performance. This guide dives deep into the essential aspects of Google Analytics, from analyzing traffic sources to understanding user demographics and tracking user engagement.
Traffic Sources Analysis:
Discover where your website traffic originates. By examining the Acquisition section, you can identify whether visitors come from organic search, paid campaigns, direct visits, social media, or referral links. This knowledge helps in refining marketing strategies and optimizing resource allocation.
User Demographics Insights:
Gain a comprehensive view of your audience by exploring demographic data in the Audience section. Understand age, gender, and interests to tailor your marketing strategies effectively. Leverage this information to create personalized content and improve user engagement and conversion rates.
Tracking User Engagement:
Learn how to measure user interaction with your site through key metrics like bounce rate, average session duration, and pages per session. Enhance user experience by analyzing engagement metrics and implementing strategies to keep visitors engaged.
Conversion Rate Optimization:
Understand the importance of conversion rates and how to track them using Google Analytics. Set up Goals, analyze conversion funnels, segment your audience, and employ A/B testing to optimize your website for higher conversions. Utilize ecommerce tracking and multi-channel funnels for a detailed view of your sales performance and marketing channel contributions.
Custom Reports and Dashboards:
Create custom reports and dashboards to visualize and interpret data relevant to your business goals. Use advanced filters, segments, and visualization options to gain deeper insights. Incorporate custom dimensions and metrics for tailored data analysis. Integrate external data sources to enrich your analytics and make well-informed decisions.
This guide is designed to help you harness the power of Google Analytics for making data-driven decisions that enhance website performance and achieve your digital marketing objectives. Whether you are looking to improve SEO, refine your social media strategy, or boost conversion rates, understanding and utilizing Google Analytics is essential for your success.
2. Who am I?
Lead Developer, Art Tracks, Carnegie Museums.
Ex-Lead Developer, American Eagle Outfitters.
Ex-Lead Developer, Iontank.
Dynamic websites for artists.
David Newbury — @workergnome 2
3. Who am I?
Lead Developer, Art Tracks, Carnegie Museums.
Ex-Lead Developer, American Eagle Outfitters.
Ex-Lead Developer, Iontank.
11 years of freelance web development.
18 years as a professional developer.
Dynamic websites for artists.
David Newbury — @workergnome 3
4. I can make a
real website.
Dynamic websites for artists.
David Newbury — @workergnome 4
5. Who am I?
I have BA in film production.
I build art installations.
I make robots that make cookies.
Dynamic websites for artists.
David Newbury — @workergnome 5
6. Who am I?
I have BA in film production.
I build art installations.
I make robots that make cookies.
I'm an artist.
Dynamic websites for artists.
David Newbury — @workergnome 6
7. This is not how to
make a real website.
Dynamic websites for artists.
David Newbury — @workergnome 7
8. This is not how to
make a real website.
This is how to
fake a website.
Dynamic websites for artists.
David Newbury — @workergnome 8
9. This is not how to
make a real website.
This is how to
fake a website.
Ya know, for art.
Dynamic websites for artists.
David Newbury — @workergnome 9
10. What we're going to do:
Teach you the fast, dirty, mostly free way
to build a website that can save user's data.
Dynamic websites for artists.
David Newbury — @workergnome 10
11. What we're going to do:
Show you how to:
—Use Sinatra
Dynamic websites for artists.
David Newbury — @workergnome 11
12. What we're going to do:
Show you how to:
—Use Sinatra
—Set up a local server
Dynamic websites for artists.
David Newbury — @workergnome 12
13. What we're going to do:
Show you how to:
—Use Sinatra
—Set up a local server
—Deploy to Heroku
Dynamic websites for artists.
David Newbury — @workergnome 13
14. What we're going to do:
Show you how to:
—Use Sinatra
—Set up a local server
—Deploy to Heroku
—Use Redis to store data
Dynamic websites for artists.
David Newbury — @workergnome 14
15. What we're NOT going to do:
—Learn HTML / CSS / Javascript
Dynamic websites for artists.
David Newbury — @workergnome 15
16. What we're NOT going to do:
—Learn HTML / CSS / Javascript
—Talk about relational databases
Dynamic websites for artists.
David Newbury — @workergnome 16
17. What we're NOT going to do:
—Learn HTML / CSS / Javascript
—Talk about relational databases
—Talk about security
Dynamic websites for artists.
David Newbury — @workergnome 17
18. What we're NOT going to do:
—Learn HTML / CSS / Javascript
—Talk about relational databases
—Talk about security
—Save personal, identifying information
Dynamic websites for artists.
David Newbury — @workergnome 18
19. Read along with me.
The code:
http://github.com/workergnome/dynamic-workshop
The slides:
http://www.slideshare.net/workergnome
Dynamic websites for artists.
David Newbury — @workergnome 19
21. Get ready.
1. Get a dropbox account.
http://www.dropbox.com
2. Get a heroku account.
http://www.heroku.com
3. Download Sublime Text 3 (optional)
http://www.sublimetext.com/3
Dynamic websites for artists.
David Newbury — @workergnome 21
22. Get set.
1. Install Ruby
* OSX 10.9/10.10 - !
* Old OSX - http://brew.sh
* Windows - http://rubyinstaller.org
2. Install Bundler
gem install bundler
Dynamic websites for artists.
David Newbury — @workergnome 22
23. Go.
1. Create a Heroku app
2. Link it to Dropbox
3. Open the app directory in Sublime Text
Dynamic websites for artists.
David Newbury — @workergnome 23
28. In the terminal:
cd ~/Dropbox/Apps/Heroku/[your_app_name]
bundle install
bundle exec rackup
In a browser:
http://localhost:9292
Dynamic websites for artists.
David Newbury — @workergnome 28
29. Blammo.
You now have a locally deployed server, hosting your
content.
Dynamic websites for artists.
David Newbury — @workergnome 29
30. Blammo.
You now have a locally deployed server, hosting your
content.
control-c will quit it.
Dynamic websites for artists.
David Newbury — @workergnome 30
31. Potential Problems:
on Windows, this error:
SSLv3 read server certificate B: certificate verify failed
Can be fixed with this:
http://git.io/AEqB
Dynamic websites for artists.
David Newbury — @workergnome 31
32. Deploy to the web.
This is the hard part.
Dynamic websites for artists.
David Newbury — @workergnome 32
33. Deploy to the web.
Go to:
https://dashboard.heroku.com/apps
Dynamic websites for artists.
David Newbury — @workergnome 33
34. Deploy to the web.
Click on your app.
Dynamic websites for artists.
David Newbury — @workergnome 34
35. Deploy to the web.
Click on .
Dynamic websites for artists.
David Newbury — @workergnome 35
36. Deploy to the web.
Type a message:
Dynamic websites for artists.
David Newbury — @workergnome 36
37. Deploy to the web.
Click
Dynamic websites for artists.
David Newbury — @workergnome 37
38. Deploy to the web.
Go to:
https://[your-app-name].herokuapp.com
Dynamic websites for artists.
David Newbury — @workergnome 38
39. Blammo.You're on the internet.
Dynamic websites for artists.
David Newbury — @workergnome 39
40. A quiet round of applause
for you.
Dynamic websites for artists.
David Newbury — @workergnome 40
41. A quiet round of applause
for you.
! ! ! ! ! ! ! ! !
Dynamic websites for artists.
David Newbury — @workergnome 41
46. Explanations.
Gemfile
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
A Gemfile lists dependencies.
External libraries that you'd like to use.
In ruby, these are called Gems.
Gemfiles are managed by Bundler.
Dynamic websites for artists.
David Newbury — @workergnome 46
48. Explanations.
Bundler
Bundler makes sure that the dependencies of your
dependencies don't conflict.
Dynamic websites for artists.
David Newbury — @workergnome 48
50. Explanations.
We want sinatra. sinatra wants rack.
sinatra also wants rack-protection.
rack-protection also wants rack.
We only want one copy of rack.
Dynamic websites for artists.
David Newbury — @workergnome 50
51. Don't worry about
all of this.
Dynamic websites for artists.
David Newbury — @workergnome 51
52. Don't worry about
all of this.
There's only 2 things you need to know:
Dynamic websites for artists.
David Newbury — @workergnome 52
53. #1Heroku uses the Gemfile to setup the server for you.
Dynamic websites for artists.
David Newbury — @workergnome 53
54. #2If you want to use a library, add it to Gemfile.
Dynamic websites for artists.
David Newbury — @workergnome 54
60. Ignore this file.
It's a Rack configuration file that handles the
interface between the webserver and the
framework while allowing middleware applications.
For more information, go to http://rack.github.io.
Dynamic websites for artists.
David Newbury — @workergnome 60
61. Ignore this file.
As long as it has the line
require './hello'
and you have a file named hello.rb
you're !
Dynamic websites for artists.
David Newbury — @workergnome 61
67. Explanations.
Hello.rb:
get '/' do
"Hello World!"
end
when there's a GET request to /,
return the string "Hello World!"
Dynamic websites for artists.
David Newbury — @workergnome 67
68. Two notes about Ruby:
1. Ruby uses do...end instead of {...}
2. Ruby returns the last line by default.
get '/' do
"Hello World!"
end
in Javascript:
function getIndex() {
return "Hello World!";
}
Dynamic websites for artists.
David Newbury — @workergnome 68
69. Let's make this more folksy.
in the terminal:
bundle exec rackup
in hello.rb:
require 'sinatra'
get '/' do
"Howdy, World!"
end
Dynamic websites for artists.
David Newbury — @workergnome 69
71. What happened?
The server is still running the original code.
Dynamic websites for artists.
David Newbury — @workergnome 71
72. What happened?
The server is still running the original code.
We could fix this by quitting and restarting.
Dynamic websites for artists.
David Newbury — @workergnome 72
73. What happened?
The server is still running the original code.
We could fix this by quitting and restarting.
BOOOORING.
Dynamic websites for artists.
David Newbury — @workergnome 73
74. Let's install a library.
Gemfile:
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
Dynamic websites for artists.
David Newbury — @workergnome 74
75. Let's install a library.
Gemfile:
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
gem 'sinatra-contrib'
Dynamic websites for artists.
David Newbury — @workergnome 75
76. Let's install a library.
Gemfile:
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
gem 'sinatra-contrib'
in the terminal:
bundle install
Dynamic websites for artists.
David Newbury — @workergnome 76
77. Let's install a library.
hello.rb:
require 'sinatra'
get '/' do
str = "Howdy, World!"
end
Dynamic websites for artists.
David Newbury — @workergnome 77
78. Let's install a library.
hello.rb:
require 'sinatra'
require "sinatra/reloader"
get '/' do
str = "Howdy, World!"
end
Dynamic websites for artists.
David Newbury — @workergnome 78
79. Let's install a library.
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
str = "Howdy, World!"
end
Dynamic websites for artists.
David Newbury — @workergnome 79
80. Let's install a library.
in the terminal:
bundle exec rackup
and http://localhost:9292
Dynamic websites for artists.
David Newbury — @workergnome 80
82. Let's make this MORE folksy.
hello.rb:
require 'sinatra'
get '/' do
"Howdy, world!"
end
Dynamic websites for artists.
David Newbury — @workergnome 82
83. Let's make this MORE folksy.
hello.rb:
require 'sinatra'
get '/' do
"Howdy, all y'all."
end
Dynamic websites for artists.
David Newbury — @workergnome 83
85. Another quiet round of
applause for you.
Dynamic websites for artists.
David Newbury — @workergnome 85
86. Another quiet round of
applause for you.
! ! ! ! ! ! ! ! !
Dynamic websites for artists.
David Newbury — @workergnome 86
87. Plain text is boring.
Dynamic websites for artists.
David Newbury — @workergnome 87
88. Plain text is boring.
(Says the man with hevetica slides)
Dynamic websites for artists.
David Newbury — @workergnome 88
89. Create a public folder
within your application's folder
and put an image in it.
Dynamic websites for artists.
David Newbury — @workergnome 89
90. Create a public folder
within your application's folder
and put an image in it.
Dynamic websites for artists.
David Newbury — @workergnome 90
91. Create a public folder
within your application's folder
and put an image in it.
Dynamic websites for artists.
David Newbury — @workergnome 91
92. Let's make this EVEN MORE folksy.
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
"Howdy, all y'all."
end
Dynamic websites for artists.
David Newbury — @workergnome 92
93. Let's make this EVEN MORE folksy.
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
"Howdy, all y'all. <br> <img src='cowboy.png'>"
end
Dynamic websites for artists.
David Newbury — @workergnome 93
95. And if we want another URL?
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
"Howdy, all y'all. <br> <img src='cowboy.png'>"
end
get '/goodbye' do
"So long, partner."
end
Dynamic websites for artists.
David Newbury — @workergnome 95
99. Move our pages out of the code:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
"Howdy, all y'all. <br> <img src='cowboy.png'>"
end
get '/goodbye' do
"So long, partner."
end
Dynamic websites for artists.
David Newbury — @workergnome 99
100. Move our pages out of the code:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
erb :index
end
get '/goodbye' do
erb :goodbye
end
Dynamic websites for artists.
David Newbury — @workergnome 100
101. And add them to a views folder:
views/index.erb:
<p>
Howdy, all y'all. <br>
<img src='cowboy.png'>
</p>
views/goodbye.erb:
<p>So long, partner.</p>
Dynamic websites for artists.
David Newbury — @workergnome 101
102. Let's make it dynamic!
Dynamic websites for artists.
David Newbury — @workergnome 102
114. Sometimes we want
statefullness.
We want a session.
Really, we just want a cookie.
Dynamic websites for artists.
David Newbury — @workergnome 114
115. Sometimes we want
statefullness.
We want a session.
Really, we just want a cookie.
!
Dynamic websites for artists.
David Newbury — @workergnome 115
117. Cookies let the
client and the server talk.
Dynamic websites for artists.
David Newbury — @workergnome 117
118. Cookies let the
client and the server talk.
!
Dynamic websites for artists.
David Newbury — @workergnome 118
119. For the client, we need jQuery...
layout.erb:
<!DOCTYPE html>
<html>
<head>
<title>Cowboys</title>
<script src='//code.jquery.com/jquery-1.11.2.min.js'></script>
</head>
<body>
<%= yield %>
</body>
</html>
Dynamic websites for artists.
David Newbury — @workergnome 119
120. We also need jQuery Cookie.
Download this:
http://git.io/AEq1
and save it as this:
/public/jquery.cookie.js
Dynamic websites for artists.
David Newbury — @workergnome 120
121. ...and add it to the layout.
layout.erb:
<!DOCTYPE html>
<html>
<head>
<title>Cowboys</title>
<script src='//code.jquery.com/jquery-1.11.2.min.js'></script>
<script src='/jquery.cookie.js'></script>
</head>
<body>
<%= yield %>
</body>
</html>
Dynamic websites for artists.
David Newbury — @workergnome 121
122. And our own javascript file
layout.erb:
<!DOCTYPE html>
<html>
<head>
<title>Cowboys</title>
<script src='//code.jquery.com/jquery-1.11.2.min.js'></script>
<script src='/jquery.cookie.js'></script>
<script src='/application.js'></script>
</head>
<body>
<%= yield %>
</body>
</html>
Dynamic websites for artists.
David Newbury — @workergnome 122
123. Which we'll stick in /public
public/application.js:
$(function() {
$.cookie('you_seen_me', true);
});
Dynamic websites for artists.
David Newbury — @workergnome 123
124. For the server, we need "sinatra/cookies"
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
get '/' do
erb :index
end
get '/goodbye' do
erb :goodbye
end
Dynamic websites for artists.
David Newbury — @workergnome 124
125. For the server, we need "sinatra/cookies"
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
require "sinatra/cookies"
get '/' do
erb :index
end
get '/goodbye' do
erb :goodbye
end
Dynamic websites for artists.
David Newbury — @workergnome 125
126. For the server, we need "sinatra/cookies"
hello.rb:
require 'sinatra'
require "sinatra/reloader" if development?
require "sinatra/cookies"
get '/' do
@you_seen_me = cookies[:you_seen_me]
erb :index
end
get '/goodbye' do
erb :goodbye
end
Dynamic websites for artists.
David Newbury — @workergnome 126
127. An aside: @variables
@something is a Ruby instance variable.
They exist in the ruby method and the view.
Dynamic websites for artists.
David Newbury — @workergnome 127
128. hello.rb:
get '/' do
@you_seen_me = cookies[:you_seen_me]
erb :index
end
index.erb:
<p>
Howdy, all y'all. <br>
<% if @you_seen_me %> Welcome back! <% end %>
<br>
<img src='cowboy.png'>
</p>
Dynamic websites for artists.
David Newbury — @workergnome 128
129. First time you come to the site:
Dynamic websites for artists.
David Newbury — @workergnome 129
130. Second time you come to the site:
Dynamic websites for artists.
David Newbury — @workergnome 130
131. hello.rb:
get '/' do
@you_seen_me = cookies[:you_seen_me]
erb :index
end
index.erb:
<p>
Howdy, all y'all. <br>
<% if @you_seen_me %> Welcome back! <% end %>
<br>
<img src='cowboy.png'>
</p>
application.js:
$(function() {
$.cookie('you_seen_me', true);
});
Dynamic websites for artists.
David Newbury — @workergnome 131
132. That's a dynamic website
that saves user data.
Dynamic websites for artists.
David Newbury — @workergnome 132
133. Let's push this to the internet.
Click
Dynamic websites for artists.
David Newbury — @workergnome 133
139. Redis is a Key/Value Store.
Dynamic websites for artists.
David Newbury — @workergnome 139
140. Redis is a Key/Value Store.
@redis.set("key","value") #saves the data
Dynamic websites for artists.
David Newbury — @workergnome 140
141. Redis is a Key/Value Store.
@redis.set("key","value") #saves the data
val = @redis.get("key") #val = "value"
Dynamic websites for artists.
David Newbury — @workergnome 141
142. Redis is a Key/Value Store.
@redis.set("key","value") #saves the data
val = @redis.get("key") #val = "value"
That's it.
Dynamic websites for artists.
David Newbury — @workergnome 142
143. Redis is a Key/Value Store.
$redis.set("key","value") #saves the data
val = $redis.get("key") #val = "value"
That's it.
(Not really. But pretend with me.)
Dynamic websites for artists.
David Newbury — @workergnome 143
144. Installing Redis on your computer
OSX:
brew install redis
Dynamic websites for artists.
David Newbury — @workergnome 144
145. Installing Redis on your computer
OSX:
brew install redis
Windows:
Dynamic websites for artists.
David Newbury — @workergnome 145
146. Installing Redis on your computer
OSX:
brew install redis
Windows:
http://git.io/AEq7
Dynamic websites for artists.
David Newbury — @workergnome 146
147. Installing Redis on Heroku
https://addons.heroku.com/rediscloud
Dynamic websites for artists.
David Newbury — @workergnome 147
148. Installing Redis on Heroku
Install it to your app.
Dynamic websites for artists.
David Newbury — @workergnome 148
149. Installing Redis on Heroku
Install it to your app.
Dynamic websites for artists.
David Newbury — @workergnome 149
150. Let's install a library.
Gemfile:
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
gem 'sinatra-contrib'
Dynamic websites for artists.
David Newbury — @workergnome 150
151. Let's install a library.
Gemfile:
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
gem 'sinatra-contrib'
gem 'redis'
Dynamic websites for artists.
David Newbury — @workergnome 151
152. Let's install a library.
Gemfile:
source 'https://rubygems.org'
ruby '2.1.2'
gem 'sinatra'
gem 'sinatra-contrib'
gem 'redis'
in the terminal:
bundle install
Dynamic websites for artists.
David Newbury — @workergnome 152
154. hello.rb:
require "sinatra/cookies"
require 'redis'
configure do
if development?
uri = URI.parse("redis://localhost:6379")
else
uri = URI.parse(ENV["REDISCLOUD_URL"])
end
$redis = Redis.new(host: uri.host,
port: uri.port,
password: uri.password)
end
Dynamic websites for artists.
David Newbury — @workergnome 154
155. hello.rb:
get '/' do
@you_seen_me = cookies[:you_seen_me]
erb :index
end
Dynamic websites for artists.
David Newbury — @workergnome 155
156. hello.rb:
get '/' do
@visitors = $redis.get( 'number_of_visitors' ).to_i
@you_seen_me = cookies[:you_seen_me]
erb :index
end
Dynamic websites for artists.
David Newbury — @workergnome 156
157. hello.rb:
get '/' do
@visitors = $redis.get( 'number_of_visitors' ).to_i
$redis.set( 'number_of_visitors', (@visitors + 1).to_s)
@you_seen_me = cookies[:you_seen_me]
erb :index
end
Dynamic websites for artists.
David Newbury — @workergnome 157
158. index.erb:
<p>
Howdy, all y'all. <br>
<% if @you_seen_me %> Welcome back! <% end %>
<br>
<img src='cowboy.png'>
</p>
Dynamic websites for artists.
David Newbury — @workergnome 158
159. index.erb:
<p>
Howdy, all y'all. <br>
<% if @you_seen_me %> Welcome back! <% end %>
<br>You're visitor <%= @visitors %>!
<br>
<img src='cowboy.png'>
</p>
Dynamic websites for artists.
David Newbury — @workergnome 159
160. Start up Redis:
on OSX:
in a NEW terminal window:
redis-server /usr/local/etc/redis.conf
on Windows:
open the redis-srv.exe file you downloaded.
Dynamic websites for artists.
David Newbury — @workergnome 160
161. in the OLD terminal window:
bundle exec rackup
Dynamic websites for artists.
David Newbury — @workergnome 161
170. Let's create a form.
index.erb:
<img src='cowboy.png'>
</p>
<!--...-->
Dynamic websites for artists.
David Newbury — @workergnome 170
171. Let's create a form.
index.erb:
<img src='cowboy.png'>
</p>
<p>Let's play the classic Cowboy game Finger Guns!</p>
<p>Choose how many fingers to show, and you'll fire at the last person to play.</p>
<p>If the total number of fingers is odd, you win!</p>
<form action="/fire_at_will" method="post">
How Many Fingers?
<input id="fingers" type="text" name="fingers">
<input id='kaboom' type="submit" value="Kaboom">
</form>
Dynamic websites for artists.
David Newbury — @workergnome 171
174. Our post route.
hello.rb:
get '/goodbye' do
erb :goodbye
end
Dynamic websites for artists.
David Newbury — @workergnome 174
175. Our post route. rural, of course.
hello.rb:
get '/goodbye' do
erb :goodbye
end
post '/fire_at_will' do
params[:fingers]
end
Dynamic websites for artists.
David Newbury — @workergnome 175
178. We can do better.
hello.rb:
post '/fire_at_will' do
fingers = params[:fingers].to_i
end
Dynamic websites for artists.
David Newbury — @workergnome 178
179. We can do better.
hello.rb:
post '/fire_at_will' do
fingers = params[:fingers].to_i
last_fingers = $redis.get('last_fingers').to_i
end
Dynamic websites for artists.
David Newbury — @workergnome 179
180. We can do better.
hello.rb:
post '/fire_at_will' do
fingers = params[:fingers].to_i
last_fingers = $redis.get('last_fingers').to_i
$redis.set('last_fingers',fingers)
end
Dynamic websites for artists.
David Newbury — @workergnome 180
181. We can do better.
hello.rb:
post '/fire_at_will' do
fingers = params[:fingers].to_i
last_fingers = $redis.get('last_fingers').to_i
$redis.set('last_fingers',fingers)
if (fingers + last_fingers).odd?
"you win!"
else
"you lose!"
end
end
Dynamic websites for artists.
David Newbury — @workergnome 181
184. We've just made a game.
Dynamic websites for artists.
David Newbury — @workergnome 184
185. We've just made a game.
A terrible, terrible game.
Dynamic websites for artists.
David Newbury — @workergnome 185
186. We've just made a game.
A terrible, terrible game.
How could we make it better?
Dynamic websites for artists.
David Newbury — @workergnome 186
187. We've just made a game.
A terrible, terrible game.
How could we make it better?
Analytics.
Dynamic websites for artists.
David Newbury — @workergnome 187
188. hello.rb:
if (fingers + last_fingers).odd?
"you win!"
else
"you lose!"
end
Dynamic websites for artists.
David Newbury — @workergnome 188
189. hello.rb:
if (fingers + last_fingers).odd?
@result = "you win!"
else
@result = "you lose!"
end
erb :score
Dynamic websites for artists.
David Newbury — @workergnome 189
190. hello.rb:
if (fingers + last_fingers).odd?
@result = "you win!"
else
@result = "you lose!"
end
erb :score
views/score.erb:
<p><%= @result %></p>
<a href="/">Play again?</a>
Dynamic websites for artists.
David Newbury — @workergnome 190
198. This:
$redis.incr("wins")
Is the same as this:
wins = $redis.get("wins")
wins = wins + 1
$redis.set("wins", wins)
Dynamic websites for artists.
David Newbury — @workergnome 198
199. This:
$redis.incr("wins")
Is the same as this:
wins = $redis.get("wins")
wins = wins + 1
$redis.set("wins", wins)
Just shorter.
Dynamic websites for artists.
David Newbury — @workergnome 199
200. Let's add some math.
hello.rb:
if (fingers + last_fingers).odd?
@result = "you win!"
$redis.incr("wins")
else
@result = "you lose!"
$redis.incr("losses")
end
@wins = $redis.get('wins')
@losses = $redis.get('losses')
erb :score
Dynamic websites for artists.
David Newbury — @workergnome 200
215. CSS
AJAX
User counts
Personal scores
Cheat detection
Completely new experiences
Go out and make cool things.
Dynamic websites for artists.
David Newbury — @workergnome 215
216. CSS
AJAX
User counts
Personal scores
Cheat detection
Completely new experiences
Go out and make cool things.
(And show them to me.)
Dynamic websites for artists.
David Newbury — @workergnome 216
217. David Newbury
@workergnome
The code: http://github.com/workergnome/dynamic-
workshop
The slides: http://www.slideshare.net/workergnome/
dynamic-websites-for-artists
Dynamic websites for artists.
David Newbury — @workergnome 217
218. David Newbury
@workergnome
The code: http://github.com/workergnome/dynamic-
workshop
The slides: http://www.slideshare.net/workergnome/
dynamic-websites-for-artists
Thank you.
Dynamic websites for artists.
David Newbury — @workergnome 218