About Features Downloads Getting Started Documentation Events Support GitHub

Love VuFind®? Consider becoming a financial supporter. Your support helps build a better VuFind®!

Site Tools


Warning: This page has not been updated in over over a year and may be outdated or deprecated.
videos:code_generators_2

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
videos:code_generators_2 [2020/10/13 10:48] – created demiankatzvideos:code_generators_2 [2021/10/22 14:44] (current) – [Video 12: Code Generators, Part 2: Creating a Controller] demiankatz
Line 1: Line 1:
 ====== Video 12: Code Generators, Part 2: Creating a Controller ====== ====== Video 12: Code Generators, Part 2: Creating a Controller ======
  
-The twelfth VuFind instructional video discusses VuFind's model-view-controller architecture and demonstrates how to use VuFind's code generation tools to build a custom controller and customize URL routes.+The twelfth VuFind® instructional video discusses VuFind®'s model-view-controller architecture and demonstrates how to use VuFind's code generation tools to build a custom controller and customize URL routes.
  
-Video is available as an [[https://vufind.org/video/Generators1.mp4|mp4 download]] or through [[https://www.youtube.com/watch?v=WxU4D4Fchco&feature=youtu.be|YouTube]].+Video is available as an [[https://vufind.org/video/Generators2.mp4|mp4 download]] or through [[https://www.youtube.com/watch?v=WxU4D4Fchco&feature=youtu.be|YouTube]].
  
 ===== Related Resources ===== ===== Related Resources =====
Line 14: Line 14:
 // This is a raw machine-generated transcript; it will be cleaned up as time permits. // // This is a raw machine-generated transcript; it will be cleaned up as time permits. //
  
-:!: Coming soon.+ welcome to the second video on code 
 +generators 
 +this month we are going to talk about 
 +customizing routes 
 +and controllers in order to add new 
 +functionality to viewfind 
 +a viewfinder is built using the model 
 +view controller model 
 +which essentially means that the 
 +software is 
 +divided into a few distinct portions 
 +which allows for separation of concerns 
 +and can make it easier to customize 
 +so there are the views which are for 
 +displaying data that's our theme system 
 +there are the controllers which are 
 +the the pieces of code that contain the 
 +business logic of viewfind that actually 
 +make things 
 +happen and then there are the models uh 
 +which represent the data within the 
 +system 
 +and there are of course some sort of 
 +services that help bring all of this 
 +together 
 +but the the important point is 
 +the controllers are make think the 
 +controllers are what make things happen 
 +the views are what display things to the 
 +user 
 +uh and today we're going to make some 
 +new things happen 
 +and display some new things to users and 
 +we're going to use 
 +code generators to make the job easier 
 +another concept that's important for 
 +understanding all of this 
 +is uh the router 
 +so viewfind uses laminas's router 
 +for mapping urls to controllers 
 +so whenever you access a url under 
 +viewfind's control 
 +the router picks apart the pieces of 
 +that url and uses them to decide which 
 +controller code to run 
 +and that's really how everything happens 
 +in viewfind 
 +routes are defined through configuration 
 +uh which can be put 
 +anywhere in the the frameworks 
 +configuration stack but currently 
 +most of you finds routes are found 
 +inside the viewfind 
 +code module and i'm just going to show 
 +you 
 +in the code under module viewfind config 
 +and module.config.php at the very top of 
 +the configuration there's this router 
 +routes section and this contains 
 +a number of predefined routes 
 +you can override these or add to them in 
 +your own local module if you need to 
 +and we'll get to that a little later but 
 +i just wanted to show you as a useful 
 +example 
 +the default route which is what 
 +viewfind will use to match urls if it 
 +finds no 
 +more specific route later in the 
 +configuration 
 +this is using a segment routing method 
 +which is what allows us to define the 
 +route with these little named 
 +placeholders 
 +brackets indicate optional portions 
 +so what this is saying is that if you 
 +have a url that starts with a slash 
 +and then optionally has some more text 
 +and maybe 
 +optionally has another slash and some 
 +even more text 
 +that first chunk of text between slashes 
 +is going to be used as a controller 
 +variable 
 +and that second part is going to be used 
 +as an action 
 +we have some constraints on these 
 +parameters so the route will only match 
 +if we have alphanumeric or underscores 
 +or dashes 
 +in the in the values 
 +and we also have some defaults so if one 
 +of these sections 
 +is omitted uh it'll use a default 
 +instead 
 +so what this is showing us is that when 
 +you go to view finds 
 +base url you go to the home action of 
 +the index controller 
 +but if you put names into the url 
 +you override these defaults and you 
 +affect 
 +which controller and which action get 
 +executed 
 +so for today i'm going to create a new 
 +controller called tutorial and put some 
 +functionality into that 
 +so based on this route you can see that 
 +if i were to 
 +just add slash tutorial to a viewfinder 
 +url what's going to happen 
 +is action is going to default to home 
 +because i omitted it 
 +and controller is going to get 
 +overridden with tutorial 
 +so let's just try that and see what 
 +happens 
 +not surprisingly i get an error message 
 +telling me 
 +controller is not found this is to be 
 +expected 
 +because we don't have a tutorial 
 +controller yet 
 +uh i should also note that i'm seeing 
 +this detailed error message 
 +uh because i've turned on development 
 +mode in viewfind 
 +if i had not turned on development mode 
 +i would see 
 +a generic message that would be far less 
 +informative 
 +it's always a good idea to have 
 +development mode on while you're 
 +developing 
 +because it helps with troubleshooting 
 +like this 
 +that all being said let's go ahead and 
 +make ourselves 
 +a tutorial controller so that we can 
 +start attaching some behavior 
 +to this url 
 +i'm going to assume that you already 
 +have a local module called tutorial 
 +and that you're somewhat familiar with 
 +the plug-in code generator 
 +because we talked about both of those 
 +things last month 
 +so i'm going to go to my viewfinder home 
 +directory 
 +and i am going to run the plugin 
 +generator to build myself 
 +a new controller inside my tutorial 
 +module 
 +so i do this by saying php public 
 +index.php 
 +generate plugin and i'm going to call 
 +my controller tutorial backslash 
 +backslash 
 +controller backslash backslash tutorial 
 +controller so the first part of the 
 +namespace 
 +will tell the plugin generator to 
 +generate code in the tutorial module 
 +the fact that the second part says 
 +controller will tell it that we're 
 +building a controller and then it will 
 +create 
 +a tutorial controller class 
 +uh one important feature of the plug-in 
 +generator that i'm going to take 
 +advantage of here 
 +is that the last parameter you can 
 +specify 
 +is the name of an existing factory for 
 +building 
 +your new class if i were to omit this 
 +parameter it would just create a new 
 +empty factory that i could fill in but 
 +because 
 +all of viewfind's controllers extend an 
 +abstract base class that provides some 
 +helpful functionality and requires 
 +some specific constructor parameters i'm 
 +going to use 
 +viewfinder's existing default controller 
 +factory which is named 
 +viewfind backslash backslash controller 
 +backslash backslash abstract base 
 +factory 
 +so this will tell the generator 
 +to reuse that existing factory to build 
 +my new class 
 +instead of building a new empty factory 
 +that i would have to fill in 
 +and also a reminder that i have to 
 +double up all of these backslashes 
 +because of the quirks of the command 
 +line 
 +but what i'm actually generating are 
 +class names with single backslashes in 
 +them as one would expect 
 +so there we go i have just created 
 +a tutorial controller and configured it 
 +in my local module 
 +so now if i go back over here and i 
 +refresh this page 
 +i have a new error message it now says 
 +error controller cannot dispatch 
 +this is because i created a controller 
 +and viewfind was able to find it 
 +but i haven't defined the home action 
 +that the route is 
 +trying to execute so my next 
 +task is to define a home action 
 +so i'm going to go over to my editor 
 +and go into my tutorial module where i 
 +will see that 
 +the code generator has created this 
 +controller 
 +folder under my source code and built an 
 +empty tutorial controller 
 +so in lobinos mvc the framework that 
 +we're using 
 +controllers are organized as a class 
 +containing methods 
 +whose names end with action so 
 +because we want to route to a home 
 +action i need to create a public 
 +function called home action 
 +and put something into it uh 
 +as i mentioned we're using a model view 
 +controller system 
 +where the views are separated from the 
 +controllers 
 +and the way that these two pieces of the 
 +system communicate with each other 
 +is that every action returns what'
 +called a view model 
 +which is just a container full of values 
 +that the view will have 
 +access to uh to get started with 
 +we don't need to send any values at all 
 +we're just going to 
 +go with the default template render to 
 +begin 
 +so we can return an empty view model 
 +with no special data 
 +and as i mentioned viewfinder 
 +controllers generally 
 +extend this abstract base class which 
 +includes 
 +a helper function called create 
 +view model which will give you an empty 
 +view model 
 +automatically with some useful values 
 +pre-populated 
 +so i'm just going to start out here with 
 +this simple 
 +uh public function home action that 
 +simply returns 
 +this create view model with no 
 +parameters 
 +so i've now defined an action that 
 +returns the right kind of value so let'
 +refresh this page and see what our next 
 +error message is 
 +all right we've got a new error message 
 +we were now able to 
 +find a controller and dispatch an action 
 +but now uh the framework is trying to 
 +render the template associated with our 
 +action 
 +which by naming convention is going to 
 +be tutorial for the controller slash 
 +home for the action but we've created no 
 +such template yet 
 +so viewfind couldn't find it so it 
 +created 
 +yet another error so let's go 
 +build a template in our theme so that we 
 +can 
 +resolve this latest problem 
 +so if i go to my tutorial theme and my 
 +templates directory 
 +i just need to create a folder in here 
 +called tutorial to match my controller 
 +and then i want to create a file in here 
 +called home.phtml 
 +to match the name of my action and the 
 +phtml extension just represents 
 +a php html template and for now all i'm 
 +going to put in here 
 +is hello world 
 +so now all of my pieces are in place 
 +i have uh created a controller 
 +and a route and a template so if i 
 +refresh the page 
 +hello world i have a message displayed 
 +so this is how you create a new action 
 +but you know displaying a piece of text 
 +is not that exciting 
 +why don't we look into how we can 
 +actually interact with this a little bit 
 +so suppose rather than saying hello 
 +world i wanted to be able to specify my 
 +name 
 +uh as a parameter on the command line so 
 +i could add question mark name equals 
 +damien 
 +and then i would like this to say hello 
 +damien 
 +instead of hello world the framework 
 +makes this quite easy to achieve 
 +first i need to go up to 
 +my tutorial controller and add 
 +some some logic 
 +so every controller in the framework has 
 +access to a helper called params which 
 +you can access 
 +uh by calling this 
 +params with parentheses 
 +and the params helper has various 
 +methods on it you can use for 
 +extracting values from the incoming 
 +request 
 +there is a from query method where you 
 +can specify the name 
 +of a parameter and also a default value 
 +so if i say 
 +name equals this params from query 
 +name comma world that means it will set 
 +the 
 +name variable equal to the value of the 
 +name 
 +parameter in the query and if that is 
 +undefined 
 +it'll just use world instead 
 +so i also mentioned of course that view 
 +models are used for passing 
 +values to the view and this create 
 +view model helper function that you have 
 +access to 
 +in viewfinds controllers lets you 
 +specify 
 +an array of values to pass so i'm just 
 +going to create an array 
 +that includes this name value i've just 
 +pulled out of the request 
 +and passes it through as name 
 +having done this uh i will now have 
 +access to a name variable in my template 
 +so i can replace the word world here 
 +with a php echo tag 
 +that displays this escape html 
 +name note that it's always important to 
 +remember 
 +to html escape values that you display 
 +to 
 +prevent injection attacks 
 +or simply garbled displays 
 +so now just by pulling a value from the 
 +query in the controller 
 +passing it to the view displaying it in 
 +the view 
 +i have some interaction in place 
 +and sure enough when i refresh the page 
 +it says hello damian 
 +and if i take my get parameter back off 
 +again 
 +the default kicks in and i still get 
 +hello world 
 +since we've made some nice progress here 
 +i'm just going to take a moment and 
 +do a git commit 
 +to save all of this 
 +progress and so that when i do some 
 +subsequent 
 +work i can more easily show you 
 +what has changed 
 +since this initial baseline was set 
 +so it's nice to be able to specify get 
 +parameters but suppose you want to 
 +actually 
 +seamlessly integrate a value into 
 +the url itself so say for example 
 +we want to be able to go to tutorial 
 +slash home 
 +slash custom location and 
 +have the display tell us that we have 
 +entered custom location 
 +if i do this right now i get 
 +a no route match instance provided 
 +because i've created this three part 
 +route with multiple 
 +separated values and there is no route 
 +configuration in viewfind that knows 
 +what to do with this 
 +the default route expects only two 
 +pieces and we've just provided three 
 +so if we want this kind of a route to 
 +work 
 +we need to generate a custom route 
 +fortunately we have a command line 
 +generator tool 
 +that will do exactly that 
 +so if i go back to the command line 
 +where i'm in the viewfinder home 
 +directory 
 +i can run php 
 +public index.php generate 
 +dynamic route 
 +and then i need to specify 
 +the name of this route which i'm going 
 +to call 
 +tutorial dash home uh the route name 
 +is important both because it's used as 
 +the key 
 +in the configuration array so that you 
 +can potentially override it by name 
 +in a later part of the configuration 
 +process 
 +it's also important because in templates 
 +you can use 
 +the url view helper to convert a route 
 +name 
 +into an actual working url which is a 
 +great way to abstract your urls and make 
 +it possible to override and customize 
 +them 
 +anyway i've named my route tutorial home 
 +here 
 +then i need to say which module or 
 +rather i need to say 
 +which controller i'm using the tutorial 
 +controller 
 +and then i need to provide uh the 
 +remainder 
 +of the route that i want to match so 
 +i'm going to say home slash colon 
 +location this is using the router'
 +segment syntax where you can put 
 +any name beginning with a colon to use 
 +as a placeholder 
 +that will be passed through to your 
 +controller as a route parameter 
 +so the idea here is that we want to 
 +allow 
 +a location name to be appended after 
 +the home part of the url 
 +finally i say tutorial for the name of 
 +the 
 +module where i want this configuration 
 +to be added 
 +so when i hit enter here 
 +it automatically makes some changes to 
 +my tutorialsmodule.config.php 
 +i should also note that dynamic route is 
 +just one of several 
 +uh route generating tools that viewfind 
 +includes you can also create 
 +static routes for simple pages that 
 +don't take segment parameters 
 +uh and you can create record routes for 
 +linking to things that act like you find 
 +standard record view 
 +you can find more details on all of this 
 +on the generator page of the wiki 
 +but for now let's just take a look using 
 +git diff 
 +at what the generator just did for us 
 +and as you can see it created 
 +a route named tutorial home like i asked 
 +it to 
 +it's a segment route because i used 
 +the appropriate generator to create 
 +segment routes 
 +and the full route is slash tutorial 
 +slash home slash 
 +location placeholder it got the tutorial 
 +part from the controller name i provided 
 +and the rest from the action i specified 
 +and then it has defaults of tutorial 
 +controller and home action 
 +because we want those values to be 
 +hard-coded in because we don't have 
 +controller or 
 +action segments in the route match 
 +so let's see what that did for us 
 +if i go back over here 
 +and refresh the page sure enough 
 +uh i no longer have an error because 
 +there's now a valid 
 +route that understands what to do with 
 +tutorial slash home 
 +custom location but i just have my 
 +default hello world message 
 +because i haven't done anything with 
 +that route parameter yet 
 +thus i need to go back to my code again 
 +and back to my controller 
 +and as i mentioned the controller'
 +params helper can get 
 +values from a variety of places and from 
 +the route 
 +is one of those places so i can say 
 +location equals 
 +this params from route 
 +specify location which matches that 
 +segment name 
 +uh in the route configuration we just 
 +looked at 
 +and just with uh just as with query 
 +parameters 
 +i can also provide a default value 
 +should that 
 +be omitted so i'll just say default 
 +location here 
 +and i need to pass that location value 
 +along to the view 
 +through the view model so i'm also going 
 +to add 
 +down here location key to 
 +point to the location variable 
 +save that go over to my template 
 +and now i can just say you are in 
 +and again i use a php echo tag 
 +to display an escaped version of the 
 +location 
 +that comes through from the route 
 +now if i go back and refresh again hello 
 +world you are in custom location 
 +i can add my name to this and it will 
 +say 
 +hello damien you are in custom location 
 +pretty neat so these are two different 
 +ways you can provide values 
 +from the url and communicate them to 
 +your controller 
 +and this explains how a lot of the urls 
 +in viewfind 
 +actually work so 
 +let's just do uh one more thing 
 +what if we wanted to have 
 +a less complicated url we don't like 
 +this home portion 
 +so we'd like to just be able to say 
 +tutorial custom location right now if i 
 +do that of course i get 
 +cannot dispatch because there's no such 
 +thing in my controller as a custom 
 +location action 
 +but we can take advantage of the router 
 +to just change the way the tutorial 
 +controller behaves 
 +and make this a little simpler to 
 +build our urls all i need to do 
 +is go into my tutorial module 
 +and edit the configuration there 
 +so let's find my route down here 
 +so right now this route is very specific 
 +it has to have slash tutorial slash home 
 +slash in it or it won't match and it 
 +also has to have some kind of a location 
 +placeholder 
 +but let's make more things optional 
 +so first of all we don't want to say 
 +home anymore that's not interesting to 
 +us 
 +uh next let's make the location 
 +value optional so that if you leave it 
 +off you can have a default 
 +let's also make this trailing slash 
 +optional we'll wrap another pair of 
 +brackets around 
 +so now if you go to 
 +[Music] 
 +tutorial by itself you're going to get 
 +the home action if you go to tutorial 
 +slash 
 +something you're still going to get the 
 +home action because it's 
 +set down here as the default but what we 
 +need to do now 
 +is add a default value for this location 
 +placeholder 
 +so that something gets passed through if 
 +it is omitted 
 +i'm going to say default route location 
 +because this will be useful for 
 +demonstrating something helpful 
 +uh the other thing that we might 
 +consider doing 
 +is adding a constraint for our location 
 +placeholder 
 +these default controller and action 
 +placeholders are actually 
 +meaningless in this context because 
 +these values can't be passed in but 
 +they're included in all of youfind'
 +routes just as sort of a safety 
 +mechanism and example 
 +but since location is something that 
 +users can provide input to we might want 
 +to control what characters they're 
 +allowed to pass through in that position 
 +to protect against attacks or unexpected 
 +behavior 
 +so i'm just going to put the same 
 +constraint 
 +on location that is used for controller 
 +and action 
 +uh to require it to start with a letter 
 +and then 
 +follow that with the sequence of letters 
 +numbers and separators 
 +so with all of this saved if i 
 +go back into the browser 
 +and refresh my page 
 +now i'm at my shorter version of the url 
 +and it's working again because the 
 +router matched this pattern 
 +and took us to the home action and 
 +passed through all of the values 
 +the other thing i wanted to show you is 
 +that if i leave 
 +off this location placeholder 
 +it now says i'm in default route 
 +location 
 +that is because i specified a default 
 +value for location in the route 
 +and even though my 
 +controller when it reads the location 
 +from the route 
 +uses this default location value if the 
 +placeholder is missing 
 +the router default is going to get 
 +applied first and that's going to take 
 +precedence 
 +over the default in my controller 
 +so that's all i wanted to show you today 
 +you should now know how to build routes 
 +and how to build controllers and also 
 +perhaps 
 +understand a little bit better about how 
 +user input from the browser 
 +flows through into viewfind's internals 
 +and how data gets displayed 
 +uh if you don't want to build a whole 
 +new controller there are also other 
 +generators you can consider using such 
 +as 
 +the extend class generator that you can 
 +use 
 +to override an existing controller 
 +in your custom module so you could 
 +override just one method or you could 
 +add a method to an existing controller 
 +you can also as i mentioned use route 
 +names 
 +to override specific routes in your 
 +local module if for example you wanted 
 +to change the text that displays in the 
 +url for certain kinds of functionality 
 +these are all things i'd be happy to 
 +demonstrate on a future video if there'
 +interest 
 +so let me know in any case 
 +thanks again for your attention and i 
 +hope this has been helpful 
 ---- struct data ---- ---- struct data ----
 +properties.Page Owner : 
 ---- ----
  
videos/code_generators_2.1602586128.txt.gz · Last modified: 2020/10/13 10:48 by demiankatz