and everyone the locations down there
okay
you're not here for location data and
your plate you're in the wrong place
he's socially awkward right right so
we're gonna talk a little bit about
background and requirements of a project
we did with the Chicago Park District is
this presentation is really going to be
a case study just so we can show some
practical examples we're going to talk
about modules we use for contributed and
custom modules and then we're going to
talk about importing data from different
kinds of sources processing the data and
formatting it for display and this
displays we used and then making the
location data available for other places
to consume and then problem some
questions we will hand out the EM so so
I guess I'm first up yeah
my name's Matthew Mesmer I'm the
director of international business at
General in Tokyo Japan that's a fancy
way to say that I'm like the lead Drupal
developer over there we partnered with
Bob's company clarity on this project
with Chicago Park District
yes named Robert shelf most people call
me Bob I mean touching my cousin's call
me Bobby I've been drilling for over
nine years started out just as the kind
of thing to use that I didn't really
understand and into a hobby and now
that's what I do
yeah so this project that we got into
this location data with is the Chicago
Park District's new website they have
facility locations within it every
statue fountain Fieldhouse is a location
so we had a lot of data photos ours
everything pertaining to a location the
park district's pretty huge it's the
whole city 26 miles 23 swimming beaches
just so much stuff and they have events
and programs for every season and there
are thousands of those as well and they
all take place at locations so it's not
just this location data is going to be
on a map somewhere out of page it's used
by things like programs and events if
you wanted to check in a South Chicago
Park District comm they have lots of
page views and the popular content aisle
includes location data programs head
locations the practice themselves and
the events ends even schedules like for
pool schedules when you can register for
for swimming they're all at a pool so
it's highly location based the crank
requirements we had
we're to import data from multiple
sources because the program data sources
was an unsupported soap service it's
kind of like an end-of-life and it might
not have even ever been something that
was for the general public so we kind of
had this dead and we had to work with
that we couldn't call up and say can you
change this voice hey there England we
also had to add supplemental information
like the hours and descriptions and
photos from the old website and we used
CSV files that were exported from mobile
websites database to match up with the
basic parts of data that we had an
dependent we also had to do daily
updates for those programs and events
and we kind of turned migrated into a
daily an import we'll have those new
programs and events that's going to
match up with the location data then
after had all that in the integer ball
it just like this is the parts of
facilities so people can find the ones
that are by name or closest to them then
the maps for those lists either side by
side or just maps on the department
cells with all the facilities within the
park and then of course I'm a detail
pages yet
third requirement was they have a mobile
app for events called my shy parks and
you can check-in at parks for points and
find events at the parks with that app
so we had to supply feeds for that app
to consume so we do a lot with this
location data and it was very
challenging fun and interesting and we
might one mention that for various
reasons the app the phone app was unable
to be updated to match any changes in
the RESTful API so the REST API that we
had to create for the new Drupal 8 site
needed to match exactly like character
for character the formatting of the old
API so we had constraints on both ends
[Music]
so modules that we used and turned into
our own geolocation and geo coder
migrated chosen Mike grade class for our
crazy imports and then ultimate crime to
do those daily reports of course they
used the core modules migrate and
restful web services and we made quite a
bit of a number of custom modules one
mainland for the imports have done some
sub modules so we could run a craft for
each and then custom blocks permit
displays we had a couple different
badges plays that were required custom
field for matters we're in a module as
well and the feeds so importing data the
dynamic we have dynamic and Static data
that processing is the next step for
turning that Mary into the proper or
getting it mapped into Drupal formatting
make sure that it's able to put into
that field this gets kind of picky
so dynamic sources we for this project
soap service on the rest services JSON
thieves any other service dynamic
service static service documents usually
anything that you import from a file so
the dynamic sources you often have
little or no control over the data that
you're receiving like we were talking
about sometimes you can get a chance to
you to your needs but it's not often
migrate met drupal migrate module
usually assumes that your mapping ones
are in fields but you may need to
combine five fields from a source into
one address field or the other way
around
so also dynamic sources sometimes they
go down you problems at times depending
on your account status so you have to
make sure that you're paying attention
and everything is always up dad is
always current though if you have a
dynamic source and the processes are
automated so it's awesome but the
challenges are getting the correct data
and getting a properly formatted
so this is an example of the my great
source plugin that we wrote for the soap
call so in the the migrant module
provides a number of source plugins a
lot around about surrounding like
database calls to old Drupal websites or
like importing like CSV files but for
our purpose we needed to extend the one
of the source plugins to make it work
for the Chicago Park District no soap
service we were needing to use so this
makes a call to the soap service and
retrieves the results that we're later
able to parse through to add the data
into Drupal and mark delay back there
was very instrumental in helping us get
this going
thanks a lot just wanted to give him the
proper credit there so static sources
are good because you have complete
control over your data you can preform
at all your addresses and text on amis
and everything to what the duplicates
need and they're all once a month if you
desire they can handle large imports
because you're not using me over the
internet connection we're just having a
challenge of that is you might have to
do an export from your vendor every time
you do a different iteration of your dev
site or like a couple hours before going
away to get that data to be grant so in
in my experience I've found that having
the static sources like a like a CSV
file or an Excel spreadsheet that you're
importing data from this is really good
for like a one-time import where you're
like migrating a site and you just need
to get the old data in once and you're
not going to run it again whereas if you
go to the trouble of setting up the the
soap call or importing a JSON feed
that's really great if you need to run
that on like a daily basis to keep
getting the new information
and that's beautiful yes so this is an
example of just like a CSV or Excel
spreadsheet where you just got all your
your data in there you've got like a key
value on the left and you got your like
address city state and then this just
gets parsed and can be added into Drupal
and the key value is a little weird but
that's because a lot of the park names
of the X of the park name column they
had weird characters and apostrophes and
things that databases don't like so we
actually at one point just substituted
that Park names with one of their ID
from the from the service and preceded
by the money app times that we tied in
for the letters
all right so processing migrate much has
many different methods available for
processing your incoming data you can
use dig for matters there are callbacks
for any PHP function makes it very handy
there's not much documentation on that
though so it takes a lot of reading and
a lot of guessing to get it to work but
then once you get paying on it it is
pretty awesome you can map your fields
to one of our many metadata to one or
many fields like in the ED s as an
example where you might have street
address zip code a bunch of different
fields that need to go into one address
field and you can look up data that
you're importing i'm by using the
migrant make migrate map table from
another important you want to elaborate
on that a little bit sure so just this a
little bit of background here to like
the the migrant module your migrations
we sort of split into two stages you
have the you have the source where you
get the data and then you process the
data so no matter what method you've
used to get the source data whether it's
from a CSV file or from the so call or
XML document once you've gotten that
data split into different rows then you
process the data and add it into Drupal
so when it does that you've got a like a
key value for identifying like a unique
identifier for that object and this
isn't the Drupal an ID or T ID of the
content you're creating but it can be
like a legacy ID or like whatever
whatever you specify in your source
plugin and once you have this set up the
migrate module takes care of creating a
map table of the source ID to the newly
created Drupal ID whether it's an ID or
the
idea or whatever it is of your content
you're creating so this is very nice
because in the migrant module
automatically keeps track for you of all
the content that you've already imported
you don't have to worry about importing
something twice or getting duplicates
because it's already taken care of that
for you and it stores it in a table so
you're able to do a lookup through a
sequel query later on where maybe in
another process or another part of the
website you know the original ID of the
content and you want to get the the new
Drupal ID you can perform a quick look
up on that and get that really easily
yeah as an example we had to do that
with category taxonomy terms in the old
system it had the old system ID and in
Drupal it has its term ID so we had to
match data just on the string of text
for that term so we didn't yeah we
didn't have keys we just could match it
by doing a database query for that and
then properly hit a process also with
taxonomy terms we had a lot of terms due
to some disorganization of the previous
system that were like had - in the
middle they have kind of like a parent
term before the - and then the actual
term afterward and we were able to split
that up into actually using the first
term before the - to associate with a
parent
and then the use the one after the - of
the job - yeah so in in some of the soap
calls the parent and child terms would
be returned in separate fields but in
other so calls they would just be
returned in one field with the two term
names separated by a - they weren't even
using the actual ID value so we had to
do a lot of juggling with the data to
split that up and look up the term ids
based on the name instead of the old
systems unique identifiers so all this
kind of stuff can be done but it
requires coding some like custom plugins
for the migration module so that you you
can get it all set up
so this is an example of llamo file this
is the configuration file for a
migration you specify all the fields
that you want to import from the old
system and you match them up with the
Drupal field names so the the fields and
the old system are what you see on the
left can you point to that blob under
fields if this part here and then
they're matched up with Drupal field
names on the right and in some of these
some of these circumstances it's just a
simple one-to-one like data from the the
so call directly into a Drupal field but
other times like you'll see for field
Chicago community we have to run this
through another migration where the
community terms are being created by a
different migration and get the updated
Drupal term IDs because the the so call
that we're calling in this migration
isn't returning of course the Drupal
term IDs that it returns the old systems
term IDs which then when the Chicago
community terms were created by the
other migration it stores the
association of the original ID to the
Drupal ID in the migrated map table
any other insights here okay
so formatting yeah we're going to kind
of relate this to our modules here and
rest field module I guess I just put
that in modulus but it's it's a basic
but crucial field it stores the basic
location data and that's where each one
of those pieces of the address lives
that we can use to get coordinates and
get things ready to be on a map the geo
coder module calculates coordinates
based on those address fields be a
service like Google Maps or any of their
of those geocoding services it's got
like ten different services you can
specify and then a geolocation module
stores the coordinates in the database
and allows you to actually select a
place on a map there's a match selection
part of the field and that's helpful
especially for example of the Chicago
Park District they're statues are in the
middle of a field sometimes there's not
an address and we don't want it to use
the closest address because like like
Linkin Park's eight miles long and the
address is in the middle second not
going to work so you can just click on
the map and set the coordinates there
and we are in the right place
we also
you want to talk about the tape
customer trades Oh so we we created a
custom module that supplied a trait to
our different classes that gave some
helper methods for calculating the
distance between two points like - June
- geo coordinate points or looking up
taxonomy term parents based on the child
terms things like that we also had
polyline feel that needed just to store
the boundaries of a part for the app so
when people checked in to the part the
half knows that they're in the park or
not actually so they demanded points at
this sitting at home
yes I'm sorry I missed the geolocation
seniors are going about moving
so every time you do any important you
have to like go through all the notes
donut-shaped see the on import if the
park has an address the geo coder module
gets called automatically and generates
GPS coordinates for the address that is
given but well I think it's the next
slide where we show when you're adding a
note manually in Drupal there's an
interface for both looking up the geo
coordinates based on the address or
clicking on the map to set the pin
manually the challenge of all of this
coordinate generation generation that
does amount of data that we had for this
project and any dart project would
require paid geocoding because there's a
lot so we used the Google API annotate
account and it's still there doing some
heavy dead racket
during that time we would be each other
so then you hit the free API call them
it pretty quickly if you're dealing with
a large amount of data yeah when we're
doing our initial imports it
yes you guys to talk more about that
later a little bit yeah if you have any
if we don't answer your question by the
end please let us know
it's just Latin long and then it also
calculates some like sine and cosine
things I don't quite understand that it
uses to more quickly do distance based
lookups does it like pre calculate some
stuff but the polyline thing with the
like the area part of it that's
something where we had to store it in a
text field and that was data that we
imported from an external system in
theory you could handle that and the
custom function right the geolocation
field doesn't support that so this is
the the node edit form where we have the
address field up at the top and then the
map below that is the widget provided by
the geolocation field and then in the
background the geo coder module is you
this forms like a link between the two
fields so that when you type in an
address in the address field and you
click locate address on the map the geo
coder module calls out to Google or
whatever other service you've specified
to get the GPS coordinates of the
address and then enters those GPS
coordinates into the geolocation field
that's all that's all out of the box in
addition to this you can put a pin on to
the map manually like clicking it and
that will store those GPS coordinates
into the geolocation field and you can
do this one of like two different ways
you could manually enter an address and
put the pin somewhere else that's
unrelated to the address if like for
example the park has a official address
but you want the pin to be in the middle
of the park instead of the like roadside
location that the address would be
indicating you can also click to put a
pin and then there on the right there's
the push to address button that will
perform a reverse lookup where based on
the GPS coordinates it tries to find the
geo code or module will try to find the
closest like street address to that pin
this can work this is a little bit
unreliable because if you like click in
the middle of a big park and you try and
look pushed to address it's it's a
little dicey on where it actually finds
the address so in those circumstances I
think it was better usually to manually
type that that wasn't always boss
and then you can see at the bottom this
is a an output from the database of the
field provided by the geolocation module
and you can see that the the geolocation
module is just storing the like GPS
coordinates in it and then these
coordinates we'll be using later on to
show the data in many different ways
maybe or
I don't believe so it just stores that
as latitude and longitude so there are
options with the module but we didn't
really explored all of them since we
didn't have the need but play around
with it it's cool so for the daily
importance that we never required used
some modules for each import so they can
have their own cron job and we were able
to do many different cron jobs because
of ultimate crown module which allows
you to do a lot of settings for your job
so you can run it at different times you
can set them at any any thinkable that
you can set with the regular Drupal
crime so what we did was copy the
the update hook from my great tools for
each one so we could run that separately
for each department and we also have
able to add custom air out but for each
import as well so we know what was
breaking and why okay and then I also go
to the next side just for the sake the
structure of the sub module the module
file where we put the hook in and I also
like to save the the mo config file for
the import in a module just as a backup
because sometimes you can think
directory and your sink director you can
get thanks that we messed up and it's
good to have like a master settings to
go back to
so this is the crown hook that's run to
kick off the mic migration on a daily
basis and it runs the Drupal migration
that we specified a few slides ago and
one of the important things here is
where it says migration get ID map
prepare update this is what allows the
migration to be run in update mode so
instead of just creating new nodes which
is the default it will update any
existing nodes with any data that has
changed in the in the so call so as I
was saying before the migration module
keeps that map table that automatically
tracks the legacy ID with the new Drupal
ID and it uses that to make sure that
instead of creating duplicate content
and Drupal it updates the existing
content
okay so now we're on to display like I
mentioned before we had a need for lists
maps and deeds up pages so we're going
to go through those
this is displaying the location data in
different ways
so for listviews view modes so we were
able to create sidebar list format pages
and put all those format and demos
chunks easily that made a custom field
formatter for the distance from user
moving the same thing then well I'll
talk about that looks like where it
shows it and we also had fill in other
location info or content related to this
like schedules so here's like a pretty
simple display of the location the parks
content in a list and in this case we're
displaying the address and the GPS
coordinates but we're not displaying the
GPS coordinates just as GPS as the
numbers because that wouldn't make any
sense to people so there's a custom
field formatter that I created that
takes the GPS coordinates stored by the
geolocation module and performs a lookup
to comparing the location of the park to
the user's location provided by the
browser and calculates how many miles
away the user is from the park did you
possibly sure that
you use it no that's um it's I think I
put it up on my github to share out but
I haven't pushed it to Ivan created a
patch or anything for the geolocation
yes
it wouldn't show anything so the way
that it works is the field formatter
creates an empty I think it's a div tag
it's it's either a div tag like a span
tag and there's data attributes on that
tag that are though the Latin long
values and then there's a JavaScript
file that gets loaded after page load
and it performs up and then changes the
like value inside the div or the span
tag to show this this markup with the
distance from the user so if if it was
if it didn't have anything it would just
be an empty HTML tag that wasn't
displaying anything
and we have the maps
we also used view modes for the tooltips
so we could get the kind of the same
book modified information on a very
quick before the markers themselves
we showed a standard marker for most
maps but the event map needed custom
markers for holidays and different event
types so we did a little magic using
text how many values and images image
field stored within the taxonomy make
that happen we also had to organize like
facilities to their parks in that map we
had to house the main location of all of
those on the top of the stack so you
weren't seeing like the Statue first you
probably wanted to go to the so here's
an example of one of the maps where
we're showing the GPS coordinates by
showing the markers by loading the
markers onto the map for each location
and as Bob said that in the field house
would always need to be on top is in the
data that we were getting from the parks
district
often the individual facilities in the
park like if the park had a swimming
pool or a statue or whatever it was
playground the the GPS coordinates that
we were getting from their service we're
not really unique to that individual
facility they were all to sort of
stacked on top of each other so one of
the requirements was that we have the
field house on top so I had to do some
fancy sorting in the sequel query to
make sure that that result was always
returned on top
and for a park detail page we had to
show all those child locations from the
main park event that also narrow the
child locations when you type in the
search box and that map and it can
filter spend that you're typing the
location type so that's kind of neat
then because I'm a person accustomed
block you're able to put it in any
position on any page and it makes it
really easy so here's a thing is one of
the park detail pages for Bessemer Park
and here we're displaying the address
field and some of the other fields from
the node in the park description
feeds so the the last part of this are
displaying the park data was to create a
feed like I said and this was consumed
by the Chicago Parks District phone app
and as I mentioned before we were we had
to match the output of the feed from the
original website like character for
character because they were unable to do
any updates to the app that had to just
like work seamlessly when the new site
was launched so um Drupal 8 provides a
really easy way to create um these
restful api is using the feeds using the
views module but you don't have total
control over the output and since we
needed the output to be very specific we
had to create our own rest resource
extending the Drupal core restful Web
Services module and this was actually
pretty easy but you have to write some
code instead of just using views
anything you want to add
so this is a example of the code we use
to create the endpoint in in a module so
it's very simple you heard unlike most
things in Drupal 8 where you have to
have a bunch of gamal files just specify
what you're doing in this case all you
have to do is have this resource plug-in
in the correct folder and up in the
common block here you specify that it's
a rest resource and you give it the URI
path and then it just works and you
extend the resource based class provided
by the restful Web Services module and
you can have a bunch of code that loads
up all your data and you return a
symphony response object and you have a
rest feed it's pretty it's pretty easy
looks easy right so here's where we're
able to like because it's just the PHP
code we can we have complete control
over how we want all the data processed
and displayed in the feed which is as I
said the reason we weren't able to use
views because the views didn't provide
the like really really finite control
that we needed
so problems encountered you talked about
some of them but specifically the
migration sometimes we would have a
field come in that was empty from the
API and maybe the first time we wrote
the processing plugin we didn't scan in
checked her that yeah so if there is a
folks there's a callback you can use in
the gamla file that's called skip rfg to
do that before it gets to the to the
plug-in or the plug-in you can do any
exempt to your and if you don't do this
then it like crashes and you get a lot
of failures in your migration same with
formatting that directly related to
location data but deep fields are huge
with this sometimes the the format will
come over different than you expected
then all the other dates previously and
it'll break so we need to handle that as
well
and a plugin another thing you can
encounter in migration especially with
these daily imports are server api
timeouts if you're trying to get 15,000
records see if there are any changes on
here's servers that have the largest
capacity it can give you a timeout so
you may have to whittle down the service
call to a more specific set of Records
that you're trying to get data from
geocoding problems like I mentioned
before the paid API key for the volume
we had there's a must or else we're
gonna get anywhere for all these markers
I mean no that's probably not all of
them I there yeah also in development
the geocoding didn't work over HTTP this
is the user's location from the browser
if they access the page over HTTP
instead of HTTP the browser where most
modern browsers will deny the location
request you just have to make sure to
make a self-signed certificate for your
machine when you wanted to develop me
globally yeah
make some inconsistencies yeah so like I
think in Google Chrome if you're
presented with the pop up to show to
share your location with the website you
click at once and then it remembers it
by default
whereas in Firefox the if you the
default behavior is just to allow the
request once and then each time the page
is reloaded they'll get asked again
unless they check the little tiny box
that nobody when testing checks that
says remember this decision and then
there's also inconsistencies in the like
fail state of these requests different
browsers would give different responses
when the user denies the request so it
was kind of hard to give useful messages
to the user whether the API whether the
like location request timed out or
whether they were denied it or whether
they just never clicked anything at all
all right question time yes did you ever
get another geocoding services besides
people what was the problem
a question was did we look at any other
services than Google for geocoding and
we did not we just figured that was the
standard for what we needed and we
already had an API key actually from a
different project so that was really the
biggest decision driver there but yeah I
haven't tested any other ones yes
so how are they connected and
if you have a close one
see
so the question was how the address
field and the geolocation field are
connected and what happens if you have
multiple ones and they're connected with
the geo coder module that's the the
module that forms the bridge between the
two of them and I as I recall I'm not
the configuration for the geolocation
field you have to specify one source
field so you have one address field so I
think if you had multiple if you had
multiple potential values you would need
multiple fields
yes you rub your own polyline basically
use your own taxability of the polyline
is there a reason you didn't use the map
optical there's nothing like that a
question was we stored polyline in a
text field instead of creating our own
and the answer is because it was already
made there's also a polyline module out
there we didn't have we just needed to
pass it through to the app so we didn't
need to do any modification or updates
to it that's why no not in the side at
all just it's just there to be in the
feed in the restful service that the
phone app consumes know how much you
guys can speak to this but the actual
adoption of what you guys build
Wyles are those people using the mobile
app are people actually using the
website in a mobile phone
the question is our users using the
website more or the app and as we
believe the app is not used as much as
the website address Kelly knows about
this
not as rich
and by the way and you know there's a
fake GPS or several pages yes absolute
you can check it in from a location but
I did not I use that on now yeah that's
apart quite so check in to do it over in
the UK - yes
so the the question is how much control
we have over the display of the map and
when using the Google Maps you do have
some options to use things like overlays
or change the colors or things like that
you you can specify whether it's showing
like the satellite by default whether it
shows like the road map view by default
whether those buttons are there to
switch between the different view modes
things like that yes
so the question was what's displaying
the map to the user and in most cases
it's a custom block that we created that
is calling to the functionality provided
by the geolocation module it's the same
thing that if you created a view and use
the geolocation modules display
formatter it would create the map for
you so we're just doing that but we're
using it in a custom module so it's
provided by the geolocation module how
do you determine the location of the
user so the question is how do we
determine the location of the user and
this is a this is functionality that's
built into the browser and we use the
JavaScript to call to the browser to
request the user's location based on
hosting its I think it depends on
whether they're on a like wired up like
a PC or a mobile phone
I believe if they're on a mobile phone
it uses something like location data
from the phone um if they're on the PC I
think it uses the IP address let's look
up which the foam is an activity the GPS
chip but they also use Wi-Fi data around
you because the world knows where the
Wi-Fi hotspots are so if it sees you
within range of different hotspots it'll
it'll wear your question it constantly
asks you if you want to use minor data
and that's what it all kind of wants to
see what hurts yeah like for our
purposes that wasn't we didn't really
need to concern ourselves with how we
got that data we just needed it seems
like hey um if you go to Google Maps and
you you look at the map it'll it'll
still like show the little blue blue dot
to indicate where you are and in my
experience that's it's kind of creepily
accurate it'll it'll show me it'll show
me like inside my house in Tokyo
it's wildly inaccurate belt especially
with a lot of the newer ISPs the you
know in in Tokyo it's really accurate
and it showed me inside my house how do
you have the the child location setup is
that a different content type and how do
you geo code for places that don't have
an address all locations are location
type and there's an entity reference to
the parent location and how we
determined after import what does what
is locations that had a parent location
we're not parks oh yeah there are
facilities so then we generated a
location or entity type part or facility
off of that so we could tell them apart
and the way that we geo coded things
that didn't have an address we're
through the geo corridor module from the
map where you click on
yes so it with geolocation module I'm
not familiar with it can you swap it in
and say so the question is which other
map providers besides Google can you use
with the geolocation module and it
provides a lot including leaflet there
were like OpenStreetMaps leaflet being
like five or six others that I had never
even heard of and I actually looked at
the the modules code and it looks like
it'd be pretty easy to provide your own
custom one by just sort of copying the
code that the module used to create one
of those and then modifying it to work
with whatever new service you needed to
use it with sort of similar to the
previous question which was how did you
find related or child
locations who-who's that was all through
taxonomy there wasn't anything
the question is were there other ways
that we determine parent-child locations
based on proximity no the data that we
were getting is was very really highly
curated so we couldn't guess at anything
or provide suggestions or wanted
everything a certain way and provide us
with that data or something but there
are filter plugins in views and filters
that you can use in sequel queries that
would give you locations by proximity
have done that on other projects
that's the beginning of your
presentation you talked about the
migration process figuring out you have
any suggestions on plating process lots
and lots of files so the question was
any suggestions on how to become an
expert at migrations and I've I've done
quite a few now and I'm still finding
new stuff like we mentioned the the
documentation isn't really complete
there's a lot of powerful stuff that the
migration module can do that isn't
really documented I just found a lot of
stuff by Google searches and looking
through the example code that the
modules provide because it provides some
mighty Salo migrations has a simple and
an advanced example they advanced a
simple example as taxonomy terms the
advanced example is notes about beer
which is kind of weird then you can't
really uninstall it easily so you might
have a new project oh yeah digger config
straight and get them out of there yeah
when you run migrate status you'll still
see the beer node migration sometimes
the example the advanced example is also
incomplete parts of it they're not
finished or documented and the best from
a starting point to get started applying
for the only like comprehensive guide
ever seen is the guide after
and Vic there's been a number of
sessions at various camps and Drupal
cons so you might be able to find some
good information on YouTube but most of
what I've learned I've learned from
reading people's blog posts and then
experience the questions
okay one thing I did not mention at the
beginning I work for clarity Partners we
do mostly government work public sector
stuff so this practised ik project was
an extension of that and the company
that did this well if you have a
government website that you need built
go see clarity partners if you need
[Applause]
thank you