How to extend Contentful's interface with custom fields

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello everyone it's tuesday and that means that we are ready to do another live stream on the contentful youtube and twitch channel and for all the people that are already hanging out we are happy to have you and with me is already uh my friend and colleague david david how's life hey not bad just uh you know riffin just hanging in there doing some live coding you know how again so so what we're going to do today is that today we're going to do another session on contentful's app framework we're going to cover on the way um what the f remote is we're going to start from scratch but i don't want to um show and tell too much but the only thing that we're going to do is that we're going to extend the interface and we're going to bring in something on top of the json field for um something like repeatable data structures that don't necessarily need to be a its own content type something like ingredients for a recipe or something like that and before we just dive right in let me just do some housekeeping and some uh drop some resources here so first of all um these live streams and all contentful events underlie our code of conduct so in case you don't feel safe or anything literally comes up and please reach out to us and we are happy to sort it out and if you're a developer and you want to know what's up in the contentful community you can have a look at our developer portal this is available under contentful.com developers and so you will find blog posts there our live streams youtube links video resources so it's the go-to place to see what's going on in the contentful community and if you want to participate with the community in real time in chat we have a slack organization so you can subscribe and sign up there at contentful.com slack and now for a while already we have our graphql api available in the free community plan and edition so um if you want to learn graphql want to get started with this fairly still new way of growing api data you can go to ctfl.io which is short for contentful learn graphql we have i think it's 12 13 videos um five minutes um that really get you started on using graphql with react and then what's even cooler if you then build something with graphql you can submit your project at ctfl.io gqlswag and um we will send you some cool things like stickers and socks maybe a t-shirt we all have to check what is in stock there but we would love or we love to see what people are building on the graphql or contentful apis in general so let us know and with this the housekeeping is already done and i'm gonna flip off my screen and we're gonna bring in david's screen and then we gonna do some life coding are you ready david yeah i think so sweet yeah so um what i've got set up here is i've created a like you said the field repeater app so let's work on that i've just to save some time i've already run the npm script the create contentful app script uh which you can find you know in our docs um so building you know building your first app it's going to talk about the create contentful stuff and creating an app definition so we're actually going to go through that a little bit but since i've already run the script i'll just run the start command so we can get it up and running and also for those of you that aren't super familiar it also builds out this um directory structure so i've got vs code open here into the field repeater app that the create contentful app built for me and it has you know all of our components a single page application so it's got all of our components and all the things that are necessary to run our single page application and in this case we're gonna use the field uh field location and create that repeater field before we just dive in maybe we want to do really just five sentences what is the app framework and what can we what will we do with it or what can you do in general yeah so i mean the app framework is the evolution of ui extensions so everything that you had available to you before to customize contentful's ui whether it be you know in the sidebar or in the editor and i'm talking about like these locations here so the sidebar here you can have you see i have like a jira app here and a netlify app for my my blog post and also you can customize you know the editor if you want to have a custom editor here or if you want to have different um different locations up here at the top you can have like different editor locations we also have full page applications too which allows you to actually come in here and you can see you can have like a full page application come in so i've got workflows installed so it it kind of expands the editor experience in the web app but not only that it also expands the experience outside of the web app because what you can do is you can build back end applications that interact with contentful they can write content and update content in contentful and what's really cool about the app framework is you can see here like the author section says me but with an app it will actually show that like the app modified something i think in the past people have kind of solved this problem by creating a dummy user or a bot user in their contentful space and assigning that with like a key and having a back end use that key to access things but now the app framework really allows you to just kind of do all that programmatically and you don't have to use up your user you know provisioning or whatever you can you can have the app work on its on its own uh behalf basically so i think that's really cool the air framework in general is really just the ability to customize the content for yeah yeah pretty much in short it's just a way to programmatically access contentful and augment contentful's interface and things like that so it's a pretty powerful i would say and you know it's varying degrees like some people build really small apps to the point where it's just like a little field and maybe it's like a color picker or something like that so it doesn't do too much it just helps like a user pick a color and then some people build insane integrations like uh translation services that read content from contentful in real time translate it send it off to third-party translation services maybe show statuses like it you can do crazy stuff with it cool and uh if someone in the content for community are hanging out on stream um we're always are up for kind of things that we can build live here if it's not too big because we're aiming for for an hour 90 minutes or something but if you have questions ideas please drop them in the chat we have already two people that said hello uh on twitch uh one of the people is uh white panther which is who is selma um someone will join contentful at some point so hey salma happy to have you and uh so what we're gonna do uh today david so what's the what's the game plan yeah so i think for today let's like focus on creating a new field and a content type so here i've got like a demo uh space uh which is just a blog post space and i think you know what we'll want to do let's say let's just say this is like a recipe blog post or something like that and one of the fields that i want to have is just the ability to list out different ingredients and i don't necessarily want to create like a new ingredient content type because i don't really need to i can just simply say like the measurement and the ingredient itself and i don't think that's you know we don't need to necessarily create a new content type for that but i do want to have a field that allows me to have like a button for example that says like add another ingredient and you can kind of list out the ingredients that you want if that makes sense that makes total sense for the people that are not necessarily familiar with contentful so the idea is i've got a handful that you can define the data structures really to your need when you want to build a blog or a landing page or something is really up to you on how you structure your data and for example when david could go to the content model section you can create these sections really in just a few minutes you define your data type and what fields should be in there and then you can connect all the pieces in kind of a tree structure which makes the whole thing very powerful but sometimes it might feel like a little bit of overkill to have a content type for everything and this is what david just described and kind of ingredients is probably a good use case for this because if you would have several content types you would have probably 10 different ingredients that only hold information like a title and maybe an amount for 500 grams or kilos or litters or something and what we're going to do now is that we're going to reuse a different field type to do that is that is that this is what i have in mind is that what you have in mind yeah i think so because like when i think about reference fields i've i think about the power that they hold where you can actually visualize and map where this content is referenced in multiple places but like if you have an if you have a list of ingredients and say you need like you know 500 grams of flour do i really care you know if i reuse that across different you know entries or something like 500 grams of flour i just can type that in i don't need to have like it's reference you know if you think about in terms of like a database i don't need to have like an entry of 500 grams of flour that gets referenced in all these different places uh so i think you make a good point here i how often it will be referenced when you think for by for example about a blog and an author you most likely will have 10 15 blog posts that should use the same author right right because it makes sense there to reuse data in a different place but for 500 grams of sugar well i'm not really sure about it exactly i think that's a good point like authors you can change the data and it updates globally whereas if i update 500 grams of sugar like that's going to change every single recipe yeah so i think here um what i've got is i'm in the blog post content type and it's a very simple content type we have a title we have a body and we have similar content which in our case is you know probably similar recipes or something like that um but what i want to do is not only do i want to have a body that explains you know what the recipe is and maybe i talk about my you know my grandma made this or whatever but what i'll do is i'll add a new field and we're just going to make it a json field which gives us the flexibility to add the data structure that we want so in this case i'll add a json object field and i'll name it the recipe ingredient yeah actually that's i think that's better so ingredients and let's just hit create and configure to see if i want to do anything else i don't need any localization uh validation i guess i could make this a required field i think for this you know for this demo i don't think it's necessary but i would say that if we're doing a if we're doing a cooking blog i would assume ingredients should be required and here you'll see that this is the appearance tab so i'm going to leave it as the default for now just so we can take a look at what it looks like but what we're going to do is we're going to create an app that's going to show up here so you can see i actually already have one app but i'll add another app in a second i'm going to create an app that shows up here that's going to help us create like this this list field i guess we'll list out the ingredients but it's also going to contain some extra functionality like a button to add a new ingredient and maybe some x x's like little x's where i can delete ingredients if i make a mistake or something like that right so let me add the ingredients list and i'm just going to move it up here this is just a visual change i'll just move it up so it's underneath the body and let me save and back in the content uh if i go to my first post here you'll see that i've got my title my body and here in the ingredients this is just like a text editor for our json editor but what it does expect is some valid json so if i do for example this it's going to say that's invalid so we do need to actually you know add some valid json in order for it to work and of course if uh this is not javascript this is json so it does need to be pretty perfect there in terms of uh the structure yeah jason jason is not forgiving right yeah yeah we can't get away with certain things um but that's okay uh we'll create an app that kind of programmatically accesses this field so we'll have a ui built on top of this field so we you know i think what we would have seen in the past right is if you were to leave this field just the default and have editors come in and have to like write an ingredients list like this you basically have to tell them like okay well you need to understand json and you need to have like a list and it's going to be an array and you need to like specify you know what's in the array so what we'll be doing is we'll be creating a ui around this and i think the end structure in our case is going to be i think something along the lines it depends on how we want to do this but i think the easiest way to do this is probably have like a key value kind of system so we can say something like the name of the ingredient again i have to do this in correct json so the name of the ingredient for example and you know let's say carrots and then we'll have to say like the amount and here i think we should also just have it as a string and let's say you know 500 grams so this is kind of what's going to be happening behind the scenes this is what the json field will look like you know when you actually make the call to the contentful apis to populate your you know the visual side of your blog post when i'm rendering my website this is the data structure i'll see but our app what our app can do is it can latch on to this specific ingredients field that i've got here and it can kind of overlay a ui inside of contentful and under the hood it's going to create this data structure that contentful understands yeah so the things will stay the same right but we were just changing the representation of this json field yeah so this is all going to go like what i'm highlighting here is kind of the under the hood of what's happening and what we're going to do is we're just going to create like a nice ui on top of this uh so so users don't have to worry about editing the json manually we'll just create a ui that edits the json for them yeah and no kidding i've been there i've seen down times because of invalid json and uh inval diameter for for for example i've seen i've worked at several companies where we had translation management and yaml files and that's the perfect morning when you wake up and it's like oh something is broken because two spaces are missing somewhere and jason is also not forgiving right it's like you single quotes and you're basically screwed yeah yeah i think uh i think that's a good point i mean yaml with like with white space type things it's it can be even more frustrating especially if you're working in an editor that doesn't show you like the white space characters yeah you know you can sit there debugging for hours deleting things you can't even see hoping it works i think i think i've seen wild things where um for example translation managers had to go to github edit there and make a pull request that was wild i can i cannot recommend yeah so i think i think i think that's what we're trying to avoid right this is part of the app frameworks mission is to make it so people that aren't technical uh can come into contentful and just edit stuff in like a nice way in a user-friendly way and they don't have to worry about all this under the hood stuff that that gets left up for the developers and of course if there's a bug then the developers have to deal with it and not necessarily the editors uh cool so how would we do that now we have the json field which is already available right if we would now publish this and we would query the data via cda which is content delivery api or our graphql api we should already have fields dot ingredients or something right yeah so that's going to show up and it's going to give me just this this json object right here that i've created freeform so i mean this is nice you can imagine that this json field does allow for you to save a lot of extra data structure inside of your already existing content type which itself is a data structure so you know it's like a mini data structure within a data structure we're getting made out here it's it's like a russian nesting doll it's like you can keep going deeper all right but i think you know the first thing we want to do so as a developer i'm a developer in this organization and that's kind of a key i do need to be a developer an admin and an organization to create an app so i think a lot of people what they'll do is they'll either create like a test organization or they'll just be kind of an admin in their in their own organization and what they'll do is they'll come into the organization settings here up in the main menu they're going to go into organization settings and over in the top menu there's an uh there's a choice for apps now what this is is all of my private applications within the organization what that means is i can create an app in my organization and i can share it between all the spaces inside of my organization so it's really you know it's really easy if i have multiple spaces and i have kind of a general app which i think this app is going to be fairly general it has different uses it doesn't just need to be ingredient lists but yeah we can share that across so let's go ahead and create a new app let's call it the ingredients list app just to you know make it easy and since we're developing locally i'm going to point this to localhost but let me explain what this thing is so again apps are single page applications that run in an iframe inside of contentful so what this means is you need to host your app either on the public internet or for development purposes on localhost that's what the iframe is going to look at right it's going to look for a source url and it's going to render the content from that source url and in our case since since i used create contentful app uh we're going to run it on localhost 3000 that just comes out of the box and the other thing is we need to describe what locations we want our app to show up in in the main web app um like i mentioned where since we're doing that json field it's going to be the entry field location and when i click on that we're going to get a choice of the actual uh types the field types that we want it to show up for so you can imagine actually i could have an app that shows up for all these different types obviously there would be a lot of code involved to kind of change how the ui works based off the type for our purposes i'm just selecting the json object field so we're going to be overriding the ui of that field um the other basically basically the json field can be used for basic it's relatively free data structures right so in case there is a short text a long text um you will have to be very specific about the data that you want to store with json you have a lot of free freedom to do so we have two questions in the chat from from selma um so sama asks is all the custom field stuff done in the ui or can i configure it in the code itself in an installation of contentful i'm not sure i fully understand the question um if if by customization if you mean like can we allow users to customize the experience further once it's in the ui the answer is yes we give so not only do we have that underlying json field but we also have specific json objects where you can store like configuration parameters specifically for your app which would allow you to kind of have like this storage location where you can store like if users want to change the color of a button in your app for example they can pick colors they can pick values they can put in third-party data if they need to like third-party uh access keys and things like that you know that's that might not be a great example because you need to be careful with security there but it's possible uh i i think that's what you mean but if not you know feel free to follow up on that yeah i think the main point is really what david just pointed out is that with front-end apps and contentful you can basically replace a lot of ui that comes by default and the way that it works is that then you have all the freedom to uh replace the ui with whatever you need um right because these iframes that point to url or um either localhost or in the publicly available big internet um are able to communicate with the rest of the ui and with the apis that are basically in the content interface right i mean kind of as a ridiculous example imagine if i owned google.com and i allowed it to be rendered in an iframe inside of contentful so i could have one field inside of my uh content type literally just be google.com because it's just an iframe so i could literally run a whole website inside of an iframe in contentful incontentful uh and have access to the contentful content type via google that's a ridiculous example but i mean since we're just running iframes and since you're just running a single page application whatever you can do with like a single page application you can do inside of contentful cool um okay so the other thing is it's asking me you know about the other locations i'm gonna skip the other locations they're all optional and i don't need them and instance parameters i did uh i went over what instance parameters are recently in our last hangout i'm not going to need them for this app but just quickly just to kind of explain what they are it's the ability to per instance um show or change something like so if you install something per content type you can actually have like a per content type configuration if that makes any sense um i think we should cover them a little bit later i think the whole idea of what happens now when we after we create the app becomes a little clearer after we press the green button yeah i think i think that's the case too so let me press the green button here and so we have our ingredients list app so this is an app definition this means that when i go back into my space where i want to install the app it's going to show up in the marketplace so let's see what that looks like so back in my example space here um let me just refresh sometimes you know we need to kind of update the caches uh so back in my example space and if i go to the apps main menu and i go to manage apps and again i need to be like i need to be someone that can manage a space or an admin to access the ability to install different applications editors can't necessarily install applications however they can use them so here in the in-app marketplace this is where all my private apps show up and also where all the public apps show up so you can see down at the bottom here we've got all of our third-party integrations these are all the public applications and here in the list of private apps indicated by the private tag and you know they just have the puzzle piece icon i've got my ingredients list app so if i click on that it's going to say you know your extension is being served from localhost this is just the developer message you don't have to worry about that showing up in production and this is the configuration page of an app now i didn't need configuration for my app it's just going to be a simple list so i'm going to go ahead and install but i do want to make a note that you do have access to this full page like this full area right here and you can have you know configuration and i think that's what selma was kind of asking was if i want to have users give users the ability to configure my app based on their input this would be the place to do it yeah i think we should also aim for this app here to be generally usable right so there there in the past what i've seen is a lot of people that kind of for example hard code certain certain keys and values right when we now think for example about the table it was like okay this app has three columns with three um rows right which is maybe ingredients mount and unit or something i think that the goal for us here today should be that we we build an app that is just okay i want to have a repeated data structure but the rest should be configurable so because we don't know if the next person wants to do ingredients or i don't have another good example here right now or something else that shouldn't be a content type um i think that should be the goal okay that's cool so i think you know how we can work on that or how i would work on that as a developer is let's solve for the immediate case which is the ingredients case figure out you know kind of where the touch points are and once we've got that down then we can start to understand how to abstract the concept i would say sounds good to me so i've got my ingredients list app installed and if i go back to my blog post entry here you'll notice that nothing has happened so i i haven't like done anything except for install the app and i know on our app definition we said we want it to show up for the json editor page or sorry the json editor field not the page but we need to still what that does is it's saying it works for json fields but now we need to specify which json fields we want it to work for so specifically in the content model if i go to the content model here and into the blog post and into our ingredients json field if i go to the settings and the appearance tab so here is where our ingredients list app shows up you'll notice this wasn't here before and now it is so when i click on it i can use that instead of the default object which we which comes with contentful this is actually an app it's specified as an app and so if i save that and then i save the content type then what's going to happen when i go back into my content is i have no longer the default editor but instead as you can see this is what i was talking about when i said we're going to replace the default editor we're going to put a ui over it so here is where we've got the iframe rendering my custom component which is like this hello world component and let me quickly just verify that so if i inspect the element here now this is kind of uh messed up but let me um let me make this a little bit bigger hopefully you can see this so if i inspect the element here you'll see that when i hover over this iframe chrome is highlighting it in the actual visual portion and you can see that the iframe is pointing to my localhost source so again this is this is what you know contentful is doing it's running this iframe inside of the web app and it's pointing to you know our code right so the reason why this worked the reason why we actually see a hello entry field component is because at the beginning of this i ran that npm run start inside my create contentful app directory that ran it on localhost and in my code editor i've got this hello entry field component and just to kind of see that it's working let's make this the ingredient list shell right just just to see what we've got here and if i move back into contentful close out of the developer here we go hot really reloading and stuff here hot reloading so we've got um we've got a place where i've got a react component rendering inside of contentful so again here's the react component and this react component renders inside of contentful here so now as you can imagine all we have to do is build the react component with the proper logic to be able to show a list um and so here is where i'll make a plug for forma36 forma36 is our react component library it basically is everything that you see on this page right so these buttons these headers this the colors the fonts everything is done in forma 36 and we give this to you as an open source thing so you can just add it to your project for free it comes built into the create contentful app uh build so when you run that command you get it as part of the thing and you can see here it's already imported for the hello world components what's really cool is form of 36 has a storybook feature so f36-storybook.contentful.com and what storybook is for those of you that aren't super familiar is it's just this way to access the different components and see what they do and kind of play around with them so for example i've got you know these these are all the different form of 36 components that exist inside of contentful and that are available to me so i can i can look at them play around with them see how they work and build them in my own react project so what i'm going to do is i'm going to look for the list component right we want to make an ingredients list and i'll just use the form of 36 list component because it's going to be styled out of the box just like contentful so hopefully our editors will get like this seamless experience where they're not you know it's not a jarring ux where uh there's one style here and then inside of one field it's like these crazy new styles and it's confusing so we'll use forma 36 to avoid all of that and what's really cool is formula uh storybook gives you access to the stories and the jsx which means we can actually look and see how this code was written and in my case i could even probably just copy and paste most of this if i wanted to but this you know this is a pretty simple list so i'm gonna just what i'm gonna do is i'm gonna say you know we need a list component and inside of it we need to list items right so in the code list component right here and this is actually auto completing because of typescript if you use typescript which comes out of the box and a list item as well so i'm i've imported these two components for use and the other thing i'll do is i'm going to change this render method and let's say i want a list right and i've messed that up and in it i want a list item and this is where i'm going to say something like flour 500 grams right this is where this is where our stuff starts to come in so back in my uh backing contentful you can see that we've got flour 500 grams now this is the part yeah how do you want to approach that i would have i have would have approached it differently what's your next step now yeah so i'm approaching it um kind of in terms the reason i'm approaching it this way is because i just want to show like the steps that it takes to actually get to the programmatic rendering of the list and so you know if we were to hard code this list in react this is what it would look like of course we don't want to hard code the list and react but i kind of like this idea of working backwards where it's like we kind of understand what we want to render and what we want it to show and now we want to start to slowly fill in this data right like flower is going to be a variable and 500 grams is going to be a variable so actually what we can do right is we can say that we want to have an ingredient um so like the name of the ingredient is the variable and the amount right so those are going to be the variables that we want to have in react not only that we also want to map over all the ingredients so we're going to have a list of ingredients right and for each ingredient we're going to take the ingredient i and we're going to return this list item i'm going to return to see where you're going my friend yeah so um and i need to do some react stuff here so let me just add a key of dot name and this is going to be i dot name and this is going to be i dot amount and now of course it's yelling at me because we don't have a variable called ingredients get rid of this comment here so let's make a variable called ingredients and it's going to be an empty list and now you're getting already closer to the data structure that we had in the json field exactly so as you'll remember the data structure in the json field was something along the lines of it's going to be like a list of objects where there's going to be a name for example like flower and there's going to be an amount and let's say that's like 500 grams and um let's refresh i mean yeah okay so here we go it's showing up and just to confirm because i did have flour hard coded before let's say sugar oops do sugar and hopefully we should see it uh refresh there we go so sugar 500 grams so now we've actually got some kind of programmatic rendering going on and the next step would be to actually access the data from contentful right so as you'll remember we had underneath this uh this single page application this iframe there's that json field which actually holds the real information that we want to access so that is going to require us accessing the sdk which again if you use the create contentful app that gets passed in already everything's hooked up for you as you'll notice i didn't have to really do too much bootstrapping for this project i can go right into like building the business logic which i really like um i've spent enough time bootstrapping projects so we all yeah it's definitely definitely nice to kind of get into it create the same config files over and over again this is what we paid for now well yeah i guess other people have you know kind of perfected the webpack or the the web bundle or whatever and so we we just only need to worry about writing this business logic so what i want to do is i want to grab this list from the underlying data structure that we already had in the field so what i'll do is i'm going to access the ingredients in a very different way and what i need to do is access it via the sdk what the sdk has on it is oops what the sdk has on it is all of these different methods and again because i'm using typescript my editor is able to show me what these methods are and in certain cases it even gives me a bit of a description which is really nice so for the current entry that we're on i want to access the fields and actually i think i can i think i can do something even a little simpler which is i can access the exact fields that we're in because this app is rendering in a specific field and what i'll do is i'll do get value okay and what this does what this code does is every time we render the field it's going to call getvalue and just to see what that actually looks like let me console.log it console.log debugging i'm in it console.log debugging and let me open up the console here [Music] and you can see here we've just got our console log and in it is the list and in the list is the carrots and the 500 grams you'll remember i typed that in manually when we were talking about how hard it is to you know do vanilla json inside the editor so this is what i typed in manually i've got 500 grams of carrots so as you can imagine this ingredients list that i've hard coded here can actually just be props.sdk.field dot get value right whoops yeah fourth time is a charm and um again looking at the data structure we'll need to access the list object so that will get us the actual array with the ingredients in it so let me just do dot list here let me get rid of my console log i think it we never talked about this but this is actually in here this is a synchronous call right this is the synchronous call yes huh is that cache or something or how does it work or is that just post message across iframe and the outer line structure yeah so it's it's posting a message across the iframe it's using the post message feature of the iframe ability so the web app knows that this is the current value at the time so when i call get value my iframe you know the app that i'm currently running this list app it posts a message back to the main uh contentful thread contentful says like here's the ingredients back in stringify.json value and that's what i get right here right when we go to actually create a list that's dynamic and i can add more list items we're gonna have to do state management and we're also going to need to add listeners for like when the value changes for example uh so it is gonna get a little more advanced in a second but for now this is just kind of reading the the current value that i had typed in manually um so let's take a look at script yay yeah typescript's giving us i guess a bit of a bit of a thing i i'm gonna bypass it for now um just because i want to kind of move on with with some stuff and i think actually what i need to do is uh i need to add this as a jsx comment and i didn't know that you have to do it like this i would have put it now in between the curlys huh but this comment yeah i would have put i would have added a lane line break before ingredients and i would have placed the comment there does that work too so this one is per line i'm disabling per line i actually think what i can do is up at the top here i think if i do ts no check this just disables the entire file and this actually might be better just for our purposes uh just for now because you know those of you that are familiar with typescript you know that what we would usually do is we'd create interfaces and all that stuff to make sure that we're getting the right values and kind of having a bit more type safety i don't know we could do that at the end i just want to kind of save some time and get to the business logic first i still have my heart i hate love relationship with typescript so i'm happy to skip it for now yeah okay that works for me so um we're grabbing the get value from the current field which is this json field of ingredients and i specified that it was on the list item so of course you can imagine we might have other things in there in the future but for now it's just that one and i iterate over it via name and amount and if i come back here you'll see carrots is showing up now this is coming from contentful right this is real data this is real data if someone was to edit this um entry somewhere else like via the api or something this would change so that's after refresh after a record we are not we don't have the listeners in place right right that would that's true so after a refresh um but now we've got so we've we've got to the point where uh we've got this dynamic list showing up with the contentful data and i think the next thing we want to do is have the ability to manipulate this data right yeah so let's let's do that and again i think you know in my opinion the simplest way to handle this is probably by manipulating the entire field which again is just this json object um this this thing that's returned from get value yep so the way i'd go about doing this is i would have a first of all we need to have some state management right we need to be able to say like when we want to update the list and when we want to delete things from the list so what i'm going to do is i'm going to have actually a listener which listens for when we add like a new value and i think you know we need to think about also the ui that we need for adding a new value so again in storybook i'm going to import a text text input field and i'm going to import a button because what i'm thinking is we'll have a place where you can type something in and a button to hit like add for example and remove eventually right and remove yes so let's just put this all in one big container so it doesn't yell at us i probably could have just used uh those of you that are familiar with react i probably could have just used a fragment but uh that's fine we don't need to go like that for now so we'll have a button that has add functionality right and we also need two input fields so let's do text inputs here so the first one is going to be for um first one is for the name of the ingredient and the second one is for the amount of the ingredient both are going to be strings so let's actually add here placeholders just to remind us what this is so name of the ingredient and over here i'll add please another placeholder and we'll do you know a mount do we have labels in forma yeah so i'm i'm a little bit off on the accessibility side of things and you shouldn't use placeholders as labels yeah it is a it is a little bit lazy isn't it um so what we what we've got if i go to my text field here or text input you'll see that this is just how a text input actually works there's actually a lot going on there but with a text field for example a text field actually does have the label text so yeah let's actually let's change that i guess let's make a text field instead so i'll change this to text field and instead of placeholder let's do label label i believe that's how it works i mean oh so it's labeled text okay we'll do label text all right label text and these are going to be text field text fields text field and let's see if we've gone and done broken anything well it worked for a second let me refresh i made a few changes just want to make sure everything is uh kind of up to date here yeah so um we've got the name we've got the amount and we've got the add button obviously the ui is a little funky but uh yeah i tend to work on the styling kind of last i just want to focus on the functionality first um we can always tweak the styles at the end if we have time i just want to yeah i want to outline you know how we're going to actually do this so we've got the two fields we've got the name and the amount and we've got the add button and of course now this is where the state management comes in right because these values they actually need to get saved to the list so what i'm going to do is i'm going to add some state in so i think what i'll do is to make things a little bit simple is i'm going to have an ingredient a new ingredient a piece of state and set new ingredient [Music] and from here this is where i'll actually import this from react so this is going to use the use state functionality which just is is a bit of a helper function to help us you know set uh set and create state and what the initial state is going to be is the name which is going to be an empty string and the amount which is going to also be an empty string so as you can imagine this piece of state this new ingredient is going to be this object right here it's going to be an object that contains a name and an amount and that's exactly the data structure that we put into our list field where all the ingredients are so as you'll remember our list is yeah this name and amount and there's going to be you know a few different objects in that using that so first of all you state for the people that are not that familiar this is if you want to do state management in functional components and i believe every component in create contentful app is a functional component is that right the config is maybe a class the config is a class and i think again um not to go to uh pedantic here but this is all just syntactic sugar so really what's happening under the hood is while the code does look different we're kind of achieving the same results so those of you that are familiar with like older version of react this dot set state and this dot state is pretty much what we're doing in our field component we're just we have this new ingredient piece of state and we have a function here that sets that piece of state right because functions don't have this dot state right thank you react land yeah so these these functions are um these fat arrow functions uh i guess to use the technical terms always are used uh if you want to reference the lexical this in a higher up component but we will skip now we're getting down here over the lexical scope now we're getting into it we're gonna we're gonna skip that for now um so what i'm gonna do to distract you from the technical side of things is functionality just move on david just move on so what the button is going to do is it's going to set the new ingredient right and the way it's going to do that is it's going to take the values from the text field and the from both text fields for the name and the amount um actually this is not going to set the new ingredient sorry i i don't mean to confuse so what we'll do here is on change so on change of these fields what we'll do is we'll take the event and we'll set the new ingredient to be we're going to take the current ingredient object so the new ingredient object this is uh so what i'm doing here is i'm spreading the new ingredient the current value of the new ingredient and i'm saying what i want to do is i want to have it change the name field all right so the name field is going to know where you target value what this does is it spreads it spreads the current object with the new object basically merging the two um and that allows us to update the field and again i'm going to do the same thing here so let me just do some quick formatting just so it's a little easier to see what i'm doing here and i'll basically copy and paste that same thing over here except the only thing i'm going to change is the amount right so this is updating the amount version of the field and so when i when i type into these fields it's going to fire this set new ingredient thing and it's going to update the state here which is going to be this new ingredient piece of state and last but not least or the value of these text inputs i want to make it dynamic right i want to make it the piece of state that we're currently updating so new ingredient i'm going to call name as the value here and again i'm going to use this as the amount for the amount version and i believe um i believe that should work i don't know i must have accidentally hit undo here okay cool i believe we should have something kind of working we won't see any true functionality just yet but let's go into the iframe and if i type stuff in so i don't see any errors in the console i'm not logging anything yet i'm not logging anything usually you know if i have an uncontrolled field in react sometimes it yells at me and it says like hey you're just typing random stuff in and there's nothing keeping track of that value the fact that i don't see that is probably a good sign nothing is yelling yeah nothing feeling so we're probably all right um so the other thing we need to do right now is we've got locally our component is actually getting the values what we need to do now is we need to actually update the values inside of contentful right so what we're going to do is we're going to create a new function here and we're going to call it let's say update update field value right yeah we didn't do a proper job here in our naming right we have this field value which holds the list which is an ingredient yeah you know what i mean a little bit i think yeah so uh just just to get the logic in though so what we want to do is and again this is a this is a little bit hacky like i don't for those of you that are more familiar i shouldn't be creating a function inside of a a react component here like this because it's going to basically recreate this function every single time so we can clean this up in a second um but what i want to do is on the field i want to set set the new value right so down here i'm going to use the autocomplete and i'm going to say that i want my new value to equal probably the current value right so new and urine no no you have to manipulate the object right and push something to the list actually right right so what i'm going to do is just since we're just adding the add functionality for now i'm going to spread the current object which is the field get value so we get the most up-to-date value right this is going to produce for us an object that has that list on it yep and what i want to do is i want to merge that with a new item um yeah a new item that has um actually i'm probably doing this a little bit backwards but basically i want the new list to include my new ingredient value right so actually i think what i'll do is i'll do this a little bit differently i'll say that my new ingredient is going to get added to a list and what i'll do is i'll access props.sdk dot field dot get value dot list and remember the list is going to be that array and i'm going to concatenate that with this new piece of state so basically what i'm doing is i'm taking the current list here and i'm adding this new piece of state which is which has the new ingredient on it if that makes sense yeah and we're setting yeah that makes sense and we should also clean it up to we should call set new ingredient with an empty object again right to kind of clear clear the inputs yeah that's a good point so basically when i set this value what i need to do is i need to say set new ingredient equals kind of back to our default which is name and amount is this now of course you probably make that value a constant right because i'm using it here and i'm using it here um but yeah we'll skip that just for now um there's a lot of you know there's a lot of cleanup you'd want to do for production but i'm hoping that this just kind of shows you uh how to get to the point and then you can start to clean these things up we have a question in the chat and the question is in which situation uh do i have to use a personal token for the cma i yeah go for it authentication i think want to take it yeah um in what situation do i need to use a personal token for the cma when you're creating a front-end app like i'm doing right now you do not need to worry about authorization or authentication what's that you don't need to write a line of code of it because what's happening is my app is accessing the underlying logged in user's abilities and authentication so when i update this field for example when i'd call set value i'm doing that as the current user because i am technically the one editing this field as if i was editing just a regular field inside of contentful right so when i add values to this ingredients field using my custom ui i'm doing it as myself as david fote and the sdk understands that it understands that i'm logged in on my account and the edits i'm making currently are my edits so i don't need to worry about logging in or anything like that now if it's the case where an editor was able to view this entry but not edit it the sdk would throw errors or you'd see warnings that like you can't edit this entry so that would kind of already be handled for you if you want to provide a more custom experience you could always check the user's abilities and then instead of rendering say this custom ui you can like render a message that says like you can't edit this field it depends on what you want to do really so when you use the cma that's really like if you have like a back end app for example um not a back and dab but just like any kind of back end that needs to do like that needs to access contentful the data inside of contentful and do any kind of modification there so that's when you use that's when you use the cma for sure i hope that do you want to keep rolling we have the next question already ready for you sure yeah let's see what what if i'm creating an app for others to be published should i rely on all oauth so that people can install it assume what they mean by others is like people in other organizations um so in that sense if you're in if you want to create an app that you want to have generally available such as like a marketplace app for example so if i go to contentful.com slash marketplace you'll see here that this is where we have all of our third-party integrations and these are all open source apps as well you can actually check out the source code for these apps if you're talking about having like an app on here you need to reach out to us directly and we need to go through a process of like verifying what the app does and we you know we help you out we take a look at it we give you some pointers if it you know just make sure it follows all the guidelines if you're talking about building a private app that you want to distribute to like privately to a few different organizations it is a little bit more manual basically what you need to do is you create the app you host it somewhere and then you create the app definition per organization that you want it to go into if you're talking about just creating an app for a single organization once you create that app definition at the organizational level like i did at the beginning of this demo then you can install it into any space like you can repeatedly install it into any space without having to do any more uh configuration uh in that sense right and the only thing that is coming to mind about oauth on my end here is it is possible to to have or flows with other vendors right because i know that there are some apps in there where you have to authorize with a third party or something and then we have yeah i've got an example right here actually so my jira app in order for me to see data from jira you can see here it says connect to jira and when i do that it's going to send me through the atlassian oauth flow so you can see the url as api.alaskian.com so what it's doing here is it's saying you know contentful wants to access your atlassian account i choose a site i hit accept and then i you know as my oauth user as my david fote atlassian user i can access third party data and then display it here in contentful right so that's that's what the oauth flow would uh do if you want to access third party integrations or if you have for example like some private server that has data on it and you've implemented an oauth flow you can you can do that as well it doesn't necessarily have to be you know like a public third-party integration good question diego let's move on let's uh let's make some progress here cool yeah so i think where we left off was we were adding in the values of these input fields and now we need to actually save it so it shows up here in the list yep so what i did was i created a function that we're going to call and when we call it it's going to set the value of the field so what we're doing is we're taking that list object that we've got for this field and we're taking the current value and we're concatenating that with this new ingredient value and as you'll remember the new ingredient value is this object with a name and amount which is kind of the data structure that we've opted to go with so once we set that value the new ingredient value we're going to kind of reset our local new ingredient value so we're ready to add a new ingredient and what i need to do is i need to add this as the on click functionality so update field value needs to go in here for the button so when i click the button it does update field value and let's um you know i think there's going to be one more thing we have to do right which is when the new value comes in we need to grab that new value so let's let's not do anything just yet let's see let's see if the app reacts the way we want it to and then we can um we can access the uh we can do the thing where we actually listen for our value change and update in real time so let's do sugar here and let's say we want um you know we want to see the doctor very often so let's do 500 grams and is that a lot 500 grams i don't even know anything though i don't even know so so there we go so we've got sugar in our list of things right and let's add another one let's add apples and i'll say three apples because again this is just a string value so i don't necessarily need to write grams every time if i don't want to and what i want to take a look at right is let me actually let me refresh the page because i want to show you i want to point something out that's pretty cool i don't think it's working yet isn't it is it it is working we're saving we're saving this to the content type what we're not doing is we're not publishing it you can see it says changed so when i add when i add these values in it does change the content uh but it's not publishing it that's for sure it's the same as if i was just to you know write some new stuff here it would update the content type you can see saved a minute ago and it's going to auto save again which is cool so let's say i put in apples and i put 3 in and i hit add so it's going to add it to the list there it shows up in my list and you can see the auto save functionality again pretty quick but everything is working for you out of the box so really you just had to focus on kind of the local state management and making sure you're calling the correct functions to set the value but we've got it you know we've built it in such a way where everything else should be handled for you so you don't have to worry about manually like auto saving or anything like that cool can before we move on can we fix the window size or the iframe size here i'm already bugged by you scrolling up and down how should we do that so we've thought about that too oh look at this mark max truck has a question which is like can you control the height of an app in the editor good question mark so this this one is i think more important right like the styling we talked we would say we'd style it at the end but the height is actually super important because you want all of your content to at least show up regardless of what your styling looks like so what we've done is we've actually given you this kind of out of the box solution for such a thing so there's props.sdk.window which gives you some window functionality here and what i can do is i can say start auto resizer what this does is it fires off a function that's going to listen for the content inside of your iframe and it's going to try to automatically adjust the height of your iframe that way you can see all the content on page load it's not perfect there are some cases if you have super dynamic content that's always changing kind of the layout it could potentially have a few problems so we do offer also the ability to manually change it so as you can see here there's a way to stop the auto resizer and there's a way to manually update the height as well and you can imagine you can call this function as many times as you want which means that if you have some kind of dynamic layout logic you can also call this function at the same time to either cal call for a calculated height or you can put in you know a hard coded height whatever you want to do how do you question out of curiosity how do you detect the height changes is there an on on resize event on the iframe or do you do mutation observers or anything other thing fancy yeah i mean all of those options are available too i mean remember this is just a single page application that's inside of a window so any kind of manipulation you do to either the inner width or the outer width of the window you would you would be controlling anyways first of all in your application most likely which means that you'd have some code that would be able to detect or calculate the height of the window you of course can always find those measurements they're on the window object themselves if you want to do some kind of calculation um in our case i'm just going to do the start auto resizer because it works pretty much 99 of the time like i said there might be some very dynamic use cases where it doesn't quite fit your needs but that's usually not the case yeah my question was more how the the sdk does it out of cue curiosity uh the sdk i'm actually not too sure i haven't i haven't touched that part of the code in the sdk so i'm actually not too sure but i suspect it's using those measurements that are provided on the window object itself i mean that's that's how i would approach the problem so i think that i'm gonna have a look um the other thing we need to do when we do the auto resizer is we want to make sure it's not literally being called over and over and over again because this function says start auto resizer it means we call it once and it then just kind of does its thing we don't need to keep starting it over and over again of functional components right yeah so that's the thing this component gets called multiple times so we need to be where we need to be aware of that which means we also need to use this method called use effect which ensures that certain function and functions only get called say once per render or they only get called if certain things uh update for example um so i think in our uh do you need an entity you can either say we only want it to up update once um but i think actually we may want to yeah let's let's just have it update once and see what it does yeah let me just for the people that are not familiar with this whole concept of hooks and react and the the resource that is really the best for that is the react documentation and i still struggle to explain usefact to people that i haven't seen that before so if you're if you're new to that i recommend to check out the docs yeah and use effect i mean if you're familiar with older versions of react where you have like component will update or component did update for example use effect is similar in that regard it's basically a way for you to hook into the life cycle of the react component at a specific time in our case it would be like when a prop or a piece of state updates right so um the effects work it might be kind of subtle and you might not have realized it but actually now our app is not scrolling anymore it's filling up the full page as you can see so i can actually see the full you know the full layout of my app now it's it's not like squished inside of that inside of that space so i think to answer i forget who asked the question but to answer that question yes start auto resizer is something we offer and as you can see in like three lines of code here i was able to get that functionality working out of the box cool we have another question about the oauth and the personal token again can you suggest me to suggest me which case i go with ors as well as a personal token i think in the case of oauth the way i've used it before is when i'm integrating inside of another application so for example again with the jira application let's talk about the jira application if you're familiar with jira jira has its own interface right it's kind of like a board of tickets and um you'll notice that when you open a ticket you have third-party integrations right you'll have like maybe like a pagerduty or a zendesk or something like this that shows up in your jira ticket these are different applications other than atlassian's applications so if you were to say implement a contentful application inside of jira you would need to be able to have your application inside of jira access data from contentful and you might want to do that on a user basis right you might want to have the generalization where it's like anybody regardless of organization regardless of contentful organization can run your contentful app inside of jira and they can access entries inside of jira and this is where oauth would come into play our classic oauth inside of contentful is you would then have this oauth handshake so jira would present to you a ui that says like connect with contentful you'd click that button it would open up contentful's oauth flow you'd go through contentful's offload then you'd end back in jira but jira would have you know your oauth token and it would be able to request certain things on your behalf to populate ui inside of jira for example cool so oauth is really for like if you're outside of contentful and you want to integrate with contentful the app framework is if you're inside of contentful and you want to integrate with contentful or with third parties yeah i think for the context of apps what we're doing here so there shouldn't be a need for any token like at all right because if it's installed in the uh contentful space or environment the sdk and everything every code that we just show here is already authenticated and authorized to write to the contentful space that's correct and if you run into a scenario where you need to access some data in contentful and the sdk is not providing it to you let us know we'll try to face that problem let this guy know that yeah um it's honestly uh we try to make it so you can access all the things that make sense there might be some things that obviously don't make sense like organizational settings are not going to come through the sdk um but if you do find where you're running into a scenario where it's like hey this sdk is not providing me you know data that i think it should definitely let us know and we'll take a look at it so yeah um was that it for the questions for now and i don't know cool so yeah i mean we we have a working application this is a repeater field and i think we talked about potentially having the ability to remove one of these things is that correct yeah let's remove one yeah so again that's that's going to be um kind of similar functionality right i'm going to write a function here and again this is kind of bad habit where i'm writing it inside the component but let's ignore that for now where i say remove ingredient and the ingredient is going to be let's let's make it so we pass in the ingredient [Music] and what we'll do is slice or supplies david yeah i think actually what we'll do is a filter i'm kind of coming from an immutable aspect of things so that's kind of how i've gotten the habit of writing code so what i think i'll do is i'll take the current list that we've got here and i will filter it out right so if we have our list of ingredients and what i'm going to do is i'm going to filter it out where the ingredient.name equals the i dot name good call that's a little bit easier and nicer to read than my slice splice approach here i would say yeah i mean well i that's debatable because it depends on what you're comfortable with i'd say some people that are you know not as familiar with this kind of functional approach they might it might take them a second or two to understand what what's actually happening here um but you know that's that's developer experience and that's something that's on a per case basis that you'll have to worry about but in our case what i'm doing again just to quickly explain as i'm getting the current value of the fields i'm getting that list and i'm removing um i'm removing the items in the list where the current ingredient that i'm iterating over matches the ingredient name that i passed in and what i'll do is for each ingredient in the ingredient list i will also include this is going to look pretty ugly but i'll include a button um i'll include a button here that says remove and just read back my storybook app um let's take a look at the button stuff because i want to just quickly see what i can do here so if i go to this knob section we can see that there's different kinds of buttons i can have like button types for example i'm going to do a negative button that's going to make it red and if i look at so the knob button type that's the name of the prop type that i'd add to my button so if i add a button type and you can see typescript's already kind of it kind of knows what i want to do so i'll be negative here such a positive person usually all right well okay fine no comment because we're happy mistakes we want to remove them because they were happy mistakes okay so um what we've got is i think you were right with the red one though but i just wanted to make a very very great pun here uh red means red means uh bad or you know delete or something like this did you know that this is regional this is not a yeah this is not across the world yeah yeah asia rent is something green and red is something good and green something bad yeah that's really interesting actually because yeah that does change good luck with that one ui people yeah that's that's a problem for a different day and i'm not going to dive into that right now so i've got my kind of ugly looking list here of items with a button that says remove and um you know if i was to really spend more time on this i'd obviously clean this up i'd probably make it like a little x button or something really cool like a little animation that comes out from the side but for this you know let's just focus on the functionality still so on click is going to be i want to call my remove ingredient function right and the ingredient i want to remove is going to be the current ingredient which is i'm iterating over here which is i right so let's see if i wrote any bugs so first of all let me let me just reload this frame just to make sure we're up to date and so if i hit remove on three apples nothing does anything happen i think you have to re-render the component don't you i think i do as well um but here's the thing i hit remove on three apples and i did see it auto-save so if i refresh the entire page i believe that re-rendering re-rendering the yep we're not re-rendering components right so here's my bug i wrote the opposite logic um what i did was i i made a mistake in my filter code and i said that i actually only want to keep the things that i remove when in fact what i want to do is not keep the things right yeah so i i wrote my filter logic wrong first of all and second of all yes i think what we need to do is we need to listen for a field value change and re-render when that value change happens i think for that for me to make that work we have to connect the whole ingredient and we have that right can you show me the state again yeah so we have we have ingredients here coming from the value i think you need another usa don't you um potentially not i think i think what i'll try to do is i'll actually try to listen for a state change what i want to do is i want to make contentful the source of truth and i don't necessarily want to have a local list and a contentful list that i need to keep in sync for me that's going to cause a lot more bugs but how do you trigger than the the re-rendering without calling set state gotcha yeah so i think i think what we can do is if i go to props.sdk.field and if i look at the field values i believe there's an on value changed here right and what one value change does is it has a callback method and when the value changes we have the ability to basically re-render if we want to i guess yep um i'm actually not entirely sure how to do that inside of a stateless component like how to just ask for the component itself to re-render that's what i'm saying you have to call set state or a setter i think actually i mean if i was to look at the react documentation there might actually be a way for it to like just say like force update if i wanted to like just like have this component like update itself um yeah but what what you could do is you could change line 12 and make it use your state right and then you have this letter available okay i see what you're saying yeah that's a good call yeah so set ingredients and yeah i was thinking about it like i would just i would just do the whole thing but actually we don't need to do that what i can do is i can say use state here and there you go yeah exactly got it yeah i think that's a good call and what we can do here is we can just make sure we refresh so when we hear that there's a value change what we'll do is we'll set ingredients and we'll just grab i guess the we'll just grab the latest value right uh field isn't it passed down and on value change it actually probably is let's take a look fallback it does it it has the value so actually that's even a little bit more bam here we go cool uh before we check uh if that's gonna work mark has another question about access roles and permissions um so he asked can you access what teams role or permissions the current user has with the sdk so if i look at props.sdk dot access there's actually a method there's methods on here well there's one method called can and you're going to have to read the documentation a little bit more on this but basically as you can see in typescript it's showing me can this user read can this user update i think there's a few other things and this returns a boolean i did not know about this method yes so thank you very much sir yes of course there's actually a few overloads here as you can see up where'd it go uh how do i get that back there's a few overload methods uh there's so there's four different versions of can and they do different things you'll have to read the documentation but this basically will let you know if users can do certain things so that's kind of what i was getting at uh this is a newer feature so people that have worked with the sdk in the past they might be surprised that this exists this is definitely a newer feature i think it's a couple months old um so if you didn't realize it exists that's uh that's why but this is what i was talking about with like you can dynamically change the ui if the user can or can't do certain things you're welcome to like you know hide certain features or something yeah yeah so we give you we give you that that functionality as well with the sdks throw an error if i for example would just set value and the user is not a allowed to do that or maybe the field is disabled or something yeah yeah so if you try to hack it for example or if you've got a user that's kind of sneaky and knows the javascript that's going on we're still going to block you from a backend perspective like your users still won't be able to make that call if you use the sdk and the user doesn't have the ability to do something yeah you're going to get an error cool let's bring that home david yes so we've got the on value changed which helps us in real time uh kind of update our state so let's again take a look here at our ingredients list let me refresh hopefully we didn't write any bugs ingredients.map is not a function [Music] this should be a function what we can do is if the list doesn't exist we'll just have it be a blank array let's see if that fixes the problem but it's probably in line in the render method no are we iterating not over list or something here we're iterating over the ingredients which i have set up here fair enough yeah fair enough and if it's an empty array it should just not show anything it's certainly possible that this is causing a problem because we did just add this code let me let me comment this out and see if that uh changes anything yeah maybe we want to log value okay yes the value is with list good call so we'll do list and that was probably the bug let's just refresh again [Laughter] um i wonder if the reason we've got this going on is because on the value change we're setting the state which potentially uh is setting are we setting the value again let's comment this out again just to play it safe i think what we'll need to do is we'll need to probably have some if value.list um we probably need to do some kind of comparison logic to make sure we're not setting ingredients all the time is my guess because we are calling on value change oh it's just interesting though let's keep it let's keep it um let's keep it simple right let's say if the current value does not equal the ingredients value on the value change then set the ingredients of value.list yeah you're missing a length length there in line 19. yep um so i'll do length cool uh i think maybe that should hopefully get rid of our stack overflow thingy that we've got going on okay nice i'm feeling fairly confident let's add some stuff here so 500 grams of sugar again because we love sugar and now let me refresh just to verify that this data is persisting yep okay and if i remove apples there it goes from the list and persisting and i'm just waiting to see over here so there's the autosave that's the and if i refresh cool so now we have our add remove logic this is a repeater field right this is we built a repeater field meaning we've got the ability to add things to a list and remove things from a list now this is when i explain instance parameters now make it configurable yeah sure sure so um what i think we can i'm gonna take a one minute break here but you you can do that cool so um what like instance parameters what they do is they allow you to configure things per field so as you can imagine i've got this ingredients field here which means that this is specifically for ingredients let's say i had a different field which is not for ingredients i might not want to have name or amount for example i might want to have you know some kind of other values there so i can actually configure this per field which is to say that if i go into again my organization settings when i go to my apps and i go to my ingredients list app will remember that here i can actually have instance parameters for the specific fields so when i click on this it's going to give me a display name this is going to be shown to the user and i'll show you what this means in a second so i think what we want to do is we want to have two things right we want to have what the name of the field is in our repeater list and what the value is in our current hard-coded option we have name and amount but you can imagine those two things can be very dynamic if we want so let's say that we want to have the title of the field and this will be short text and there's going to be no default value here and we also want to have the value of the field and this is going to be short text and no default value and let me save this because i do need to save the app definition i'm making changes to an existing app definition which means i do need to be careful i shouldn't do this to like a production app for example unless i know what i'm doing but in this case that's why it's asking me you know it's confirming that i actually want to do this and it's saying this will affect the installations so i'm going to hit save and back over in my space because again this is a per space per environment configuration i'll go to the content model i'll go to the blog post and the ingredients list and over here in the appearance tab you'll notice that where we used to have a blank space before we now have these two values right so this is where i can start to get a little bit dynamic and i can say you know let's say i actually don't want it to be name and amount i want it to say ingredient and measurement right let's say i want for this specific blog post content type i want my ingredients list app to have these two values let's say so let me save that and save the content type and back in our uh app what i want to do is i want to make it so this display for the users actually shows that under the hood i'm not going to change the value because it's going to mess with my data structure you of course could change it under the hood if you wanted to as well it's a little more work but i'm just going to make it so the displays here are dynamic and the way i'm going to do that is i'm going to first just kind of take a look at what i'm actually working with so console.loggingtheprops.sdk dot parameters and this is where i can access different parameters and this goes back to salma's question which was how do i you know save and add and modify configuration for for an application this is how you do it so apps have different sets of parameters one of them is installation parameters which is kind of like the global when the app gets installed these parameters are accessed throughout the space and one of them is instance which is what we're going to be working with so i'm actually going to be able to dynamically get those values that i typed in for the blog post content type specifically the last one is invocation this one you don't use this often it's more for like dialog modals and things like that which is you can pop a dialog modal with specific values like it's kind of like just like a random json object that you can pass to a dialog model so let me log out my instance parameters just so we get an idea of what we're working with here you can see here here's the log of my instance parameters so there's a title and then there's a value what i'm going to do here is instead of hard coding this label text instead going to make it dynamic and have it go props.sdk.parameters.instance.title right and this one i'm going to have it say value and if we go back into the web app you'll see here that i've got ingredient and measurement and now again this is how users can now configure your application without having to go into the code let's say i don't want to call this ingredient i want to switch it back to you know something else i go into the content model i go to blog post i go to ingredients appearance and here let's just say like food for example let me save that and back in my entry you can see that that got updated cool that's pretty decent for today huh what do you think yeah i think i think that covered a lot of stuff and i think it shows like you know how you can make your app configurable to the user and generalize it for the user as well as you know not have to deal with all the webpack stuff which i really like don't we all yeah so what do you think should we should we polish that and maybe push the app later to github or how do you feel about it yeah we can do that i mean i'm not really happy with the visual aspect of the app right now so i definitely would like to clean it up a bit but i think this app is fairly useful for a lot of people it's it's simple enough where you can easily like install it to any space that has a json field it doesn't require much configuration so i think it's a it's very valuable yeah for me the one thing uh um do we want to do five more minutes and generalize it a little bit more or should we call it day for me it was like a little bit like we would have this app and you could define the different fields um like dynamically right so the way that i thought about it was like we have one string field which is then like title amount unit and i don't care about the fact that it's all strings um that we store but this way we could have not only two fields but we could have for example four or six or eight whatever the person wants to deal with right i'm not sure i'm totally following you so you're saying actually having more input fields that correspond to more values yeah right now we only have two two fields right per ingredient or whatever we define i think to have the real value out of this application it would be okay here you have a repeater field and define the fields that you're interested in they can be all strings or not doesn't matter and then everything adjusts automatically yeah i think i think that's definitely possible to do um i don't i don't know if we really have time for it because what what you're talking about is actually instead of the list itself being dynamic because the list is just going to you know eventually we would just have the list iterate over all the keys inside of our object right over name over a mount over anything that you create and here's where here's what you're talking about is this text field would actually not be hard-coded this would be kind of like how we're mapping the list we would map text fields and we'd be able to add text dynamically yeah you're right takes probably a little bit longer than five minutes because we would have to grab object keys on the instance parameters somehow and then kind of untangle everything yeah um there there's there's definitely more it's totally possible i understand what you're saying now it's i think that that would be very valuable uh but yeah i think it's just gonna be a lot more work and it's it's more just tedium of setting it all up and getting state management right cool yeah i know for that i i think we made it uh thank thanks david i think we had a we had a good session here and yeah thanks everybody for watching let me do we have some should we plug the resources again no i think we did that very fairly good in the beginning so for everybody who is interested in the next live streams you can have a look at contentful.com oh no no you should stop sharing is that me sorry that is me all right let me just clean up my screen here for a moment um so we've got a few more live streams coming up um so i'm ah i'm gonna yeah let me just go you can find live streams currently on content for developers or contentful.com events so what you can do here is you can type decide if my what no type of event we're gonna go with livestream here so this is what we currently have lined up so we have the app framework something with more apps we have cicd pipelines with shai and tyler coming up and if you want to join for the future we always have fun having you and i think's super nice so if you have questions um or comments um reach out to us or hang with uh hang out with us on slack on the contentful.com slack and that's pretty much it i think we made one hour and 32 minutes of hardcore app framework live coding we had a thing we're gonna share out the app uh after david polished it a little bit and made the buttons a little nicer with a little access on twitter our newsletter probably and the slack org and with that thank you everybody for watching and we see you latest
Info
Channel: Contentful
Views: 9,385
Rating: undefined out of 5
Keywords:
Id: OtmV3TPTbRs
Channel Id: undefined
Length: 92min 50sec (5570 seconds)
Published: Wed Nov 25 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.