├── LICENSE.md ├── README.md ├── acknowledgements.md ├── courseSections ├── section0.md ├── section1.md ├── section10.md ├── section11.md ├── section12.md ├── section13.md ├── section14.md ├── section15.md ├── section16.md ├── section17.md ├── section2.md ├── section3.md ├── section4.md ├── section5.md ├── section6.md ├── section7.md ├── section8.md └── section9.md ├── images ├── addedRemote.png ├── baseHomepage.png ├── blankHerokuApp.png ├── blankNavbar.png ├── bundleInstall.png ├── c9InitialReadme.png ├── clutteredHomepage.png ├── codeAnywhereInit.png ├── codeAnywhereLandingPage.png ├── codeAnywhereSignup.png ├── colourPalette.png ├── contactWireframe.png ├── containerSetup.png ├── cookieText.png ├── copySSHLink.png ├── createReadme.png ├── editOnGit.png ├── emptyRepo.png ├── fileTree.png ├── finalTree.png ├── finalWireframe.png ├── firstWireframe.png ├── fullLogo.png ├── gitCommit.png ├── gitStatus.png ├── glyphicon.png ├── goodJob.png ├── graph.png ├── herokuCreated.png ├── imageWireframe.png ├── indexErb.png ├── navbarBrand.png ├── navbarTitle.png ├── navigateToCollaborators.png ├── newRepo.png ├── nonRunning.png ├── octocat.png ├── pairProgramming.png ├── repoSetup.png ├── rspecPass.png ├── rvmInstall.png ├── specFolderStructure.png ├── styledHomepage.png ├── tdd.png ├── travisIntegrate.png ├── travisOutput.png ├── travisProfile.png ├── travisSignup.png └── tsPrototype.png ├── navigation.md ├── precourse.md └── tasks ├── task1.md ├── task2.md ├── task3.md ├── task4.md ├── task5.md ├── task6.md └── task7.md /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## creative commons 2 | 3 | # Attribution-NonCommercial 4.0 International 4 | 5 | Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. 6 | 7 | ### Using Creative Commons Public Licenses 8 | 9 | Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. 10 | 11 | * __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors). 12 | 13 | * __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees). 14 | 15 | ## Creative Commons Attribution-NonCommercial 4.0 International Public License 16 | 17 | By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. 18 | 19 | ### Section 1 – Definitions. 20 | 21 | a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. 22 | 23 | b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. 24 | 25 | c. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. 26 | 27 | d. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. 28 | 29 | e. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. 30 | 31 | f. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License. 32 | 33 | g. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. 34 | 35 | h. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License. 36 | 37 | i. __NonCommercial__ means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange. 38 | 39 | j. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. 40 | 41 | k. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. 42 | 43 | l. __You__ means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. 44 | 45 | ### Section 2 – Scope. 46 | 47 | a. ___License grant.___ 48 | 49 | 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: 50 | 51 | A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial purposes only; and 52 | 53 | B. produce, reproduce, and Share Adapted Material for NonCommercial purposes only. 54 | 55 | 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. 56 | 57 | 3. __Term.__ The term of this Public License is specified in Section 6(a). 58 | 59 | 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. 60 | 61 | 5. __Downstream recipients.__ 62 | 63 | A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. 64 | 65 | B. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. 66 | 67 | 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). 68 | 69 | b. ___Other rights.___ 70 | 71 | 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. 72 | 73 | 2. Patent and trademark rights are not licensed under this Public License. 74 | 75 | 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties, including when the Licensed Material is used other than for NonCommercial purposes. 76 | 77 | ### Section 3 – License Conditions. 78 | 79 | Your exercise of the Licensed Rights is expressly made subject to the following conditions. 80 | 81 | a. ___Attribution.___ 82 | 83 | 1. If You Share the Licensed Material (including in modified form), You must: 84 | 85 | A. retain the following if it is supplied by the Licensor with the Licensed Material: 86 | 87 | i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); 88 | 89 | ii. a copyright notice; 90 | 91 | iii. a notice that refers to this Public License; 92 | 93 | iv. a notice that refers to the disclaimer of warranties; 94 | 95 | v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; 96 | 97 | B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and 98 | 99 | C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. 100 | 101 | 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. 102 | 103 | 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. 104 | 105 | 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License. 106 | 107 | ### Section 4 – Sui Generis Database Rights. 108 | 109 | Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: 110 | 111 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database for NonCommercial purposes only; 112 | 113 | b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and 114 | 115 | c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. 116 | 117 | For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. 118 | 119 | ### Section 5 – Disclaimer of Warranties and Limitation of Liability. 120 | 121 | a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__ 122 | 123 | b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__ 124 | 125 | c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. 126 | 127 | ### Section 6 – Term and Termination. 128 | 129 | a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. 130 | 131 | b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: 132 | 133 | 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or 134 | 135 | 2. upon express reinstatement by the Licensor. 136 | 137 | For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. 138 | 139 | c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. 140 | 141 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. 142 | 143 | ### Section 7 – Other Terms and Conditions. 144 | 145 | a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. 146 | 147 | b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. 148 | 149 | ### Section 8 – Interpretation. 150 | 151 | a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. 152 | 153 | b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. 154 | 155 | c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. 156 | 157 | d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. 158 | 159 | > Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. 160 | > 161 | > Creative Commons may be contacted at creativecommons.org 162 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | A day as a Developer 2 | ==================== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](./navigation.md) 5 | 6 | What is this all about? 7 | ---------------------- 8 | 9 | As an agile team member working in tech you have the fortune/misfortune to work with developers. We try to work using agile methodologies and this includes the concept of the cross-functional team. This is about the big picture. A team has a goal that it needs to achieve, how it gets there should be the preserve of the team and this should not be hampered by job titles and/or narrow working silos. Having a common level of understanding and a common language across the team can help to break down these silos creating a highly performing team. 10 | 11 | Now when it comes to obscure language and weird acronyms, I have to admit, developers need to shoulder much of the blame. So think of this course as a tortuous apology and, as the quickest way to learn something is to do it, you will now get to spend the next day as a developer. 12 | 13 | So how do you "be a developer". The truth is that the job requires a broad range of skills and the willingness to dive into something that you know almost nothing about, learn it, use that knowledge to fix your current problem and then find another problem and do it all again. It's about leveraging a large range of skills, technologies and languages putting them all together and making things that work, even when it is particularly bewildering. That's the ideal anyway. 14 | 15 | This course is designed to mimic this process in a structured way. The first half will walk you through key concepts and provide some foundational knowledge. As we move on things will start to get a little harder, there will be fewer explicit answers and you will need to find and provide your own solutions. Hopefully, it will push you out of your comfort zone while teaching you a few new things along the way. 16 | 17 | Let's begin! 18 | 19 | Precourse and Setup 20 | ------------------ 21 | 22 | Prior to this course you should have completed everything in the [Precourse Setup Section :arrow_forward:](./precourse.md) 23 | 24 | Before moving forward please ensure that you have all the accounts required. 25 | 26 | How to follow this Course 27 | ------------------------ 28 | 29 | Nothing in the course is designed as a trap. If you follow the material you should end the day with a working Minimum Viable Product website that can be deployed for the rest of the world to see! There are only two rules: 30 | 31 | - **Type every line of code yourself.** While it can seem faster to copy and paste it stops you from learning what's going on. 32 | - **You don't need to understand everything.** Understanding is vital but so is managing how much you need to know - there is only so much time in the day and we want to have a working website at the end of this particular day. It isn't possible to understand everything. 33 | 34 | What do I do if I get stuck 35 | --------------------------- 36 | 37 | One of the first problems to overcome as a developer is getting stuck. It's a tricky one because getting stuck sucks especially when you have no idea how to get unstuck. The good news is that all developers have been there so the following guidelines provide a handrail to follow throughout the day when you face a problem and can't seem to find a way out. 38 | 39 | 1. Try to work out what is actually going on. It sounds patronising but if you can describe the problem you have an idea of what's blocking you. Even if it is in vague terms if you then need to seek help you can at the very least describe the problem accurately. 40 | 2. Talk everything through with your pair partner, bounce ideas off each other. Take a quick break and then approach the problem again as though it is the first time you have encountered it. 41 | 3. Throughout the preceding steps try to gather keywords that relate to the problem like, 'Array' or 'Terminal'. 42 | 4. Isolate error keywords. If you have an error message, identify and add these keywords to your results from (3). 43 | 5. Google! Research the problem using your keywords. Also use the keywords to indentify relevant results (i.e. not just the first one). 44 | 6. Other pairs of Developers. Take your well-described, well formatted question to another developer or pair of developers; they may have encountered the same problem and know how to solve it. 45 | 7. Coach/Senior Developer. If all else fails take your question all the way to the top. Don't be disappointed though if the answer comes as more questions. 46 | 47 | :blue_book: Consider bookmarking this page for quick reference as you go through the course. 48 | 49 | Start Developing 50 | ---------------- 51 | 52 | When you're ready click the link to navigate to [the first section :arrow_forward:](./courseSections/section0.md) 53 | 54 | --------------- 55 | [:tada: Acknowledgements :tada:](./acknowledgements.md) 56 | -------------------------------------------------------------------------------- /acknowledgements.md: -------------------------------------------------------------------------------- 1 | Acknowledgements and attribution 2 | ================================ 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](./navigation.md) 5 | 6 | This course is heavily based on the [Build a Website :link:](https://github.com/makersacademy/build-a-website) project and uses a similar style of teaching to that propagated by the phenomenal [Makers Academy :link:](http://www.makersacademy.com/). If you don't know anything about Makers then do take a look it is an awesome organisation. 7 | 8 | The logo for the prototype website was made by [Freepik :link:](http://www.freepik.com) and was made available through [www.flaticon.com :link:](http://www.flaticon.com) - a great resource 9 | -------------------------------------------------------------------------------- /courseSections/section0.md: -------------------------------------------------------------------------------- 1 | Pair Programming 2 | ================ 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | Throughout this course you will be working in pairs to try and build a prototype website. Working in pairs is not just something to help us learn on this course it is also a fundamental skill used by many developers to improve their code quality, pace of learning and make a few friends along the way. 7 | 8 | ![Pair Programming](../images/pairProgramming.png) 9 | 10 | Pair programming is the process whereby two people actively collaborate on developing code. Used as part of a general teamwork approach it leads to improved code quality, team communication, knowledge share and huge learning gains. Not suprisingly, [Large scale studies of computer science students :link:](http://www.cs.pomona.edu/classes/cs121/supp/williams_prpgm.pdf) have shown greatly improved outcomes when students pair program on coding problems. 11 | 12 | How to 13 | ------ 14 | 15 | While there are many styles of pair programming we will be using a common driver :red_car: navigator :loudspeaker: style here. 16 | 17 | The key component of pair programming is regular driver/navigator switching :twisted_rightwards_arrows:. When pair programming, at any one time, one person should be the driver, i.e. the person actually typing, while the other pair should be the navigator. The navigator's role is to try and think more broadly about where the code is going; to act as a sounding board to the driver and to offer suggestions on architectural design or to be looking up documentation related to the task at hand. The navigator should avoid constantly mentioning spelling mistakes and other typos unless the driver is really stuck. 18 | 19 | It's absolutely critical that you swap driver and navigator roles frequently - probably at least once every 15 minutes. If one person carries on driving for the whole session both parties learning and code quality will be impaired. Whether you are extrovert or introvert, driver or navigator it is the responsibility of both of you to rotate roles. Don't be a keyboard hog! 20 | 21 | Pair programming can be very exhausting as it will often lead to a state of very highly focused concentration. Make sure you take occasional breaks (at least every 90 minutes), and remember that learning how to effectively pair with individuals from all backgrounds and personality types is at least as important as any individual coding skills. 22 | 23 | To prod you into good practices wherever you see a :twisted_rightwards_arrows: you should think about switching roles. 24 | 25 | General Pair Programming Do's and Don'ts 26 | -------------------------------------- 27 | 28 | **Do's:** 29 | - Before you begin, check in with each other about your energy levels, moods and working styles. 30 | - Talk 31 | - Listen 32 | - Rotate roles 33 | - Be patient 34 | - Respect each other 35 | - Take breaks 36 | - Prepare for the session 37 | - Take care of personal hygiene 38 | - Have fun 39 | 40 | **Don'ts:** 41 | - Be bossy 42 | - Be intimidated 43 | - Be quiet 44 | - Suffer in silence 45 | 46 | ------------ 47 | 48 | [:arrow_backward: Previous page](../README.md) | [Continue to the next section :arrow_forward:](./section1.md) 49 | -------------------------------------------------------------------------------- /courseSections/section1.md: -------------------------------------------------------------------------------- 1 | Development Environment 2 | ======================= 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | Developers generally work closer to the bare bones of the computer than your average user. That means lots of time in the 'command line' and not relying on 'GUI' (Graphical User Interface) tools. However, to get your computer setup for web development is a art in and of itself- especially on Windows. 7 | 8 | Fortunately, there are a number of cloud based development environments available that provide almost identical experience but with everything ready for you out of the box. For this course we will be using CodeAnywhere. 9 | 10 | Getting Started 11 | --------------- 12 | 13 | Choose who is going to be the driver and the navigator to begin with and follow the steps below on the driver's laptop. 14 | 15 | 1. [Navigate to the CodeAnywhere account you created earlier :link:](https://codeanywhere.com/editor/) - After some loading time you should see the following page: 16 | 17 | ![CodeAnywhere Init](../images/codeAnywhereInit.png) 18 | 19 | 2. We will be creating a workspace that is preconfigured to have almost everything we need to get going. With that in mind select `Container` from the menu on the left side of the connection wizard. 20 | 21 | 3. In the `Name` field enter your projects name. As we will be creating a prototype website you could perhaps go with the imaginative name: `prototypeWebsite`?! 22 | 23 | 4. Scroll through the environment options in the centre of the pane until you get to the `Ruby` options and then the `Ubuntu` environment as shown below: 24 | 25 | ![Container Setup](../images/containerSetup.png) 26 | 27 | 5. Now click `Create`! 28 | 29 | After a little bit of work, your environment should be created for you and you should arrive on a landing page with some helpful information about the container you have just created in the cloud (Don't worry too much for the moment what a container or the cloud actually are). 30 | 31 | ![CodeAnywhere landingpage](../images/codeAnywhereLandingPage.png) 32 | 33 | What you are seeing in this image is an **Integrated Development Environment (IDE)**. IDEs are highly complex applications and take a bit of getting used to. Think Microsoft Word, on steroids, exposed to radiation in a secret nuclear incident and having gained super powers...something like that. Regardless, the important thing is that CodeAnywhere gives us the four critical components of our development environment: 34 | 35 | - A **file system** to store our source files (code, images, HTML, CSS and others) 36 | - An **editor** to edit the above mentioned source files 37 | - An **operating system** to run the program described by these files 38 | - Finally, a **command line** or **terminal** to send instructions to the operating system 39 | 40 | Creating a README 41 | ----------------- 42 | 43 | It's a convention of all good projects to have a README file that explains what the project is for and provides information about how to install and run the program. Right click on the `prototypeWebsite` container icon under `Connections` in the tree view to the left of the screen. Select `Create File` and enter the name `README.md`. 44 | 45 | ![Create README](../images/createReadme.png) 46 | 47 | Once created the file should open in editing pane and also show up in the tree view to the left of the screen. The file has a `.md` extension, which means it is intended to be written in **Markdown** a popular syntax for lightly styling text files. Markdown is ubiquitous on **Github** [and here is a useful guide to it :link:](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). For now though, let's just create a basic placeholder for our information. 48 | 49 | Type the following into our newly created file (those are equal signs under the title): 50 | 51 | ``` 52 | Prototype Website 53 | ================= 54 | 55 | Built by [Your names here] 56 | ``` 57 | 58 | Introducing Ruby 59 | --------------- 60 | 61 | Ruby is a [programming language :link:](http://www.webopedia.com/TERM/P/programming_language.html). That is to say that it is a formal computer language designed to communicate instructions to a machine, particularly a computer. It is also interpreted. As an aside: languages broadly fall into two catagories: interpreted and compiled. Interpreted languages are read by a program and converted into machine code when they are run whereas compiled langagues are converted into machine code by a compiler. This produces a file that can then be run. This may sound like an exercise in semantics but the point is that different languages have different properties that make them particularly suited to certain tasks. 62 | 63 | Ruby as a language is perfect for our needs and importantly it comes pre-installed on your CodeAnywhere workspace. To test this, go to the command line and type (don't include the `$`) 64 | 65 | > The command line should be the first tab open in your editor pane. 66 | 67 | ``` 68 | $ ruby -v 69 | ``` 70 | (...then hit return to enter it) and you should see something like this: 71 | 72 | ``` 73 | ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux] 74 | ``` 75 | 76 | > We'll use the `$` sign to represent the command line prompt and to differentiate commands you should enter from the output you should see. 77 | 78 | This tells us the currently installed version of Ruby (which we requested by passing the `-v` to the `ruby` command). 79 | 80 | Updating our Ruby Version 81 | ------------------------- 82 | 83 | Before we go ahead, we need to ensure that the version of ruby we are running is updated so that some of the newer features we'll experiment with during the day will work. 84 | 85 | For this we'll use another tool that comes preinstalled with CodeAnywhere called `rvm` short for Ruby Version Manager which is just a program for controlling the version of the Ruby language that you are running. 86 | 87 | Go back to the command line and run the following commands one after another: 88 | 89 | ``` 90 | $ rvm install 2.4.2 91 | ``` 92 | 93 | This should produce an output that looks a little like this: 94 | 95 | ![rvm install](../images/rvmInstall.png) 96 | 97 | Once this has finished installing we can then tell our environment to use this installed version as follows: 98 | 99 | ``` 100 | $ rvm use --default 2.4.2 101 | ``` 102 | 103 | If you then run: 104 | 105 | ``` 106 | $ ruby -v 107 | ``` 108 | 109 | You should see that the output has changed to show that we are now using our newly installed version: 110 | 111 | ``` 112 | ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux] 113 | ``` 114 | 115 | Writing a Ruby Program 116 | ---------------------- 117 | 118 | Create a file in your workspace called `hello.rb`. By convention, Ruby files have the extension `.rb`. The benefit of this convention is that CodeAnywhere will provide Ruby **syntax highlighting** for all files with the `.rb` extension. 119 | 120 | Open the file in the editor and add the following content: 121 | 122 | ```ruby 123 | puts 'Hello Ruby' 124 | ``` 125 | 126 | See how syntax highlighting works? The IDE recognises the Ruby language and uses colours to differentiate elements of the 'grammar'. You may see different colours depending on your chosen theme. 127 | 128 | Save the file. Now go to the command line and enter the following: 129 | 130 | ``` 131 | $ ruby hello.rb 132 | ``` 133 | 134 | This tells the Ruby engine to run the code in the `hello.rb` file. You should see the following output: 135 | 136 | ``` 137 | Hello Ruby 138 | ``` 139 | 140 | You've just written a command-line program: you run it from the command line and it outputs to the command line! 141 | 142 | --------- 143 | 144 | :twisted_rightwards_arrows: At this point let's do our first switchover (staying on the same laptop) and move onto the next section. 145 | 146 | -------- 147 | [:arrow_backward: Previous section](./section0.md) | [Continue to the next section :arrow_forward:](./section2.md) 148 | 149 | -------------------------------------------------------------------------------- /courseSections/section10.md: -------------------------------------------------------------------------------- 1 | Adding Your Own Style 2 | ====================== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | Previously we added some content using the Bootstrap framework and some of you were hopefully wondering what was being provided behind the scenes and how our website was already looking a little...styled? To put everything into perspective: so far we've written a little Ruby (telling our computer what to do and what to check for), a little HTML (decribing the structure of the content we want for our page) and now we come to CSS. 7 | 8 | CSS (more formally Cascading Style Sheets) is the technology we use to define the *layout* and *design* of the HTML *structure* we have already written. Without CSS our webpages would just be a load of left-justified, black-text-on-white-background monstrosities. 9 | 10 | Bootstrap will take us a long way, particularly when it comes to our page layout and scaling across different devices, but it still leaves a little to be desired in the looks department. So let's get under the hood and add our own styling to take our site to the next level. 11 | 12 | Making our homepage pretty 13 | -------------------------- 14 | 15 | Following a quick show-and-tell with our product owner they remarked that while they were impressed with your rapid prototyping ability they thought that the page looked a little bland. Thankfully they had just a the thing: a handy colour palette for us to brighten up the site and a user story to describe the work to be completed. 16 | 17 | ``` 18 | As a prototypical business owner 19 | I want my site to be decked out in prototypical colours 20 | So that my eyes are soothed every time I open my web-browser 21 | ``` 22 | 23 | ![Prototype colour palette](../images/colourPalette.png) 24 | 25 | Inline styling 26 | -------------- 27 | 28 | Before we get down into the weeds we'll start with some of the basics. 29 | 30 | To style our page we can add some CSS directly to our `index.erb` file by adding the `style` attribute to the HTML tag that you want to apply it to. 31 | 32 | So for example, try the following in `index.erb` 33 | 34 | ```html 35 | 36 | ... 37 | 38 | ``` 39 | 40 | How red does your page look now?! 41 | 42 | The CSS we just added tells the browser to render the body of our page - i.e everything that's visible on the screen - with the specified background colour. Once upon a time, all CSS was added directly inline with the HTML like this. However, as with our ruby code this is going to be difficult to read and maintain. We want to put all of our styles in a separate file (or files) and keep our code DRY. As an aside the DRY principle (Don't repeat yourself) is key to being a developer. Essentially Duplication is waste and is likely to lead to code and processes that are harder to understand and much more error prone. Duplication of logic (which we are dealing with here) should be eliminated by abstraction while duplication of processes should be eliminated by automation (Hopefully this chimes with a few of the ideas we talked about with testing). 43 | 44 | > Have a think about the many tasks that you do repetitively day in day out - could any of these be automated? If so how? If you can answer those questions maybe there's a startup in the making! 45 | 46 | If you would like to know more about DRY and other key principles that guide software development then have a read of this article on the aptly named [Giant Robots Smashing into Other Giant Robots Blog :link:](https://robots.thoughtbot.com/back-to-basics-solid). 47 | 48 | Creating our own CSS 49 | -------------------- 50 | 51 | Remove the inline style that we added in the last step so that you are left with ` ... `. Now create a `public` folder in your CodeAnywhere workspace and then add a `css` folder inside `public`. Finally create a file called `application.css` inside the `css` folder. At the end your file tree should look a little like this: 52 | 53 | ![file tree](../images/fileTree.png) 54 | 55 | Let's firstly normalise the background colour to be in line with the colour palette we've been given. Add the following: 56 | 57 | ```css 58 | body { 59 | background-color: #FAF9F9; 60 | } 61 | ``` 62 | 63 | You can interpret this CSS code as being the following instruction to the browser: *render* any `` *element* on the page using the background colour with the Hex value `#FAF9F9`. In the case of `body` there should only ever be one on the page. But if you were refering to paragraph elements: `

` there could be many spread across the page. 64 | 65 | Refresh your preview. Did it work (admittedly comparing two shades of white can be hard)? Did you expect it to work? It doesn't matter whether you were right or wrong - what matters is how you use that outcome to progress. Take a few moments to consider the changes we just made and how they might have affected the outcome. 66 | 67 | The answer is that the browser doesn't know anything about `public/css/application.css`. Why would it? It's our responsiblity to tell the browser about this external stylesheet. Fortuantely, that's another fundamental part of the way the web works. In fact you've already done it once before! 68 | 69 | In the same way we had to tell our html in `index.erb` to use the bootstrap CSS framework we now need to tell it to also pull in our newly created `application.css`. 70 | 71 | Update your `...` section to include the following: 72 | 73 | ```html 74 | 75 | ``` 76 | 77 | Notice how our `href` is in this case pointing to our local file rather than a remote url and that we don't need to add the `public`. Make sure your `index.erb` file is saved and then switch over to your blank `application.css`. 78 | 79 | Now refresh your browser. The background should be *Snow* coloured. 80 | 81 | That's probably not the most exciting change you've ever seen (if you can even see the change) so let's start fleshing things out with a bit of styling to our `jumbotron` element. Add the following to `application.css`. 82 | 83 | ```css 84 | .jumbotron { 85 | margin-top: 5em; 86 | background-color: #FAF9F9; 87 | border: solid 2px #BEE3BD; 88 | color: #555B6E; 89 | } 90 | ``` 91 | 92 | > Why do you think we've described the jumbotron using `.jumbotron` in our css file? If you're struggling then maybe [this will help :link:](https://www.w3schools.com/cssref/sel_class.asp). 93 | 94 | Now if you refresh your browser you should see a nicely outlined jumbotron more centrally positioned on our homepage with text in *Black Coral*. Exciting stuff!!! 95 | 96 | Task 5 97 | ------ 98 | 99 | :twisted_rightwards_arrows: 100 | 101 | - [ ] Our work on the current user story is not complete. Our navbar is still looking distinctly "off brand". Style the navbar to bring it inline with the rest of our site and the colour palette. Feel free to go rogue and change the colors and values we've used in our CSS so far. The goal is consitency, but do add a bit of your own flare if you'd like. 102 | 103 | - [ ] *Bonus Task* - Add a custom font and update the `application.css` to style our `

` element to use it. [Google fonts is a great source :link:](https://fonts.google.com/) 104 | 105 | -------------- 106 | 107 | [:arrow_backward: Return to previous section](../courseSections/section9.md) | [Continue to the Answers :arrow_forward:](../tasks/task5.md) 108 | -------------------------------------------------------------------------------- /courseSections/section11.md: -------------------------------------------------------------------------------- 1 | Making Things Happen With JavaScript 2 | ==================================== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | While our website is now an explosion of colour there's nothing dynamic about it. We're going to change that now using JavaScript. JavaScript is not just another programming language. Unlike Ruby which runs on the server JavaScript *runs in the browser*. that might not mean much right now, but it's a game changer! It means that we can load code into our pages from various sources - not just our own server - and have it run independently on the client's machine. 7 | 8 | If you think that sounds potentially dangerous, you are right. A large number of Internet security vulnerabilites involve JavaScript. However, without JavaScript, the web would be a much duller place. 9 | 10 | As with our Ruby and CSS code we'll be using a framework to help us along the way. In this instance the popular [JQuery :link:](https://jquery.com/) Library. 11 | 12 | As with our other frameworks we need to tell our application to load JQuery so that it's ready for our use. 13 | 14 | Add the following line just before your closing `` element in your `index.erb`. 15 | 16 | ```html 17 | 18 | ``` 19 | 20 | Loading JQuery into the page won't by itself do anything. For that we need to write our own Javascript to interact with it and the page. Let's begin by creating a folder `public/javascript` and within that create a file called `app.js`. 21 | 22 | Once complete you should be left with the following file structure: 23 | 24 | ![Final file tree](../images/finalTree.png) 25 | 26 | Now as with our JQuery library we need to add our `app.js` to the page with the following line again just before your closing `` element. 27 | 28 | ```html 29 | 30 | ``` 31 | 32 | Fantastic and it's just in time because it looks like our client has come back with some further requirements. 33 | 34 | Adding Functionality to our page 35 | -------------------------------- 36 | 37 | Having seen the initial site the client has been highly impressed and wants to engage us to extend it further: adding navigation tabs and additional content described in the following user stories: 38 | 39 | ``` 40 | As a prototypical user 41 | I want to see plans for a top secret prototype 42 | So that I can prototype it 43 | ``` 44 | 45 | ``` 46 | As a prototypical user 47 | I want to be able to navigate to different pages using tabs in the navigation bar 48 | So that I may better consume information on prototypes 49 | ``` 50 | 51 | ``` 52 | As a prototypical user 53 | I only want to see the content relevant to the tab that I have selected 54 | So that my mind is not overwhelmed with vast quantities of knowledge 55 | ``` 56 | 57 | Handily the client has also provided us with a wireframe for our new content. 58 | 59 | ![Image WireFrame](../images/imageWireframe.png) 60 | 61 | 62 | Creating the content 63 | -------------------- 64 | 65 | This breaks down our work nicely. However as you may have realised before we can start using javascript to control our view of the page there is some content that we need to deliver. 66 | 67 | By now the HTML we need to add should be pretty familiar. For the first user story add the following within the `
...
` below the `
71 |

Our Top Secret Prototype

72 | 73 |
74 | ``` 75 | 76 | And add the following within the `
...
` after the `

...

` element: 77 | 78 | ```html 79 | 85 | ``` 86 | 87 | Now with all of that content added if you refresh the page you should see a very cluttered website that looks a little like the following: 88 | 89 | ![Cluttered homepage](../images/clutteredHomepage.png) 90 | 91 | Now we can bring it all togather using a little CSS and Javascript. First we need to define a small piece of CSS that can be used to hide our elements. Add the following to your `application.css`. 92 | 93 | ```css 94 | .hidden { 95 | display: none; 96 | } 97 | ``` 98 | 99 | If you save the CSS file and reload the page you should now see that our homepage looks much like before. However, we currently have no way of making the hidden content show itself. Time to get the Javascript written. 100 | 101 | Showing and Hiding 102 | ------------------ 103 | 104 | When trying to work out how to write our code it is often good to first try and ignore the code completely and find a way to articulate each step the you want the program to take. 105 | 106 | This is such a good technique that it even has a name: [Rubber Duck Debugging :link:](https://rubberduckdebugging.com/). 107 | 108 | So let's try it out here. What are the steps that we need to go through to get to a working solution. 109 | 110 | 1. When we click on the *Prototypes* tab we want it to become active. 111 | 2. When we click on the *Prototypes* tab we want to see the *prototypes* section content. 112 | 3. When we click on the *Prototypes* tab we want the *About* tab to lose its active status. 113 | 4. When we click on the *Prototypes* tab we want the *about* section to be hidden. 114 | 115 | Brilliant now that we have our sequence of events to code let's write that out in Javascript. In your `app.js` add the following: 116 | 117 | ```javascript 118 | /* global $ */ 119 | 120 | $(document).ready(function(){ 121 | 122 | $('#prototype').click(function(event){ 123 | event.preventDefault(); 124 | $('#prototype').addClass('active'); 125 | $('.prototype').removeClass('hidden'); 126 | $('#about').removeClass('active'); 127 | $('.about').addClass('hidden'); 128 | }); 129 | 130 | }); 131 | ``` 132 | 133 | Save the file, reload the page and try to click the prototypes tab. Does it work? 134 | 135 | Now try clicking on the About tab to go back...not so good. We need to add another method to go back to our first tab. Luckily it should just be a reverse of what we've already written. Add this function below the first inside the `$(document).ready(function(){...});` 136 | 137 | ```javascript 138 | $('#about').click(function(event){ 139 | event.preventDefault(); 140 | $('#about').addClass('active'); 141 | $('.about').removeClass('hidden'); 142 | $('#prototype').removeClass('active'); 143 | $('.prototype').addClass('hidden'); 144 | }); 145 | ``` 146 | 147 | Now if you save and reload your page you should be easily able to flick back and forth between the two tabs. Very nifty! 148 | 149 | Task 6 150 | ------ 151 | 152 | Our client has a further requirement for us: 153 | 154 | ``` 155 | As a prototypical user 156 | I would like to be able to contact the owners of a prototypical site 157 | In order to ask them questions about their prototypes 158 | ``` 159 | 160 | And accompanying wireframe. 161 | 162 | ![Contact WireFrame](../images/contactWireframe.png) 163 | 164 | - [ ] Create the new contact details tab and add another javascript method that toggles whether it is shown. 165 | - [ ] Update the existing methods so that when you click on each tab only its content is shown. 166 | 167 | ------------- 168 | 169 | [:arrow_backward: Return to previous section](./section10.md) | [Continue to the answers :arrow_forward:](../tasks/task6.md) 170 | -------------------------------------------------------------------------------- /courseSections/section12.md: -------------------------------------------------------------------------------- 1 | Refactoring 2 | =========== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | Looking at our implementation of the show-hide logic for moving between tabs there is clearly a large amount of duplicated code. But why is this a bad thing? I mean we've tested that it works and we've fulfilled our requirements, surely that should be good enough? Not quite: think about the next time our client asks us to add a tab. It's just a little bit more work that the last time we did it. Now think what would happen if our website had 30 or 40 pages each with their own tab views that now need to be updated. This solution is clumsy and doesn't lend itself to extension. 7 | 8 | So what should we do? 9 | 10 | The simple answer is look for a better solution. A key skill to gain is the ability to spot repetition in code. Repetition is almost always a sign that your current implementation has reached its limits and now you need to abstract the common logic. Holding this common logic in one place then provides you with a better, optimised solution to the problem. 11 | 12 | > Take a moment now to look at the code we've written. Grab a piece of paper and try to describe in English how you might **refactor** this problem to remove the repetition. 13 | 14 | Abstracting repetition 15 | ---------------------- 16 | 17 | When thinking about the above problem we can see that in our code the only thing that really changes in each of our show/hide methods is the name of the element that we are operating. Ideally we would like some way of creating a default piece of logic that can be passed around that either shows or hides a tab depending on which one has been clicked. 18 | 19 | While there are multiple ways that this could be achieved here is one implemenation. If you want to use it then it should completely replace everything that is in `app.js`. 20 | 21 | ```javascript 22 | /*global $ */ 23 | $(document).ready(function(){ 24 | 25 | var tabs = ['contact', 'about', 'prototype']; 26 | 27 | function eventHandler(event){ 28 | event.preventDefault(); 29 | tabs.forEach(function(item){ 30 | if(event.currentTarget.id === item){ 31 | $('#' + item).addClass('active'); 32 | $('.'+item).removeClass('hidden'); 33 | } else { 34 | $('#' + item).removeClass('active'); 35 | $('.' + item).addClass('hidden'); 36 | } 37 | }); 38 | } 39 | 40 | $('#prototype').click(eventHandler); 41 | $('#about').click(eventHandler); 42 | $('#contact').click(eventHandler); 43 | 44 | }); 45 | ``` 46 | 47 | There are still ways that this code can be improved but for now this should do. Now all we have to do if we're asked to add a new tab is add it to the tabs *array* and then add a call to our `eventHandler` function when it's clicked. Much simpler! Hopefully, this also illustrates how less code can actually do more for you. 48 | 49 | Moving on 50 | --------- 51 | 52 | You'll be glad to hear that our client has decided that the website is ready to be released to the wider world! You've done a great job now all we need to do is find some way of getting this out onto the web permanently. 53 | 54 | :twisted_rightwards_arrows: commit and push your code, switch over your driver and navigator and we'll move onto looking at deployment. 55 | 56 | -------- 57 | 58 | [:arrow_backward: Return to previous section](../tasks/task6.md) | [Continue to next section :arrow_forward:](../courseSections/section13.md) 59 | -------------------------------------------------------------------------------- /courseSections/section13.md: -------------------------------------------------------------------------------- 1 | Deployment 2 | ========== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | One of the great benefits that we've already seen with CodeAnywhere is that the website we've created is already online. The URL we visit is available to the whole world and anyone can visit our great prototype site. However, this is really only intended for development and testing. If you don't interact with your workspace in CodeAnywhere for 2 days it will be shut down along with any running processes (i.e. your server). Your won't lose any work - you just won't be able to access the application from outside of CodeAnywhere until you log in and restart your server. Anyone trying to access your application will see something like this: 7 | 8 | ![CodeAnywhere non running](../images/nonRunning.png) 9 | 10 | As you can imagine any client would be understandably a little annoyed if their brand new website ceased to work after only two days. What we need to do now is **deploy** the application to a **production environment**. Once upon a time that was no trivial matter. It might have required server teams, network teams, thousands of poundsworth of hardware and required weeks of planning. However, with the advent of cloud computing and Platform as a Service (PaaS), you can now set up a production environment in about 5 minutes and deploy to it in about 30 seconds. 11 | 12 | Deploying to Heroku 13 | ------------------- 14 | 15 | We're going to deploy our application the [Heroku :link:](https://www.heroku.com/). Heroku is a massive PaaS provider that offers free hosting for small projects. You should already have an account setup as part of the pre-course but if not head [there now :link:](https://www.heroku.com/) and set one up. Make sure to note the email and password you used, you'll need them in a second. 16 | 17 | Heroku provides a suite of tools for interacting with it from the command line, called the [Heroku Toolbelt :link:](https://devcenter.heroku.com/articles/heroku-cli). The first thing we need to do is to install this onto our workspace. Run the following command: 18 | 19 | ``` 20 | $ wget -qO- https://cli-assets.heroku.com/install-ubuntu.sh | sh 21 | ``` 22 | 23 | Now we can check that the tools are installed and in particular which version we have by running: 24 | 25 | ``` 26 | $ heroku --version 27 | ``` 28 | 29 | You should see something like: 30 | 31 | ``` 32 | heroku-cli/6.14.39-addc925 (linux-x64) node-v9.2.0 33 | ``` 34 | 35 | You can interact pretty easily with Heroku from their website but it's more fun to do it from the command line. First things first we need to hook up to our account: 36 | 37 | ``` 38 | $ heroku login 39 | ``` 40 | 41 | This will prompt you for the email and password you used to create your Heroku account. Once you are logged in you can create a new application: 42 | 43 | ``` 44 | $ heroku create 45 | ``` 46 | 47 | If you check back on the Heroku website you should see that your application has been created. 48 | 49 | ![Heroku created](../images/herokuCreated.png) 50 | 51 | You can even visit your new application in a browser by following its unique url: 52 | 53 | ![blank Heroku app](../images/blankHerokuApp.png) 54 | 55 | Before we push our application to Heroku we need to tell Heroku how to run our application: 56 | 57 | Create a file in the top level of your workspace called `config.ru` with the following content: 58 | 59 | ```ruby 60 | require './server' 61 | 62 | run Sinatra::Application 63 | ``` 64 | 65 | If you've been adding, committing and pushing throughout the course today your application should be ready to go after the `config.ru` is added to git. All you need to do to get your application to the cloud is run the following: 66 | 67 | ``` 68 | $ git push heroku master 69 | ``` 70 | 71 | When the task finishes go back and visit the application url. What do you see? 72 | 73 | :twisted_rightwards_arrows: 74 | 75 | --------- 76 | 77 | [:arrow_backward: Return to previous section](../courseSections/section12.md) | [Continue to the next section :arrow_forward:](../courseSections/section14.md) 78 | 79 | -------------------------------------------------------------------------------- /courseSections/section14.md: -------------------------------------------------------------------------------- 1 | Continuous Integration and Continuous Delivery 2 | ============================================== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | The two phrases above, often shortened to CI and CD are currently big buzzwords that are often thrown around but rarely understood or used correctly. Throw in other things, such as, build pipelines, Integration Acceptance and Feature tests and things can start to get a bit bewildering but at their heart both are simply good Agile practices that help us to deliver quality features directly to the end-user as fast as possible. So let's try and demystify all of this by creating our own Continuous Delivery pipeline for our Prototype website. 7 | 8 | Before we go ahead implementing this let's talk first about Continuous Integration. The good news is that you've been practicing most of the key ideas already. Simply put, it is the practice of *integrating* your code into a shared repository as often as practicable. 9 | 10 | Each check in to this repository is then verified automatically by an automated build. there are a whole load of benefits to working in this manner but as a developer the key positives are that each check in is small, quick and easy: if anything does break it is easy to catch and fix which ultimately means less time fixing bugs and more time adding features. Speaking of which our fantastic Business Analyst has already put together a user story in conjunction with our client. 11 | 12 | ``` 13 | As a prototypical business owner 14 | I want an automated build pipeline 15 | So that I detect integration issues as early as possible 16 | ``` 17 | 18 | Setting up an automated build pipeline 19 | ------------------------------------- 20 | 21 | In the precourse we setup access to a service called [Travis CI :link:](https://travis-ci.org/) which we'll use to automate our CI pipeline. 22 | 23 | But first, what is Travis and what exactly will it do for us? 24 | 25 | Simply put, Travis is just another computer somewhere out on the internet that we can interact with in a particular way. When setup correctly it will attempt to take our code from github, follow the instructions we've specified to install all the related programs that we need for our prototype to work (all of our gems for example), and then run the tests we've written to check that our application is in a good state to run and deploy anywhere. The output of this process is what is commonly known as a **build**. 26 | 27 | With a good set of tests, we can have multiple developers, potentially all over the globe all adding code to the same project, safe in the knowledge that if an individual's changes break something then it will be caught before that broken feature can be seen by the end user. 28 | 29 | So without further ado let's setup travis to run our tests every time we push some new code: 30 | 31 | Use the following link to navigate to the [Travis homepage :link:](https://travis-ci.org) and login using your github account. 32 | 33 | > Note - this should be the Travis account of the person who has the `prototype-website` repository. 34 | 35 | Now click on your github account portrait in the top right hand corner of the page: 36 | 37 | ![Travis Profile](../images/travisProfile.png) 38 | 39 | You should now see a page that lists all the repositories held under your Github account. 40 | 41 | Find your prototype website repository and check the switch to confirm that you want it to integrate with Travis. 42 | 43 | ![Integrate with Travis](../images/travisIntegrate.png) 44 | 45 | Telling travis what to do 46 | ------------------------- 47 | 48 | So far we've told Travis that we want it to integrate with our project but for this to be useful we actually need to find some way of telling it what we actually want it to do. 49 | 50 | Thankfully Travis has a handy way of letting us do this. Create a new file called `.travis.yml` in the `prototype-website` directory and then add the following to it. 51 | 52 | ```yml 53 | script: bundle exec rspec 54 | ``` 55 | 56 | It's as simple as that. 57 | 58 | :twisted_rightwards_arrows: This time ensure that when you commit and push, you have a browser window open on your Travis home-page. What do you see? 59 | 60 | Hopefully, if everything was connected correctly you ended up with an output that looked similar to the following: 61 | 62 | ![travis output](../images/travisOutput.png) 63 | 64 | Here you can see that after starting up, Travis clones your code, checks the version status of a number of different pieces of software such as the ruby language, runs `bundle install` to pull in all our dependencies and then runs the commands that we specified in our `.travis.yml` i.e. running all our tests. If all of that runs and passes then we have a successful build! 65 | 66 | ------------ 67 | 68 | [:arrow_backward: Return to previous section](../courseSections/section13.md) | [Continue to the next section :arrow_forward:](../courseSections/section15.md) 69 | -------------------------------------------------------------------------------- /courseSections/section15.md: -------------------------------------------------------------------------------- 1 | Continuous Deployment 2 | ===================== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | So we've setup a Continuous Integration pipeline but how does that help us with the idea of Continuous Delivery and why are we now talking about Continuous Deployment? 7 | 8 | In short, Continuous Integration is a way for us to produce artifacts that we are confident can be put in front of a user. 9 | 10 | Think of the life-cycle of a feature. We gather some requirements, build a feature against them and then make what we've built available to the user. Real feedback on this feature will only come at the point that a user is actually interacting with it. If we want to improve our products and features we want to do everything we can to reduce this feedback loop. 11 | 12 | Following this line of thinking: if we are continuously integrating our code and are happy that it can be used, can we find a way that will enable us to get it to the end user as quickly as possible? The answer is yes: Continuous Delivery, which is the delivery of features to the user as soon as they are ready. Continuous Deployment is, from a technical perspective, *how* we can achieve this. 13 | 14 | Using Travis to Continuously Deploy 15 | ----------------------------------- 16 | 17 | We have integrated Travis into our project to build our code and run our tests. Seperately we also have a deployed application setup on Heroku. Wouldn't it be great if every time we pushed our code to Github Travis ran all our tests, then if they passed that code was automatically pushed to Heroku and then deployed for all the world to see? 18 | 19 | The first thing we need to be able to do is interact with Travis using the command line. Luckily for us the helpful folks at Travis have created a gem for this exact purpose. Let's add the following into our `Gemfile`: 20 | 21 | ```ruby 22 | gem "travis" 23 | ``` 24 | 25 | and follow that up with a quick: 26 | 27 | ``` 28 | $ bundle install 29 | ``` 30 | 31 | Now that we have the Travis CLI (Command line interface) installed we can log into Travis. Run the following: 32 | 33 | ``` 34 | $ travis login 35 | ``` 36 | 37 | Follow the prompts and enter your credentials to associate Travis with your Github repository. 38 | 39 | At this point we are ready to tell Travis to *Continuously Deploy* our application. Update your `.travis.yml` file to the following: 40 | 41 | ```yml 42 | script: bundle exec rspec 43 | deploy: 44 | provider: heroku 45 | api_key: 46 | secure: 47 | app: 48 | ``` 49 | 50 | Here we are telling Travis to deploy our code to our *provider* Heroku. You will also have noticed that we appear to have a few blank fields defined with no data associated with them. 51 | 52 | The `api_key` is where we will define credentials that will allow Travis to identify itself to Heroku as being authorised by us. However, there is a catch: remember that we are pushing our code to Github and that our code, being open-source, is therefore visible to anyone with an internet connection. We therefore need to add an encrypted key that can be passed around and decrypted where needed. To do this automagically, run the following command: 53 | 54 | ``` 55 | $ travis encrypt $(heroku auth:token) -r [Your github repo name here: e.g. ALRW/prototype-website] --add deploy.api_key 56 | ``` 57 | 58 | If you now open your `.travis.yml` it should look a little like the following: 59 | 60 | ```yml 61 | script: bundle exec rspec 62 | deploy: 63 | provider: heroku 64 | api_key: 65 | secure: WTD1P6b4f9mxV07XO9hiwCPRsE/a8fzBTL1xZjCM3d+xhQBk5r8G2pDO4zShrfZ7V5Ym2b+VA4TIbRienumGaqMcZqlvbxlYy7NU8W0VPGAUV05Y/vxH5Zi1/XEraNiLso1H4uSPsUfRgtG4/hgyQlASmHI4A6oCoOqFbyHDY4uPTigCbURE3xG95K6o0Xuwbikr+ibpnSkXcbLXJrOQF3GUuXv4OCfauRhsvEiDbnjfBgQB/iE9PG7wbKL9mXja+OsMWLfPu/sZHohl9JF2sG8hAve2HeAn8A5KK6YklQMkACvtJOz1l8yJ6waBRubQwTEuRfNUc2YJXoNvU7xtGsu9orO7QgEoc1Ps3K+zNHIMOuFJEbIKcy7+8jD/LQxyXtWUvl54+A5nJpR/jiiCPQvXXJf9QStRg516UzAj0JP9zBmxTuPBn/ghaORQqnZa6pctbcg96ri/0iuO9jqj1O6Tj6KeuVpg/YBF+m/Cjimt5Ussv6+e4MLqKBpHrK76v4UcJe3bArWu2AItQpVd1XD3AXjuZ2kotlOi7FhAmovAW/2LrmlpYYVPP+YPLbSbRtxBfIupxHe4pO3tMOYFmT/NOy2/79pXXz+0YkDLd8ELL9NRM92WkU93DIe3SgMB5rjebfTYxqZP23YcKNFJUyduV5Q+dIgmsG2XNSGvnqI= 66 | app: 67 | ``` 68 | 69 | Now that we can easily authenticate with Heroku from Travis we only need to tell travis the name of our app on Heroku. Update the final line of the `.travis.yml` with the name of your application (note yours will be different): 70 | 71 | > If you're wondering how to find the name, it can be found [here :link:](https://dashboard.heroku.com/apps). 72 | 73 | ```yml 74 | app: delicious-pie-39548 75 | ``` 76 | 77 | ---------------------------------- 78 | 79 | :twisted_rightwards_arrows: - When you commit and push your code this time watch the progress of the build on Travis. If everything is setup correctly you should see that the build succeeds and your code is pushed and deployed to Heroku. However, when you open up your website it looks exactly the same...We haven't made any noticeable changes. Wouldn't it be nice to implment a final feature using everything that we know? Great idea! 80 | 81 | ---------------------------------- 82 | [:arrow_backward: Return to previous section](../courseSections/section14.md) | [Continue to the next section :arrow_forward:](../courseSections/section16.md) 83 | -------------------------------------------------------------------------------- /courseSections/section16.md: -------------------------------------------------------------------------------- 1 | Changing Requirements, Rotting Code and Test Driven Development! 2 | ================================================================== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | For this final section we're going air a few aspects of developer dirty laundry and look at how we can possibly try and mitigate them. 7 | 8 | As if by magic our client has also just come to us with some requirements that nicely illustrate these points. Their UX (User Experience) team have been doing some research with the public on our live prototype website and have come up with some interesting findings. 9 | 10 | As the following highly technical graph shows it seems that there is some variation in the way that people contact Prototype Inc. 11 | 12 | ![graph](../images/graph.png) 13 | 14 | Our mysterious client would like to optimise their contact pathway reducing the number of forms of communication and also making it easier for the user to make contact. All of which is encapsulated in the following user story. 15 | 16 | ``` 17 | As a prototype obsessed user 18 | I want a navber link to contact Prototype Inc by email 19 | So that I can contact my favourite prototype team in the most efficient manner 20 | ``` 21 | 22 | As the wireframe below shows, they would like us to remove the contact tab and add in a `mailto` link wrapped up as an image to the navbar. 23 | 24 | ![final wireframe](../images/finalWireframe.png) 25 | 26 | Why am I deleting everything? 27 | ----------------------------- 28 | 29 | This is a great example of a common occurance during any development project. Requirements that effect, modify or straight up remove a previous feature. This process multiplied many times leads to what is sometimes known as **[code rot](http://www.agile-process.org/change.html)**. Essentially each new change may lead to new subtle bugs that take time to fix and can themselves lead to even more subtle bugs. Eventually, in a worst case scenario, the cost of maintaining the code-base exceeds the resources available and it is actually more efficient to start from scratch. 30 | 31 | This also leads us onto the topic of **[technical debt](https://martinfowler.com/bliki/TechnicalDebt.html)**. In our case, for this new requirement we could just delete the `Contact` tab from our navbar. This would nuke that feature in the fastest time possible allowing us to get on with adding in the new `mailto` icon. However, we would be left with a whole load of redundant code that could potentially cause bugs in the future. If we needed to get this new feature out to our customers ASAP this might be acceptable but over time constantly incurring similar debts would keep on reducing our speed of delivery to the point were we are adding very little value for our effort. Keeping technical debt under control is crucial in the long run. 32 | 33 | As a rule, taking on technical debt should be a conscious choice as well as being the exception rather than the norm. One way to help ensure this is a robust set of tests with code that is written to be easily testable. This leads us nicely to another Agile development practice. 34 | 35 | Test Driven Development 36 | ---------------------- 37 | 38 | Earlier in this course we delved into testing. However, the tests we wrote were authored after the fact. On a site as small as this that is a forgivable sin but think about the *coverage* of the tests we do have, do you have confidence that we could run our tests and know that everything we had previously implemented was working as required? 39 | 40 | [Test Driven Development :link:](http://www.extremeprogramming.org/rules/testfirst.html) (TDD) is a methodology for forceing ourselves to write well tested and easily testable code. At a high level it follows the iterative process shown below often shortened to the phrase: *red, green, refactor*. 41 | 42 | ![TDD](../images/tdd.png) 43 | 44 | This creates a nice rhythm: you write a failing test to define an aspect of your problem (this should be small and well defined); you then write the **simplest** code that will make this test pass (go green); at this point, you can look to see if this code can be refactored or optimised in anyway; now you can start the process all over again by writing your next failing test. 45 | 46 | This has all the benefits of testing that we have talked about previously with a couple of further added benefits. Firstly, as a process it forces you to think through the problem you are trying to solve rather than just jumping in head first. Essentially, you have to document in code (your tests) exactly what problem you are trying to solve. As a nice byproduct, anyone else working with your code can use your tests to understand exactly what you are doing. Secondly, the code you create should be short and simple: it will implement only the features you wanted and through your tests these will also be future proofed, reducing the potential for future bugs. 47 | 48 | Final task 49 | ---------- 50 | 51 | Now that we have covered all of the above it just remains for you to try and implement this new requirement using a TDD approach. Remember to make sure you clean up anything that could be regarded as technical debt. 52 | 53 | If you want to go all out on the tests consider looking at the [rspec documentation :link:](http://rspec.info/documentation/3.6/rspec-core/) although you should already have covered everything needed to test this feature. 54 | 55 | If you go down the route of testing what HTML you are returning on the page then you may want to search [Stack Overflow :link:](https://stackoverflow.com) for how to escape quotes in ruby. 56 | 57 | For the image `mailto` link feel free to use anything you want but as a simple starting point consider looking at the [Bootstrap glyphicons :link:](https://getbootstrap.com/docs/3.3/components/). 58 | 59 | Good luck! 60 | 61 | ---------------------------------- 62 | 63 | [:arrow_backward: Return to previous section](../courseSections/section14.md) | [Continue to the answers :arrow_forward:](../tasks/task7.md) 64 | -------------------------------------------------------------------------------- /courseSections/section17.md: -------------------------------------------------------------------------------- 1 | Course Finale! 2 | ========================== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | That's it for the day, congratulations. Have a think about what you've accomplished. In the course of a day you've built an application's backend in **Ruby**; created content in **HTML**; styled that content using **CSS**; added a dynamic frontend using **JavaScript** and deployed the resulting prototype to a production environment that can be accessed by anyone anywhere in the world. Not bad for a day's work. 7 | 8 | More importantly, throughout this journey you've also touched almost every aspect of web-development from Git and version control systems to interpreted and compiled languages. Hopefully you now feel in a position to understand any discombobulated phrase that a developer throws your way. 9 | 10 | As with every piece of learning and development things shouldn't stop at the end of the course. This is a starting point not the finish line. So to help you on your way the following are a few 100% free resources that can help you build upon everything you've picked up here today. 11 | 12 | Further learning and development 13 | ------------------------------- 14 | 15 | While there are numerous articles, blogs, books, courses and other resources out there today many are of questionable quality or are prohibitively costly. The following resources are in contrast, high quality and more importantly all offer free material (some charge for additional content). 16 | 17 | ------------------------------- 18 | 19 | [Learn to Program - PDF :link:](https://pine.fm/LearnToProgram/) 20 | 21 | A great book to cover the basics of programming by Chris Pine. Focuses on the Ruby language but everything covered is highly applicable across all programming languages. 22 | 23 | [Codecademy :link:](http://www.codecademy.com/) 24 | 25 | A platform for learning to code with numerous short courses for various languages and web technologies. It is a great place to start your learning about a particular language. 26 | 27 | [Khan Academy :link:](https://www.khanacademy.org/) 28 | 29 | Some good basic and intermediate courses on web development that focus primarily on HTML, CSS and JavaScript. 30 | 31 | [Udemy :link:](https://www.udemy.com/) 32 | 33 | Although it has a freemium model and some low quality content there is a wealth of fantastic resources that can be accessed here. 34 | 35 | [Udacity :link:](https://www.udacity.com/) 36 | 37 | A platform for computer science, web developement and machine learning/AI courses. Offers more in depth nano-degrees although after a free trial these can become expensive. 38 | 39 | [Free Code Camp :link:](http://www.freecodecamp.com/) 40 | 41 | A fantastic and completely free programming resource based on a HTML CSS and JavaScript stack. Great if you want to dive in, go all the way and not pay a penny. 42 | 43 | [Exercism :link:](http://exercism.io/) 44 | 45 | Code kata are a proven way of improving your ability to program by facing short interesting problems. It's also a nice way to experiment with a new language. Exercism is probably the best platform to do this through and the feedback and iterative approach it provides is second to none. 46 | 47 | [CodeWars :link:](http://www.codewars.com/) 48 | 49 | Another good code-kata website that has a massive number of challenges. 50 | 51 | ------------------------------ 52 | 53 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](./navigation.md) 54 | 55 | -------------------------------------------------------------------------------- /courseSections/section2.md: -------------------------------------------------------------------------------- 1 | Welcome to the World Wide Web 2 | ============================= 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | A website is a program that receives requests and sends responses over the Internet. But that's a lot easier said than done. Fortunately, it's also so utterly fundamental that the heavy lifting is already done for us by something else; something we call a **web framework**. Most programming languages have a number of web frameworks to choose from and Ruby is no exception. Today we are going to use a framework called [Sinatra :link:](http://www.sinatrarb.com/). 7 | 8 | Creating the server 9 | ------------------ 10 | Create a file in your workspace called `server.rb` 11 | 12 | Open the file in the editor and add the following content: 13 | 14 | ```ruby 15 | require 'sinatra' 16 | set :bind, '0.0.0.0' 17 | set :port, 3000 18 | 19 | get '/' do 20 | 'Hello World!' 21 | end 22 | ``` 23 | 24 | Make sure you save the file. Now try running it from the command line: 25 | 26 | ``` 27 | $ ruby server.rb 28 | ``` 29 | 30 | Your should get an error: 31 | 32 | ``` 33 | /usr/local/rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- sinatra (LoadError) 34 | from /usr/local/rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require' 35 | from server.rb:1:in `
' 36 | ``` 37 | 38 | That was just to get you warmed up! Error messages often look unfriendly, but they're really rather useful when you get to know them. What does this one mean? 39 | 40 | If you throw your hands up in the air and exclaim 'How the devil should I know?', then don't worry. That's how we all feel sometimes. One of the skills of a good developer is to make and test small hypotheses about the cause of an error message, then iterate over the process until the solution is found. Oh, and Google it. You can always just Google it. 41 | 42 | But don't spend too long climbing down that rabbit hole, you might never make it back. The answer here is actually much simpler than you might infer from some of the answers on Google. Sinatra is just another Ruby program; but it's not yet installed in our workspace. To install Sinatra, enter the following on the command-line. 43 | ``` 44 | $ gem install sinatra 45 | ``` 46 | 47 | You should see a few lines of output and a confirmation that a certain number of gems have been installed. Sinatra is itself dependent on some other programs, so when you install Sinatra, those dependencies are installed too. 48 | 49 | Lets try running it again: 50 | 51 | ``` 52 | $ ruby server.rb 53 | ``` 54 | 55 | Your program should now be running and sending output to the command line. As a slight diversion the line `set :port, 3000` has told our application to run on the port that is reserved for [Hyper Text Transfer Protocol Secure (HTTPS)](https://en.wikipedia.org/wiki/HTTPS). This means that if you now open another tab in your browser you can now visit your application using it's public `https` url which should look like the following: 56 | 57 | `https://[application name, in our case prototypeWebsite]-[Your username].codeanyapp.com` 58 | 59 | You can also find url specifiec on the information page that opened when you first started your container on CodeAnywhere. More excitingly: that's a real, live URL. Try opening it from another window, or from your phone. Cool, huh? 60 | 61 | To stop the program running at any time, press `Ctrl + C` in the command window. 62 | 63 | :twisted_rightwards_arrows: Now that we've completed another small step it's time to switch over again! 64 | 65 | Task 1 66 | ------ 67 | 68 | - [ ] Now the gloves come off...a little. Expanding on what we've just done try to create a route called `'/names'` that, when visited, returns both of your names. 69 | 70 | ------ 71 | 72 | [:arrow_backward: Previous page](./section1.md) | [Continue to the answers :arrow_forward:](../tasks/task1.md) 73 | -------------------------------------------------------------------------------- /courseSections/section3.md: -------------------------------------------------------------------------------- 1 | Responding with HTML 2 | ============================= 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | Admittedly, sending a single string 'Hello world!' to a browser window is not very useful. It is, however, worth it to see how much a web framework does for you. All we had to do in our `server.rb` file was define a **path** (`/`) and a response (`Hello world!`). 7 | 8 | The path forms part of the URL to which the browser makes a request - it's the bit that comes after the domain (i.e. `https://prototypeWebsite-[Your username].codeanyapp.com/`). The single slash (`'/'`) denotes the **root path** - i.e. `https://prototypeWebsite-[Your username].codeanyapp.com/[Nothing Here]` 9 | 10 | Rather than return a single string, let's respond with some HTML. HTML (Hyper Text Markup Language) is the language of the web and it is used to define the *structure* and *content* of a 'page'. Since HTML is just text, you might be tempted to do this: 11 | 12 | ```ruby 13 | require 'sinatra' 14 | set :bind, '0.0.0.0' 15 | set :port, 3000 16 | 17 | get '/' do 18 | '

Hello World

' 19 | end 20 | ``` 21 | 22 | Try it. You will need to stop and restart your program after making the changes. 23 | 24 | > Why is it necessary to stop and restart the program? It may or may not be obvious - but it's good to ask yourself these questions. 25 | 26 | Did it work? It should have. But it's not very pretty and HTML pages can get *very long*, so this approach is not going to scale very well. Ideally, we want to separate the HTML into its own file so it's easier to maintain. Again, this is so fundamental that it's already built into Sinatra. 27 | 28 | Create a new folder in your workspace called `views`. Create a new file inside the `views` folder called `index.erb` with the following content: 29 | 30 | ```html 31 | 32 | 33 | 34 | Prototype Website 35 | 36 | 37 |

Prototype Website

38 |

By tonight I'll have a fully-functioning website!

39 | 40 | 41 | ``` 42 | 43 | Now change the `server.rb` file to the following: 44 | 45 | ```ruby 46 | require 'sinatra' 47 | set :bind, '0.0.0.0' 48 | set :port, 3000 49 | 50 | get '/' do 51 | erb :index 52 | end 53 | ``` 54 | 55 | Save the changes and re-run the program. You might be wondering what the `erb :index` means and why the file is called `index.erb`. If you're not wondering that, then you should be - unless you know already! 56 | 57 | Without going too far into the technology of ERB (Embedded Ruby) and how Sinatra uses it, it's sufficient to understand the `erb :index` looks for a file called `./views/index.erb`, loads it, and returns the contents as text (in this case, the text is HTML). 58 | 59 | Hopefully, you should see something like this: 60 | 61 | ![This is what it should look like](../images/indexErb.png) 62 | 63 | -------- 64 | 65 | :twisted_rightwards_arrows: You know what to do. 66 | 67 | -------- 68 | [:arrow_backward: Previous page](./section2.md) | [Continue to the next section :arrow_forward:](./section4.md) 69 | -------------------------------------------------------------------------------- /courseSections/section4.md: -------------------------------------------------------------------------------- 1 | Git and Version Control 2 | ======================= 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | So we have the beginnings of our website but before we jump into creating an all singing, all dancing web application there is one other aspect of our workflow that needs to be covered: **version control**. 7 | 8 | Version control is the process and technology used to **control** various **versions** of the code that you write. If, for example, you were building a house, you'd likely start with the foundation and make sure it's solid before you started building the walls. You'd want to stop after the walls were built to make sure everything lines up properly before adding the roof. You wouldn't want to build the entire thing and realise, after the roof is built, that there's a crack in the foundation. 9 | 10 | Software version control helps us avoid these problems by allowing us to keep various versions of what we're building. If we realise we've made a mistake, we can revert back to a previous version that we know is solid. 11 | 12 | Additionally, version control allows multiple versions to be built simultaneously and then brought together. It doesn't matter whether you're working in a team or writing code alone, version control is something you absolutely need to understand as a developer (as you'll see it's also very useful for pair programming). 13 | 14 | Using Git to version control your own code 15 | ----------------------------------------- 16 | 17 | The most common version control system used by web developers is git. With git you get all of the benefits of controlling various versions of your code and the ability to handle distributed work among teams. While there are a number of other examples of version control software out there, git is the largest and most popular and it's what we're going to use on this course. 18 | 19 | Luckily for us CodeAnywhere comes with git installed but, just to check, type the following into the command line: 20 | 21 | ``` 22 | $ git --version 23 | ``` 24 | 25 | which should give you 26 | 27 | ``` 28 | git version 1.9.1 29 | ``` 30 | 31 | Setting up your first git repository 32 | ----------------------------------- 33 | 34 | Now that we know we have the tools, let's use git to start version controlling the code we're writing. 35 | 36 | The first thing we need to do is tell git to make our current directory a *git repository*. Type the following into the command line: 37 | 38 | ``` 39 | $ git init 40 | ``` 41 | 42 | You should see the following: 43 | 44 | ``` 45 | Reinitialized existing Git repository in /home/cabox/workspace/.git/ 46 | ``` 47 | 48 | We now have an initialised repository - something that only has to be done once for every repository. This repository is really just a folder that has all its files *under version control*. When you run `git init`, git created a hidden directory called `.git` (with a dot in front) that it uses to track all changes to the files in the directory. Now that we're setup we can actually start tracking the work we've done so far. 49 | 50 | Adding Committing and Status 51 | --------------------------- 52 | 53 | Often when working with a version control system (and throughout today) you'll want to see what state your repository is in. For this we have the `status` command try this in the command line: 54 | 55 | ``` 56 | $ git status 57 | ``` 58 | 59 | What did you see? 60 | 61 | Hopefully if you've kept up with things so far you should see something like this on your screen: 62 | 63 | ![git status](../images/gitStatus.png) 64 | 65 | While there is potentially a lot of information here, the important thing that git is telling us is that we have a number of untracked files. 66 | 67 | Git as a tool is meant to act like a time machine, allowing you to go back to where you've been in the past. However, allowing you to travel to an arbitrary moment in time wouldn't make sense. The thing about time travel is you may want to go back to yesterday, or yesterday morning, or that specific moment right before you try to rob the bank. However, you wouldn't want to go to any specific second of any of the past years, unless that second was somehow important for some reason. 68 | 69 | Tracking every single change you make while coding would be unnecessary and slow (imagine how much disk space it would take to record every single keystroke of every developer on a large project!). So instead of tracking every change, we must tell git when to create a *checkpoint* also known as a *commit* in git terminology that we'll be able to go back in time to. 70 | 71 | However, before creating this *commit*, we need to specify what is being committed. What if we have a temporary file that we don't want to be saved anywhere long-term? Imagine you're using git to track changes to a novel you're writing. You've finished chapter one and you want to commit it to git, so that you could always go back in time to the moment the first chapter is finished. However, you also have some random notes for chapter two that you don't want to save just yet (you'll commit them when chapter two starts taking some shape). 72 | 73 | So, you'd tell git to only add chapter one to the staging area. The staging area is a special place that git uses to keep track of all files that will be committed on the next step. So even if you have several files that have changes since the last commit (or since the repo was created), you can choose which of them will get committed. So, we're telling git that we're happy with the file as it is now and we'd like to create a *checkpoint* (or *commit*) that we could go to in case we ever want to. 74 | 75 | So let's go ahead and do that - adding everything that we've done so far: 76 | 77 | ``` 78 | $ git add README.md hello.rb server.rb views/index.erb 79 | ``` 80 | 81 | Even though there is no output from git after you tell it to add a file, unless you see an error message you can assume it went well. 82 | 83 | > Try running `git status` now. What changes do you see? 84 | 85 | Now we can actually commit our staged changes. Run the following: 86 | 87 | ``` 88 | $ git commit -m "My First Commit" 89 | ``` 90 | 91 | This creates our snapshot in time and unlike when we added our files, git now gives some output to tell us what it is doing. 92 | 93 | ![git commit](../images/gitCommit.png) 94 | 95 | This is what a successful commit message looks like. Git is telling you that it created a commit called "My First Commit" with a number (or hash or SHA) 094d3a5 (yours will be different). 3 files were changed and 33 insertions made (the lines of ruby, HTML and text that we have already written). Now if we ever need to go back to the very beginning we'll be able to `git checkout c11a464` to get us back to this point in time. 96 | 97 | --------- 98 | 99 | [:arrow_backward: Previous section](./section3.md) | [Continue to the next section :arrow_forward:](./section5.md) 100 | -------------------------------------------------------------------------------- /courseSections/section5.md: -------------------------------------------------------------------------------- 1 | Github 2 | ======= 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | ![octocat](../images/octocat.png) 7 | 8 | Making all of these changes on your local computer is great, but we'll need some additional functionality provided by [Github :link:](https://github.com/) to collaborate with other developers. 9 | 10 | Github does three things. Firstly it displays git repos in a visual way, so you can look at them online. Secondly, it serves as a common place for open source projects, so if you're using some open source library, the chances are you can find it on Github. Finally, Github provides a set of tools (forking, issues, etc) to help developers collaborate on projects. If you'd like to see an example Github project, checkout [Bootstrap :link:](https://github.com/twbs/bootstrap). We'll be incorporating this into our project later. 11 | 12 | Github is Distributed 13 | -------------------- 14 | Github is really just another computer somewhere in the USA that you can create a repository on. When (as we will do in a minute) you go to Github and create a new repository, Github does `git init` on its local computer. 15 | 16 | So Github's web interface is nothing more than a visual interface to git installed on Github's server. 17 | 18 | The key feature of git when used in conjunction with Github is the ability to copy code between repositories. If you have a local repository (on your own laptop) and remote repository (on Github), you can copy code in either direction. Crucially you can also move code using git between developers' laptops, even directly if you wish. 19 | 20 | Using Github 21 | ------------ 22 | 23 | If you haven't already then signup for a [free Github account :link:](https://github.com/join) 24 | 25 | Once you are signed up and signed in click on the green new repository button: 26 | 27 | ![New repo](../images/newRepo.png) 28 | 29 | Enter `prototype-website` into the *Repository name* field, add an optional description and make it public so that others can see it. Don't initialise it with a README. Then when you're happy create the repository: 30 | 31 | ![Create repository](../images/repoSetup.png) 32 | 33 | You should see the following: 34 | 35 | ![Empty repo](../images/emptyRepo.png) 36 | 37 | This means that you have a remote repository but it's empty. Github also shows us the steps required for a new repository and for an existing one. Since we already have a repository setup for our application in CodeAnywhere we only have two steps to do. 38 | 39 | The first one is to connect our two repositories together. Right now you have two git repositories: one on CodeAnywhere and one on github but they don't know of each other. So, we need to connect them first. 40 | 41 | Connecting two repositories is done by creating something called a *remote*. This is simply a record in a local repository that it's linked to another one. Let's take a look at the current list of the remotes for your local git repo. Run the following in the command line: 42 | 43 | ``` 44 | $ git remote -v 45 | ``` 46 | 47 | > What did you get? What do you think this means? 48 | 49 | Hopefully, you were thinking that the lack of output means that your local git repo has no associated remotes. Now let's follow the advice that git gave us and set one up (The remote we're adding is the SSH URL and can be copied directly from git or entered manually as follows): 50 | 51 | ``` 52 | $ git remote add origin git@github.com:[Your username]/prototype-website.git 53 | ``` 54 | 55 | Now if you try `$ git remote -v` again you should see something similar to this: 56 | 57 | ![added remote](../images/addedRemote.png) 58 | 59 | What is origin? Honestly, you can replace origin with anything that you want it's just a conventional name but if you're using one repository to store code remotely (i.e. on github) and you're coordinating the work of a team then it's convention among developers to call that repository origin. 60 | 61 | Awesome! Now your local repository knows that it's *linked* to another repository somewhere on github.com. Note that no real connection is established yet. You could have added a remote while being offline. To actually move the code we have committed locally to the repo on Github (called origin) we need to use the `git push` command. 62 | 63 | Pushing your code 64 | --------------- 65 | 66 | Back in CodeAnywhere go to the command line and run the following: 67 | 68 | ``` 69 | $ git push -u origin master 70 | ``` 71 | 72 | You should see some output: 73 | 74 | ``` 75 | Warning: Permanently added 'github.com,192.30.253.112' (RSA) to the list of known hosts. 76 | Counting objects: 6, done. 77 | Delta compression using up to 8 threads. 78 | Compressing objects: 100% (4/4), done. 79 | Writing objects: 100% (6/6), 862 bytes | 0 bytes/s, done. 80 | Total 6 (delta 0), reused 0 (delta 0) 81 | To github.com:ALRW/prototype-website.git 82 | * [new branch] master -> master 83 | ``` 84 | 85 | This means that the push went well. Let's just quickly break down the command. It tells git to push code from your local repository (it's implied) to a repository called origin (that's the name of the remote we've just added). The last bit, "master", means that we're pushing the branch called "master" (the only branch we have right now). We haven't discussed branches yet, so don't worry about it. The "-u" switch means that these parameters should be saved as default, so next time you won't have to type "origin master". You'll be able to simply do: 86 | 87 | ``` 88 | $ git push 89 | ``` 90 | 91 | Try it now. Git will tell you that everything is up to date. This means that there are no local changes that haven't been pushed yet to Github. 92 | 93 | Ok, now let's flick over to Github itself. Refresh the page....What do you see? 94 | 95 | Hopefully, you should see all your code held on github with your readme displayed. Compare it to your local version, each of the files should contain exactly the same content. 96 | 97 | So now you have two repositories, one locally and one on Github, that have the same commits. Now even if you do lose your laptop you'll at least be able to get your code from Github. 98 | 99 | Adding a collaborator 100 | -------------------- 101 | 102 | Our ultimate goal is for your pair partner to have access to the code you have created. In order to do this we need to tell github to add a collaborator to the repo we have created. On the repository page navigate to `Settings` and then `Collaborators`. 103 | 104 | ![navigate to collaborators](../images/navigateToCollaborators.png) 105 | 106 | Enter the username, name or email address of your pair partner's github account and *voila* they will have access to your repository. 107 | 108 | ---------- 109 | 110 | [:arrow_backward: previous section](./section4.md) | [Continue to the next section :arrow_forward:](./section6.md) 111 | -------------------------------------------------------------------------------- /courseSections/section6.md: -------------------------------------------------------------------------------- 1 | Pulling code from Github 2 | ==================================== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | To recap, by now you know how to create a repo locally and push your local code to Github. Now you also need to know how to get your code back from Github. Let's say you and one other developer work on a website together. You both have local repos and a Github repository that you both have added as a remote called "origin". Your colleague made some changes to the website and pushed them to github. How do you get them? You need to "pull" them: 7 | 8 | ``` 9 | $ git pull origin master 10 | ``` 11 | 12 | Running this command tells git to get all the latest commits from origin and copy them into your local repository. Try pulling the changes in CodeAnywhere now. Nothing will happen because there are no remote changes. 13 | 14 | Let's make a remote change. We'll use github UI for this but normally this would happen because someone else pushed new code. 15 | 16 | :twisted_rightwards_arrows: When switching pairs this time the new driver should now use their own laptop. 17 | 18 | Go to the git repo and click on the `README.md` file. 19 | 20 | There is an edit button :pencil2:. Click on this and add the following to the readme: 21 | 22 | ``` 23 | PROTOTYPE WEBSITE 24 | ================= 25 | 26 | The Best Prototype Website Ever 27 | ``` 28 | 29 | ![edit on git](../images/editOnGit.png) 30 | 31 | Add a commit message and then click on `Commit changes` 32 | 33 | Excellent. We have now made changes on the Github computer. Now on your laptop (this should be the laptop that has no code written on it yet) go to your CodeAnywhere account and follow the steps in [section 1 from **Getting Started** to **Updating the README**](./section1.md). 34 | 35 | This should give you a blank project. Now rather than doing all of that work again we would like to fast forward to the same point that your github repository is at. 36 | 37 | First as this is a blank project, we need to initialise git using: 38 | 39 | ``` 40 | $ git init 41 | ``` 42 | 43 | > What do you think we need to do next before we can get the code you have on github? 44 | 45 | Did you guess? That's right, we need to tell your local environment to use the remote `origin` as the place it can push and pull code from. 46 | 47 | In case you don't have the URL for the repository to hand on the repository home-page there is a helpful little button `clone or download` from which you can copy the repositorys SSH link. 48 | 49 | ![copy SSH Link](../images/copySSHLink.png) 50 | 51 | Then as before: 52 | 53 | ``` 54 | $ git remote add origin git@github.com:[username of the person who created the repo]/prototype-website.git 55 | ``` 56 | 57 | You should now have your local project linked to the remote repo on github that your pair created. You can check that this is correct by running: 58 | 59 | ``` 60 | $ git remote -v 61 | ``` 62 | 63 | Now to make the magic happen: if you go back to the command line and run 64 | 65 | ``` 66 | $ git pull origin master 67 | ``` 68 | 69 | If you open up/refresh the `README.md` you should now see the changes you made on Github. Neat! 70 | 71 | Time Travelling 72 | -------------- 73 | 74 | So far we have added our code, pushed, made some further changes and then pulled those changes back down from Github. 75 | 76 | What if we wanted to go back in time to the first time we made a commit? 77 | 78 | To see all the commits that have been made in the past use the command `$ git log`. You should see something similar to the following: 79 | 80 | ``` 81 | commit 743d0c7b48698192a367892aeb67f947937e4e81 82 | Author: John <123456@gmail.com> 83 | Date: Tue Mar 21 17:22:27 2017 +0000 84 | 85 | Updated the readme 86 | 87 | commit 094d3a55c05f25623d4f7d3db570e7070bf09d32 88 | Author: John <123456@gmail.com> 89 | Date: Mon Mar 20 16:39:52 2017 +0000 90 | 91 | My First Commit 92 | ``` 93 | 94 | Now for the exciting part. Copy the commit ID for your first commit and run the *checkout* command like so: 95 | 96 | ``` 97 | $ git checkout 094d3a55c05f25623d4f7d3db570e7070bf09d32 98 | ``` 99 | 100 | Look at your `README.md` now. You have just travelled back to the past. Now to get us back to the present: 101 | 102 | ``` 103 | $ git checkout master 104 | ``` 105 | 106 | You should now see that our changes to the `README.md` have been reinstated. We haven't lost any work and importantly we can now propagate changes made by one person onto another persons computer and (through github) to the rest of the world. 107 | 108 | When and how to commit 109 | --------------------- 110 | 111 | As a final aside it wouldn't be very good if you learned all of this without touching on when and how to use git - *git-etiquette* if you will. 112 | 113 | A good rule of thimb is **commit early, commit often**. Whenever you make a meaningful change, make a commit. You don't have to push it to Github straight away: you can make several commits and then push them in one go. 114 | 115 | Make a commit when you've done a meaningful piece of work. Ideally, your commit log should document the developement of the project. For example: 116 | 117 | - Intial commit (added Readme file) 118 | - Added an empty web page 119 | - Put a welcome message on the page 120 | - Added a header with a logo 121 | - Added a footer with a few links 122 | - Added /contact-us page 123 | 124 | and so on and so forth (in reality it'll be more detailed and technical). Read [the commit messages of the jQuery project :link:](https://github.com/jquery/jquery/commits/master) to get an idea of what they look like in real life. 125 | 126 | Task 2 - Switching pairs using git 127 | ---------------------------------- 128 | 129 | :twisted_rightwards_arrows: Now that you know the basics we can integrate git into our workflow 130 | 131 | - [ ] This time when you switch over add a line to your readme saying what you want to learn on this course then `add` and `commit` your changes `push` them up to github then your pair partner should `pull` them down. Good luck! 132 | 133 | ---------- 134 | 135 | [:arrow_backward: Previous Section](./section5.md) | [Continue to the Answers :arrow_forward:](../tasks/task2.md) 136 | 137 | -------------------------------------------------------------------------------- /courseSections/section7.md: -------------------------------------------------------------------------------- 1 | A Prototype Website 2 | =================== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | You've come a long way already today and now that we've accumulated a large amount of building-block knowledge let's put it to use and actually build ourselves a prototype website. 7 | 8 | To set the scene. A potential client has expressed interest in revamping their business website and wants to see what we are capable of. They have asked us to produce a prototype website for their "prototype" business. Kindly they have also provided us with a few user stories and a number of wireframes to work with. Fantastic. 9 | 10 | To start with. 11 | 12 | ``` 13 | As a prototypical business owner 14 | I want a website 15 | So that I communicate my prototypes to the world 16 | ``` 17 | 18 | ``` 19 | As a prototypical user 20 | I want a navigation bar 21 | So that I can navigate around a prototype website 22 | ``` 23 | 24 | ``` 25 | As a logo obsessed prototypical business owner 26 | I want to see my prototype logo and company name on the website navigation bar 27 | So that I am able to sleep at night 28 | ``` 29 | 30 | ``` 31 | As a detail oriented prototypical user 32 | I want to see a description of my prototype business on the website's home page 33 | So that I can understand what a "prototype" business is 34 | ``` 35 | 36 | And an initial wireframe of the page: 37 | 38 | ![first Wireframe](../images/firstWireframe.png) 39 | 40 | Where do I start?!! 41 | ------------------- 42 | 43 | Ok so we have our starting requirements, but maybe you're thinking "*how am I going to get from the simple page with a bit of text to a pristine looking webpage?*" :confused: that is to say, this looks like a rather large jump in task size. This is a common theme for developers so it is worth discussing now. A developer produces the best results when faced with a small narrowly defined piece of work. However, we live in the real world and as this task demonstrates we need to be able to deliver. So mentally we need to break down the work into smaller bite-size chunks that we can easily reason about and therefore complete. 44 | 45 | You may have heard developers talk about **Front-end** and **Back-end** - the terminology may sound a little dodgy but this is an example of this kind of *breaking down* that allows us to reason about seperate parts of the same task. Concretely, you have already done both front-end and back-end development. When you created your ruby program: 46 | 47 | ```ruby 48 | get '/' do 49 | erb :index 50 | end 51 | ``` 52 | that was you programming the back-end server to perform the task of automatically getting you a particular resource when you asked for it. 53 | 54 | the `index.erb` that you created is your front-end: the resource that will be returned to you and rendered in your web browser. Developers who work creating content for both the front-end and back-end are known as a full-stack developers. 55 | 56 | So onto the first user story. To get this prototype website off the ground we need to have a route setup to serve this page for us. Handily we've already done this with the above piece of code. Why reinvent the wheel when we can reuse the work we've already done. If that feels to easy, don't worry that will all change soon! 57 | 58 | Adding a front-end framework 59 | ---------------------------- 60 | 61 | We now want to move on to updating the content. You may remember that we've been using the framework (just a fancy way of saying someone elses code) **Sinatra** to help with our back-end. Well now we are going to do the same with our front-end using a framework called [Bootstrap :link:](https://getbootstrap.com/) to help structure our page and make it look pretty. 62 | 63 | As you may also remember the first thing we need to do is tell our program that it needs to incorporate this framework. 64 | 65 | Open up your `index.erb` in CodeAnywhere and update it to look like this: 66 | 67 | ```html 68 | 69 | 70 | 71 | Prototype website 72 | 73 | 74 | 75 |

Prototype Website

76 |

By tonight I'll have a fully-functioning website!

77 | 78 | 79 | ``` 80 | 81 | This addition of the `` tells our html template to go and get the external resource located at the link specified in the `href` attribute. Don't worry too much about the specifics of the other attributes for now, suffice to say they are security related and ensure that we are pulling in what we intend and not some malicious code. 82 | 83 | Navbar 84 | ----- 85 | 86 | Now that we have access to bootstrap let's move forward to the next user story. 87 | 88 | Update the ` ... ` section of your `index.erb` file with the following: 89 | 90 | ```html 91 | 92 | 96 | 97 | ``` 98 | 99 | Remember to save your file and then if you need to, start up your sever again using the commands below, or otherwise just refresh the page. 100 | 101 | ``` 102 | $ ruby server.rb 103 | ``` 104 | 105 | Hopefully when you preview your masterpiece you should see the following rather unexciting page. 106 | 107 | ![blank navbar](../images/blankNavbar.png) 108 | 109 | Task 3 110 | ------ 111 | 112 | :twisted_rightwards_arrows: Now's a good opportunity to switch using git to add, commit, push and pull your changes. 113 | 114 | Another thing developers spend a large amount of their time on is reading documentation. We've pulled in the bootstrap framework which gives us access to a whole bag of tools, their documentation is how we learn how to use the toolkit so let's do some research: 115 | 116 | - [ ] Using the documentation below add the company logo and name: "Prototype Inc." to the navigation bar to fulfil the following user story 117 | 118 | ``` 119 | As a logo obsessed prototypical business owner 120 | I need to see my prototype logo and company name on the website navigation bar 121 | In order to be able to sleep at night 122 | ``` 123 | 124 | For this task you should have a look at the bootstrap documentation for navbars [bootstrap documentation for navbars :link:](https://getbootstrap.com/components/#navbar). You may also want to look into how the [html tag works :link:](https://www.w3schools.com/tags/tag_img.asp). 125 | 126 | Kindly our client has provided the following logo for us: 127 | 128 | ![fullLogo](../images/fullLogo.png) 129 | 130 | The icon you need to add can be loaded from the following url: 131 | 132 | ``` 133 | https://raw.githubusercontent.com/ALRW/dayAsADev/master/images/glyphicon.png 134 | ``` 135 | 136 | The client has also asked that we add the company name as a `

` size element. 137 | 138 | Good luck! 139 | 140 | ------------------ 141 | 142 | [:arrow_backward: Return to previous section](../tasks/task2.md) | [Continue to answers :arrow_forward:](../tasks/task3.md) 143 | 144 | ------------------ 145 | 146 | Icon made by [Freepik :link:](www.freepik.com) from [www.flaticon.com :link:](www.flaticon.com) 147 | -------------------------------------------------------------------------------- /courseSections/section8.md: -------------------------------------------------------------------------------- 1 | Finishing the Home Page 2 | ======================= 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | All we have left to do for our homepage now is the last of our user stories. 7 | 8 | ``` 9 | As a detail oriented prototypical user 10 | I would like to see a description of my prototype business on the websites home page 11 | In order to understand what a "prototype" business is 12 | ``` 13 | 14 | To help us comply with the wireframe we were givene we will use the useful [bootstrap jumbotron element :link:](https://getbootstrap.com/components/#jumbotron) within bootstrap's handy [grid system :link:](https://getbootstrap.com/css/#grid). 15 | 16 | The client has also kindly provided us with some text that they would like us to use on the website (in this case feel free to copy and paste the text). 17 | 18 | Below your closing `` tag, add the following to your `index.erb`: 19 | 20 | ```html 21 |
22 |
23 |
24 |
25 |
26 |
27 |

Home of the World's Best Prototypes

28 |

29 | A prototype is an early sample, model, or release of a product built to test a concept or process or to act as a thing to be replicated or learned from. 30 | It is a term used in a variety of contexts, including semantics, design, electronics, and software programming. 31 | A prototype is generally used to evaluate a new design to enhance precision by system analysts and users. 32 | Prototyping serves to provide specifications for a real, working system rather than a theoretical one. 33 | In some design workflow models, creating a prototype (a process sometimes called materialization) is the step between the formalization and the evaluation of an idea. 34 |

35 |

This website showcases some of the most prototypical of prototypes.

36 |
37 |
38 |
39 |
40 |
41 |
42 | ``` 43 | 44 | If you refresh your preview page it should now look like the following: 45 | 46 | ![base homepage](../images/baseHomepage.png) 47 | 48 | At this point you're probably wondering: how is bootstrap making all of our html look so pretty?!! Fear not, after a brief detour, all will be explained. 49 | 50 | :twisted_rightwards_arrows: 51 | 52 | ---------- 53 | 54 | [:arrow_backward: Return to previous section](../tasks/task3.md) | [Continue to next section :arrow_forward:](../courseSections/section9.md) 55 | -------------------------------------------------------------------------------- /courseSections/section9.md: -------------------------------------------------------------------------------- 1 | Testing 2 | ======= 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | Testing is a whole topic in and of itself and there are various different tools, models and approaches. However in this case let's try and simplify things down to the bare bones. 7 | 8 | If you look back through the journey we've come on we've already created the bare bones of a functioning website. At each stage we've made some changes and then crucially we've gone back to the webpage, refreshed and *tested* to see that our changes have taken effect. 9 | 10 | Now as developers you should be thinking, ok that's fine in this limited instance but what happens when this prototype website really takes off and we're adding mountains of functionality. I can manually check the whole website to make sure that my changes have come through and that they haven't broken anything else! 11 | 12 | Luckily in the same way we can tell a computer to show us a webpage we can also get it to do our testing. Maybe that feels a little bit lazy but in this case laziness is good, embrace it! 13 | 14 | Setting up your test suite 15 | -------------------------- 16 | 17 | Now in the same way that we have done previously there are certain things that we need to have setup in order for us to begin to create our tests. Don't worry too much about the exact details of what we are doing. At a high level it is essentially configuration telling our program to pull in a number of other programs and setting up the parts that we need. 18 | 19 | So without further ado, in the command line run the following: 20 | 21 | ``` 22 | $ gem install bundle 23 | ``` 24 | 25 | This gives us access to a handy little program that can pull in all our dependencies. 26 | 27 | Now the nice thing about this program is that we can create a `Gemfile` that lives with our project and specifies all of the other programs on which it depends. This means that if anyone else were to takeover building this website they would not have to install each of these programs themselves but can do it all in one go. 28 | 29 | To do this add a new file to your `prototype-website` directory called `Gemfile` and add the following to it 30 | 31 | ```ruby 32 | source "https://rubygems.org" 33 | 34 | gem "rack" 35 | gem "sinatra" 36 | 37 | group :test do 38 | gem "rspec" 39 | gem "rack-test" 40 | end 41 | ``` 42 | 43 | Notice as well as adding the new *gems* (programs) that we need we've also added the sinatra framework that we had installed previously. 44 | 45 | Now go to the command line and run: 46 | 47 | ``` 48 | $ bundle install 49 | ``` 50 | 51 | If all goes well you should see the following output: 52 | 53 | ![bundle install](../images/bundleInstall.png) 54 | 55 | 56 | Writing Tests 57 | ------------- 58 | 59 | Create a new folder called `spec` and create a new file within that called `app_spec.rb`. 60 | 61 | Your folder structure should look like this afterwards 62 | 63 | ![spec folder structure](../images/specFolderStructure.png) 64 | 65 | Now let's add an initial test to check that our `server.rb` will respond to us when run. 66 | 67 | In `app_spec.rb` add the following: 68 | 69 | ```ruby 70 | require File.expand_path '../../server.rb', __FILE__ 71 | require 'rspec' 72 | require 'rack/test' 73 | 74 | ENV['RACK_ENV'] = 'test' 75 | 76 | describe 'Prototype App' do 77 | include Rack::Test::Methods 78 | 79 | def app() Sinatra::Application end 80 | 81 | it 'displays the homepage' do 82 | get '/' 83 | expect(last_response.status).to eq 200 84 | end 85 | 86 | end 87 | ``` 88 | 89 | Save the file and in the command line run: 90 | 91 | ``` 92 | $ rspec 93 | ``` 94 | 95 | What did you see? Is this what you expect? 96 | 97 | While there is some initial configuration in the test file we have just created the key to understanding it is seeing that we are *describing* our Prototype App and saying that *it* displays a homepage. The test is *expecting* to see that when we ask for that page we get a [HTTP 200 response :link:](https://httpstatuses.com/200) essentially telling us that the request has succeeded. 98 | 99 | Great but let's see if we can go a little bit further and actually test what is on the page we have created in `index.erb`. Add the following test after the `end` of the first `it` block and before the `end` of the `describe` block. 100 | 101 | ```ruby 102 | it 'displays the company name: Prototype Inc' do 103 | get '/' 104 | expect(last_response.body).to include "Prototype Inc." 105 | end 106 | ``` 107 | 108 | Now save the file and run `$ rspec` again. 109 | 110 | You should get a quick response telling you that the tests have been successful. 111 | 112 | Perfect. we now have the beginnings of a test suite that can be added to, saving us time manually checking everything whenever we make any further changes. 113 | 114 | Task 4 115 | ----- 116 | 117 | :twisted_rightwards_arrows: This time when you pull down the changes onto your computer remember that you will need to install the programs we have defined in our gemfile. To do this from the command line you should now only have to run: 118 | 119 | ``` 120 | $ gem install bundle 121 | $ bundle install 122 | ``` 123 | 124 | - [ ] Add a new test as an **it** description within our current tests that sees if our pages **includes** the text within our jumbotron 125 | 126 | Everything you need should be on this page but if you're looking to do something fancy then feel free to look into the [Rspec testing framework documentation :link:](http://www.rubydoc.info/gems/rspec-expectations/frames) 127 | 128 | ---------- 129 | 130 | [:arrow_backward: Previous Section](./section8.md) | [Continue to the Answers :arrow_forward:](../tasks/task4.md) 131 | -------------------------------------------------------------------------------- /images/addedRemote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/addedRemote.png -------------------------------------------------------------------------------- /images/baseHomepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/baseHomepage.png -------------------------------------------------------------------------------- /images/blankHerokuApp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/blankHerokuApp.png -------------------------------------------------------------------------------- /images/blankNavbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/blankNavbar.png -------------------------------------------------------------------------------- /images/bundleInstall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/bundleInstall.png -------------------------------------------------------------------------------- /images/c9InitialReadme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/c9InitialReadme.png -------------------------------------------------------------------------------- /images/clutteredHomepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/clutteredHomepage.png -------------------------------------------------------------------------------- /images/codeAnywhereInit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/codeAnywhereInit.png -------------------------------------------------------------------------------- /images/codeAnywhereLandingPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/codeAnywhereLandingPage.png -------------------------------------------------------------------------------- /images/codeAnywhereSignup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/codeAnywhereSignup.png -------------------------------------------------------------------------------- /images/colourPalette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/colourPalette.png -------------------------------------------------------------------------------- /images/contactWireframe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/contactWireframe.png -------------------------------------------------------------------------------- /images/containerSetup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/containerSetup.png -------------------------------------------------------------------------------- /images/cookieText.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/cookieText.png -------------------------------------------------------------------------------- /images/copySSHLink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/copySSHLink.png -------------------------------------------------------------------------------- /images/createReadme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/createReadme.png -------------------------------------------------------------------------------- /images/editOnGit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/editOnGit.png -------------------------------------------------------------------------------- /images/emptyRepo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/emptyRepo.png -------------------------------------------------------------------------------- /images/fileTree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/fileTree.png -------------------------------------------------------------------------------- /images/finalTree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/finalTree.png -------------------------------------------------------------------------------- /images/finalWireframe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/finalWireframe.png -------------------------------------------------------------------------------- /images/firstWireframe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/firstWireframe.png -------------------------------------------------------------------------------- /images/fullLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/fullLogo.png -------------------------------------------------------------------------------- /images/gitCommit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/gitCommit.png -------------------------------------------------------------------------------- /images/gitStatus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/gitStatus.png -------------------------------------------------------------------------------- /images/glyphicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/glyphicon.png -------------------------------------------------------------------------------- /images/goodJob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/goodJob.png -------------------------------------------------------------------------------- /images/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/graph.png -------------------------------------------------------------------------------- /images/herokuCreated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/herokuCreated.png -------------------------------------------------------------------------------- /images/imageWireframe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/imageWireframe.png -------------------------------------------------------------------------------- /images/indexErb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/indexErb.png -------------------------------------------------------------------------------- /images/navbarBrand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/navbarBrand.png -------------------------------------------------------------------------------- /images/navbarTitle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/navbarTitle.png -------------------------------------------------------------------------------- /images/navigateToCollaborators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/navigateToCollaborators.png -------------------------------------------------------------------------------- /images/newRepo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/newRepo.png -------------------------------------------------------------------------------- /images/nonRunning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/nonRunning.png -------------------------------------------------------------------------------- /images/octocat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/octocat.png -------------------------------------------------------------------------------- /images/pairProgramming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/pairProgramming.png -------------------------------------------------------------------------------- /images/repoSetup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/repoSetup.png -------------------------------------------------------------------------------- /images/rspecPass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/rspecPass.png -------------------------------------------------------------------------------- /images/rvmInstall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/rvmInstall.png -------------------------------------------------------------------------------- /images/specFolderStructure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/specFolderStructure.png -------------------------------------------------------------------------------- /images/styledHomepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/styledHomepage.png -------------------------------------------------------------------------------- /images/tdd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/tdd.png -------------------------------------------------------------------------------- /images/travisIntegrate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/travisIntegrate.png -------------------------------------------------------------------------------- /images/travisOutput.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/travisOutput.png -------------------------------------------------------------------------------- /images/travisProfile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/travisProfile.png -------------------------------------------------------------------------------- /images/travisSignup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/travisSignup.png -------------------------------------------------------------------------------- /images/tsPrototype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ALRW/dayAsADev/a64232734b9817f6c0f8c9414dfba3f6429338a0/images/tsPrototype.png -------------------------------------------------------------------------------- /navigation.md: -------------------------------------------------------------------------------- 1 | Course Navigation 2 | ================= 3 | 4 | Home pages 5 | --------- 6 | - [Course Home](./README.md) 7 | - [Precourse](./precourse.md) 8 | 9 | Course Sections 10 | --------------- 11 | 12 | - [Section 0 - Pair Programming](./courseSections/section0.md) 13 | - [Section 1 - Development Environment](./courseSections/section1.md) 14 | - [Section 2 - Welcome to the World Wide Web](./courseSections/section2.md) 15 | - [Section 3 - Responding with HTML](./courseSections/section3.md) 16 | - [Section 4 - Git and Version Control](./courseSections/section4.md) 17 | - [Section 5 - Github](./courseSections/section5.md) 18 | - [Section 6 - Pulling code from Github](./courseSections/section6.md) 19 | - [Section 7 - A Prototype Website](./courseSections/section7.md) 20 | - [Section 8 - Finishing the Home Page](./courseSections/section8.md) 21 | - [Section 9 - Testing](./courseSections/section9.md) 22 | - [Section 10 - Adding Your Own Style](./courseSections/section10.md) 23 | - [Section 11 - Making Things Happen With JavaScript](./courseSections/section11.md) 24 | - [Section 12 - Refactoring](./courseSections/section12.md) 25 | - [Section 13 - Deployment](./courseSections/section13.md) 26 | - [Section 14 - Continuous Integration and Continuous Delivery](./courseSections/section14.md) 27 | - [Section 15 - Continuous Deployment](./courseSections/section15.md) 28 | - [Section 16 - Changing Requirements, Rotting Code and Test Driven Development](./courseSections/section16.md) 29 | - [Section 17 - Course Finale!](./courseSections/section17.md) 30 | 31 | 32 | Answers 33 | ------- 34 | 35 | - [Task 1 - Creating a new route](./tasks/task1.md) 36 | - [Task 2 - Getting your code to Git](./tasks/task2.md) 37 | - [Task 3 - Adding an icon to the Navbar](./tasks/task3.md) 38 | - [Task 4 - Testing our page content](./tasks/task4.md) 39 | - [Task 5 - Styling the page](./tasks/task5.md) 40 | - [Task 6 - Adding JavaScript for all of our elements](./tasks/task6.md) 41 | - [Task 7 - Adding Technical Debt](./tasks/task7.md) 42 | 43 | 44 | --------- 45 | 46 | [:tada: Acknowledgements :tada:](./acknowledgements.md) 47 | -------------------------------------------------------------------------------- /precourse.md: -------------------------------------------------------------------------------- 1 | Precourse 2 | ========= 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](./navigation.md) 5 | 6 | For this course we will be using a number of free services to help reduce the amount of configuration required and to allow you to focus on learning. 7 | 8 | Before coming on this course please create a free account for Github and Heroku(the links will take you through to the signup pages) 9 | 10 | - [Github :link:](https://github.com/join) 11 | - [Heroku :link:](https://signup.heroku.com) 12 | 13 | Once you have these accounts you can then signup to the following services using your Github account. In both cases you will be taken through to Github to authorise access. 14 | 15 | - [CodeAnywhere :link:](https://codeanywhere.com/signup) 16 | 17 | ![CodeAnywhere Signup](./images/codeAnywhereSignup.png) 18 | 19 | - [Travis CI :link:](https://travis-ci.org/auth) 20 | 21 | ![Travis Signup](./images/travisSignup.png) 22 | 23 | Security 24 | -------- 25 | 26 | Security is not a dirty word, mostly. Given that we've just signed up to a load of services some of which use our credentials from another service it could be worth considering setting up two-factor authentication on your Github account. 27 | 28 | Additionally, you will need your usernames and passwords for Github and Heroku on the day so either make them memorable or use a [Secure Password Manager :link:](https://www.lastpass.com/). And as a bit of further inculcation into the developer world here is xkcd's advice on passwords: 29 | 30 | ![xkcd](https://imgs.xkcd.com/comics/password_strength.png) 31 | 32 | -------- 33 | 34 | Now enough admin! Take a minute to pat yourself on the back: you now have everything need to complete the course! 35 | 36 | [:school: Return to the homepage :school:](./README.md) 37 | 38 | -------------------------------------------------------------------------------- /tasks/task1.md: -------------------------------------------------------------------------------- 1 | Task 1 - Creating a new route 2 | ============================= 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | 7 | To create a new route that returns both of your names you need to add another method to the `server.rb` file like so: 8 | 9 | ```ruby 10 | get '/names' do 11 | '[first name here] and [second name here]' 12 | end 13 | ``` 14 | 15 | > Replace the square brackets and their contents with your names 16 | 17 | Make sure you save the upated file. If you have your ruby process running then stop it by pressing `Ctrl-c` in the command-line . Startup the process again (or for the first time) with the newly updated ruby file by running: 18 | 19 | ``` 20 | $ ruby server.rb 21 | ``` 22 | 23 | You should now be able to visit `https://[application name, in our case prototypeWebsite]-[Your username].codeanyapp.com/names` 24 | and hopefully both of your names will be displayed for all to see! 25 | 26 | Good job! :twisted_rightwards_arrows: 27 | 28 | [:arrow_backward: Back to section 2](../courseSections/section2.md) | [Continue to Section 3 :arrow_forward:](../courseSections/section3.md) 29 | -------------------------------------------------------------------------------- /tasks/task2.md: -------------------------------------------------------------------------------- 1 | Task 2 - Getting your code to Git 2 | ================================ 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | Once you have added something like `I want to learn how to be more like [insert name] awesome developer that I know` to your readme and saved it then running 7 | 8 | ``` 9 | $ git status 10 | ``` 11 | 12 | should show you that there are changes to your `README.md` file. Add this 13 | 14 | ``` 15 | $ git add README.md 16 | ``` 17 | 18 | and then commit it. 19 | 20 | ``` 21 | $ git commit -m "Updated the readme with my motivation to learn" 22 | ``` 23 | 24 | then push 25 | 26 | ``` 27 | $ git push -u origin master 28 | ``` 29 | 30 | by following these steps your code should now be up on Github. 31 | 32 | :twisted_rightwards_arrows: You should now switch over and on the new driver's laptop pull down the changes by running: 33 | 34 | ``` 35 | $ git pull origin master 36 | ``` 37 | 38 | Double check: if you open `README.md` do you see the changes that are held on github? 39 | 40 | Congratulations you now have all the basics of version control. 41 | 42 | ![Good job](../images/goodJob.png) 43 | 44 | Switching 45 | --------- 46 | 47 | For the rest of this course whenever you see the :twisted_rightwards_arrows: you should add, commit and push your code so that your pair partner can pull down your changes and work away on their own laptop. 48 | 49 | :blue_book: Consider bookmarking this page for quick reference. 50 | 51 | Otherwise if everything is good lets get building! 52 | 53 | -------- 54 | 55 | [:arrow_backward: Return to previous section](../courseSections/section6.md) | [Continue to Section 7 :arrow_forward:](../courseSections/section7.md) 56 | -------------------------------------------------------------------------------- /tasks/task3.md: -------------------------------------------------------------------------------- 1 | Task 3 - Adding an icon to the Navbar 2 | ===================================== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | Looking at the bootstrap documentation we can see that we just need to add a link `` html tag with a `class="navbar-brand"` around an `` tag. Using the Url provided in the previous section in the `src"..."` attribute we should end up with the following in our body section: 7 | 8 | ```html 9 | 10 | 19 | 20 | ``` 21 | 22 | Let's take a minute to talk through a few of the attributes that we are adding here and explain what they do: 23 | 24 | - A `class` is simple a descriptive name for a group of html items that all share a similar purpose and/or style. 25 | - `href` is something that we'll return to but suffice to say the it is the attribute that specifies where the link (the `` tag) points to. 26 | - When you include an `alt` attribute you give the browser some text that will display if for whatever reason the person viewing your site is unable to load the image itself. 27 | - Lastly the `src` attribute tells our `` tag where it can find the image that it is meant to load for us. 28 | 29 | All being well if you now save your `index.erb` and refresh your preview you should see a slightly more colourful navigation bar. 30 | 31 | ![navbar brand](../images/navbarBrand.png) 32 | 33 | Now finally to add the company name all that should be required is your `

` to added into the html as follows: 34 | 35 | ```html 36 | 37 |
47 | 48 | ``` 49 | 50 | Now when we refresh the page we should see that we have everything required by the user story. 51 | 52 | ![navbar title](../images/navbarTitle.png) 53 | 54 | :twisted_rightwards_arrows: Good job. Lets switch over and get building the rest of our page. 55 | 56 | -------- 57 | 58 | [:arrow_backward: Return to previous page](../courseSections/section7.md) | [Continue to next section :arrow_forward:](../courseSections/section8.md) 59 | -------------------------------------------------------------------------------- /tasks/task4.md: -------------------------------------------------------------------------------- 1 | Task 4 - Testing our page content 2 | ================================= 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | Hopefully you found that pretty simple. 7 | 8 | To complete this task you should simply have had to add another test similar to the last one we wrote that checks whether the jumbotron text is included within the page. It should look similar to this: 9 | 10 | ```ruby 11 | it 'displays the correct content' do 12 | get '/' 13 | expect(last_response.body).to include "Home of the World's Best Prototypes" 14 | end 15 | ``` 16 | 17 | Once you've add your test and saved the `app_spec.rb` file, running `$rspec` in the command line should give you the following output. 18 | 19 | ![rspec tests passing](../images/rspecPass.png) 20 | 21 | As you can see, even with such a small application, the computer is still far more efficient at checking everything, in my case completing its checks in 0.2 seconds. We now do not need to manually check these features every time we make a change freeing us to work on new features in a more efficient manner. 22 | 23 | Now let's give our site a facelift! 24 | 25 | :twisted_rightwards_arrows: 26 | 27 | -------- 28 | 29 | [:arrow_backward: Return to Previous Section](../courseSections/section9.md) | [Continue to next section :arrow_forward:](../courseSections/section10.md) 30 | -------------------------------------------------------------------------------- /tasks/task5.md: -------------------------------------------------------------------------------- 1 | Task 5 - Styling the page. 2 | ========================== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | The first part of this task should be a relatively simple one and we should just be able to re-use some of the styling we created for our `.jumbotron`. 7 | 8 | Styling the `.navbar` element with following: 9 | 10 | ```css 11 | .navbar { 12 | border: solid 2px #BEE3BD; 13 | background-color: #FAF9F9; 14 | } 15 | ``` 16 | 17 | should hopefully leave you with something similar to the screenshot below: 18 | 19 | ![styled homepage](../images/styledHomepage.png) 20 | 21 | Now adding a font. If you follow the documentation on the google fonts page you first need tell your HTML page to import the new font. In this example I've used a font called [*Cookie*](https://fonts.google.com/specimen/Cookie?selection.family=Cookie). So adding: 22 | 23 | ```html 24 | 25 | ... 26 | 27 | ... 28 | 29 | ``` 30 | 31 | Imports the font for us. Now all that's left for us to do is to tell out text elements to use it. 32 | 33 | In `application.css` we can specify these text elements (the `

` and `

` tags) to use the `font-family` css attribute like so: 34 | 35 | ```css 36 | p, h2 { 37 | font-family: 'Cookie', cursive; 38 | } 39 | ``` 40 | 41 | Now when you save and refresh you should see your text wrapped in all the glory of its new font. 42 | 43 | ![Cookie in action](../images/cookieText.png) 44 | 45 | :twisted_rightwards_arrows: Commit your code and switch back over. Now lets see what else our mysterious client would like us to do! 46 | 47 | -------- 48 | 49 | [:arrow_backward: return to previous section](../courseSections/section10.md) | [Continue to next Section :arrow_forward:](../courseSections/section11.md) 50 | -------------------------------------------------------------------------------- /tasks/task6.md: -------------------------------------------------------------------------------- 1 | Task 6 - Adding JavaScript for all of our elements 2 | ================================================== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | So first things first, let's create the content that we are going to use. Underneath the `

` add the following: 7 | 8 | ```html 9 | 23 | ``` 24 | 25 | Now that we have the content we can extend our javascript in `app.js` to account for this new block. 26 | 27 | ```javascript 28 | /* global $ */ 29 | $(document).ready(function(){ 30 | 31 | $('#prototype').click(function(e){ 32 | e.preventDefault(); 33 | $('#contact, #about').removeClass('active'); 34 | $('#prototype').addClass('active'); 35 | $('.contact, .about').addClass('hidden'); 36 | $('.prototype').removeClass('hidden'); 37 | }); 38 | 39 | $('#about').click(function(e){ 40 | e.preventDefault(); 41 | $('#about').addClass('active'); 42 | $('#prototype, #contact').removeClass('active'); 43 | $('.about').removeClass('hidden'); 44 | $('.prototype, .contact').addClass('hidden'); 45 | }); 46 | 47 | $('#contact').click(function(e){ 48 | e.preventDefault(); 49 | $('#contact').addClass('active'); 50 | $('#prototype, #about').removeClass('active'); 51 | $('.contact').removeClass('hidden'); 52 | $('.about, .prototype').addClass('hidden'); 53 | }); 54 | }); 55 | ``` 56 | 57 | The above code works and fulfils our user stories. We now have a nice working website and our client should be mightily pleased but should we? 58 | 59 | > Looking at the above code can you see any issues? Take a moment to think about what might be bad practice about the solution we've just implemented. 60 | 61 | ----------- 62 | 63 | [:arrow_backward: Return to Previous Section](../courseSections/section11.md) | [Continue to next section :arrow_forward:](../courseSections/section12.md) 64 | -------------------------------------------------------------------------------- /tasks/task7.md: -------------------------------------------------------------------------------- 1 | Adding Technical Debt 2 | ===================== 3 | 4 | [:globe_with_meridians: Go to course navigation :globe_with_meridians:](../navigation.md) 5 | 6 | Red 7 | --- 8 | 9 | The first thing we want to do is write a test for the first, smallest bit of functionality that we want to add: 10 | 11 | ```ruby 12 | describe 'mailto link' do 13 | 14 | it 'is right justified on the navigation bar' do 15 | get '/' 16 | expect(last_response.body).to include " 57 | ``` 58 | 59 | Ensure that all your changes have been saved and then run your tests hopefully if all has gone well you should be presented with the following: 60 | 61 | ``` 62 | Finished in 0.03435 seconds (files took 0.18052 seconds to load) 63 | 4 examples, 0 failures 64 | ``` 65 | 66 | Simple! 67 | 68 | Refactor 69 | -------- 70 | 71 | At this point there are a number of things to consider before we move to refactor. We certainly have a lot of things we know we need to remove but is now the right time? 72 | 73 | The answer is possibly. This is a subjective decision: do you think you're next round of TDD would be helped or hindered by any refactoring at this point? Only you can answer that question. For now we'll make the decision to hold off until our feature is fully implemented and go for another round of Red -> Green -> Refactor. 74 | 75 | Red 76 | --- 77 | 78 | Let's now add our next failing test: 79 | 80 | ```ruby 81 | it 'displays the mailto link with the correct address' do 82 | get '/' 83 | expect(last_response.body).to include "
  • " 84 | end 85 | ``` 86 | 87 | Green 88 | ----- 89 | 90 | And now to make it pass simply insert the following inbetween our `` tags. 91 | 92 | ```html 93 |
  • 94 | ``` 95 | 96 | Fantastic if we run our tests now we should see the following output: 97 | 98 | ``` 99 | Finished in 0.03821 seconds (files took 0.18052 seconds to load) 100 | 5 examples, 0 failures 101 | ``` 102 | 103 | Refactor 104 | -------- 105 | 106 | > Before moving forward take a moment to reflect on what we've just done. Throughout this process we haven't even had to open our browser and refresh the page to check whether our feature is actually there. That's been handled by the code (although you can go and check if you don't belive the tests). I don't know about you but it's a lot faster and involves a lot less switching between tabs, windows and screens. 107 | 108 | We're not quite done yet though, the old prototype tab is still there. We need to refactor this out of existence! 109 | 110 | Remove all the offending code from your `index.erb` **and** from our `app.js`. 111 | 112 | Ok brilliant, we've refactored our HTML by removing a load of unwanted content but what about improving the quality of our tests, afterall they are part of our code-base. 113 | 114 | In each of our tests we start by calling 115 | 116 | ```ruby 117 | get '/' 118 | ``` 119 | 120 | If we think about it we only need to get this page once for all of our tests so we can remove this from each of our specs and instead at the top of our `app_spec.rb` we can add the following: 121 | 122 | ```ruby 123 | before(:all) do 124 | get '/' 125 | end 126 | ``` 127 | 128 | Lastly in many of our specs we are checking the body of the page. It might be nice to encapsulate this fact in a helper method: 129 | 130 | ```ruby 131 | def body 132 | last_response.body 133 | end 134 | ``` 135 | 136 | Then in each of our tests: 137 | 138 | ```ruby 139 | expect(body) to include ... 140 | ``` 141 | 142 | As you can see we're getting to the stage now where in our current state further refactoring will give us only minor gains. This would mark the natural point to start implementing any other new features safe in the knowledge that our features are covered by a good suite of tests. 143 | 144 | ---------------- 145 | 146 | Push your code up to Github watch the build progress through Travis CI and all being well deploy automatically to Heroku. Impressive stuff. 147 | 148 | ---------------- 149 | 150 | [:arrow_backward: Return to previous section](../courseSections/section16.md) | [Continue to the next section :arrow_forward:](../courseSections/section17.md) 151 | --------------------------------------------------------------------------------