├── .gitattributes ├── .github └── workflows │ └── rspec.yml ├── .gitignore ├── .ruby-version ├── .tool-versions ├── CONTRIBUTING.md ├── Gemfile ├── Gemfile.lock ├── LICENSE.md ├── Procfile ├── README.md ├── Rakefile ├── app.rb ├── assets ├── javascripts │ ├── analytics.js │ ├── application.js │ ├── checkboxes.js │ ├── doc_page.js │ └── md5.js └── stylesheets │ ├── application.css │ ├── big_checkbox.scss │ ├── coderay.css │ ├── doc_page.scss │ ├── flags.scss │ ├── font_awesome.scss │ ├── header.scss │ ├── step.scss │ └── toc.scss ├── config.ru ├── lib ├── big_checkbox.rb ├── contents.rb ├── doc_page.rb ├── erector_scss.rb ├── flags.rb ├── html5_page.rb ├── markdown_page.rb ├── markdown_renderer.rb ├── media_wiki.rb ├── media_wiki_page.rb ├── raw_page.rb ├── site.rb ├── site_extensions │ ├── docs.rb │ ├── installfest.rb │ ├── intro-to-rails.rb │ └── javascript-snake-game.rb ├── site_index.rb ├── step.rb ├── step_page.rb └── titleizer.rb ├── locales ├── en │ ├── captions.yml │ ├── general.yml │ ├── header_sections.yml │ └── sites.yml ├── es │ ├── captions.yml │ ├── general.yml │ ├── header_sections.yml │ └── sites.yml └── zh-tw │ ├── captions.yml │ ├── general.yml │ └── header_section.yml ├── public ├── flags │ ├── ES.png │ ├── US.png │ └── ZH-TW.png ├── fonts │ ├── aleo-bold-webfont.eot │ ├── aleo-bold-webfont.svg │ ├── aleo-bold-webfont.ttf │ ├── aleo-bold-webfont.woff │ ├── aleo-regular-webfont.eot │ ├── aleo-regular-webfont.svg │ ├── aleo-regular-webfont.ttf │ ├── aleo-regular-webfont.woff │ ├── aleo.css │ ├── opensans-bold.woff │ ├── opensans-italic.woff │ ├── opensans.css │ └── opensans.woff └── img │ ├── check-box.png │ ├── check-dim.png │ ├── check.png │ ├── grid.jpg │ ├── macos.png │ ├── navbar_texture.gif │ ├── tux-trans.png │ └── windows.png ├── sites ├── docs │ └── docs.step ├── frontend │ ├── HTML_attributes.step │ ├── HTML_structure.step │ ├── HTML_tags.step │ ├── _consider_deploying_to_github.step │ ├── _consider_deploying_to_github_again.step │ ├── _developer_tools.step │ ├── _working_effectively_and_efficiently.md │ ├── add_more_elements.step │ ├── add_starter_files.step │ ├── basic_CSS.step │ ├── basic_javascript.step │ ├── deploying_to_github.step │ ├── deploying_to_github_again.step │ ├── developer_tools.step │ ├── front-end-lesson.zip-manifest │ ├── frontend.step │ ├── get_a_sticker.step │ ├── grid.html │ ├── griding_with_bootstrap.step │ ├── html_quick_reference.md │ ├── img │ │ ├── boxmodel.png │ │ ├── css.png │ │ ├── css_bundler.png │ │ ├── css_class.png │ │ ├── css_id.png │ │ ├── css_zen.png │ │ ├── devtools.png │ │ ├── devtools_console.png │ │ ├── devtools_elements.png │ │ ├── devtools_network.png │ │ ├── devtools_script.png │ │ ├── get_a_sticker_fork_button.png │ │ ├── get_a_sticker_https.png │ │ ├── get_a_sticker_output.png │ │ ├── github_create_repo.png │ │ ├── github_name_your_repo.png │ │ ├── hello_html.png │ │ ├── hello_omg.png │ │ ├── hello_structure.png │ │ ├── hello_style.png │ │ ├── hello_title.png │ │ ├── hello_world.png │ │ ├── hello_world_2line.png │ │ ├── hello_world_2line2.png │ │ ├── hello_world_jazzy.png │ │ ├── html_tags_list.png │ │ ├── jquery_result.png │ │ ├── page.png │ │ ├── page_anchors.png │ │ ├── page_html.png │ │ ├── page_img.png │ │ ├── page_sample.jpg │ │ ├── prompt.png │ │ └── zip.png │ ├── introduction_to_html.step │ ├── jquery.step │ ├── jquery_vs_javascript.step │ ├── make_a_web_page.step │ ├── make_columns.step │ ├── resources.step │ ├── tool_installation.step │ └── zip_content │ │ ├── .gitignore │ │ ├── index.html │ │ └── resources │ │ ├── javascript.js │ │ ├── layout.css │ │ └── picture.jpg ├── installfest │ ├── _command-line-glossary.md │ ├── _general-glossary.md │ ├── _install_atom_for_mac.step │ ├── _install_homebrew.step │ ├── _install_ruby.step │ ├── _install_rvm.step │ ├── _install_textmate.step │ ├── _ruby-and-rails-glossary.md │ ├── _switch_to_home_directory.step │ ├── choose_your_operating_system.step │ ├── clean_up.step │ ├── configure_git.step │ ├── create_a_github_account.step │ ├── create_a_heroku_account.step │ ├── create_a_rails_app.step │ ├── create_an_ssh_key.step │ ├── deploy_a_rails_app.step │ ├── editors.step │ ├── get_a_sticker.step │ ├── glossary.step │ ├── img │ │ ├── AboutThisMac.png │ │ ├── WinRailsInstaller.jpg │ │ ├── appstore.jpg │ │ ├── directory.png │ │ ├── get_a_sticker_you_should_see.png │ │ ├── install_atom_mac.gif │ │ ├── railsbridge_ubuntu12-checkbox.png │ │ ├── railsbridge_windowsScreenshot-commandprompt-pinnedtotaskbar.png │ │ ├── railsbridge_windowsScreenshot-commandprompt_ror.png │ │ ├── railsbridge_windows_findingCommandPrompt_win7.png │ │ ├── railsbridge_windows_findingCommandPrompt_win8.png │ │ ├── successful_rails_install.png │ │ ├── xcode-prefs.jpg │ │ └── xcode-tools-install.png │ ├── install_xcode.step │ ├── install_xcode_command_line_tools.step │ ├── install_xcode_from_app_store.step │ ├── install_xcode_from_dvd.step │ ├── installfest.step │ ├── linux.step │ ├── macOS.step │ ├── osx_rvm.step │ └── windows.step ├── intro-to-rails │ ├── CRUD_with_scaffolding.step │ ├── _consider_deploying.step │ ├── _consider_deploying_again.step │ ├── _deploying_to_heroku.step │ ├── _deploying_to_heroku_again.step │ ├── _switch_to_home_directory.step │ ├── _working_effectively_and_efficiently.md │ ├── add_the_project_to_a_git_repo.step │ ├── allow_people_to_vote.step │ ├── clean_up_links_on_the_topics_list.step │ ├── creating_a_migration.step │ ├── credits_and_next_steps.step │ ├── deploying_to_heroku.step │ ├── deploying_to_heroku_again.step │ ├── getting_started.step │ ├── glossary.step │ ├── hooking_up_votes_and_topics.step │ ├── img │ │ ├── Seattle_list_with_topic.png │ │ ├── Seattle_topic_created.png │ │ ├── Seattle_topic_list_page.png │ │ ├── Start_page.png │ │ ├── atom_add_folder_to_project.png │ │ ├── atom_project_as_folder.png │ │ ├── finished_app.png │ │ ├── mvc.png │ │ ├── rails4_rails_info_routing.png │ │ └── workflow.png │ ├── intro-to-rails.step │ ├── make_the_topic_title_a_link.step │ ├── rails_architecture.step │ ├── redirect_to_the_topics_list_after_creating_a_new_topic.step │ ├── ruby_language.step │ ├── running_your_application_locally.step │ ├── setting_the_default_page.step │ └── voting_on_topics.step ├── javascript-snake-game │ ├── img │ │ └── browser_console.png │ ├── javascript-snake-game.step │ ├── js-snake-game-tutorial.zip-manifest │ ├── js │ │ ├── chunk.js │ │ ├── lesson-10.js │ │ ├── lesson-11.js │ │ ├── lesson-12.js │ │ ├── lesson-13.js │ │ ├── lesson-2.js │ │ ├── lesson-3.js │ │ ├── lesson-4.js │ │ ├── lesson-5.js │ │ ├── lesson-6.js │ │ ├── lesson-7.js │ │ ├── lesson-8.js │ │ ├── lesson-9.js │ │ └── snake.js │ ├── lesson-1.step │ ├── lesson-10.step │ ├── lesson-11.step │ ├── lesson-12.step │ ├── lesson-13.step │ ├── lesson-14.step │ ├── lesson-2.step │ ├── lesson-3.step │ ├── lesson-4.step │ ├── lesson-5.step │ ├── lesson-6.step │ ├── lesson-7.step │ ├── lesson-8.step │ ├── lesson-9.step │ └── zip_content │ │ ├── index.html │ │ └── snake.js ├── javascript-to-do-list-with-react │ ├── AdvancedTodoList.zip-manifest │ ├── adding_an_item.step │ ├── building_complex_applications_with_react.step │ ├── creating_a_list.step │ ├── deploying_your_site.step │ ├── developer_tools.step │ ├── javascript-to-do-list-with-react.step │ ├── loading_items.step │ ├── marking_an_item_as_complete.step │ ├── next_steps.step │ └── zip_content │ │ ├── app.js │ │ ├── console-polyfill.js │ │ ├── debut_light.png │ │ ├── index.html │ │ ├── store.js │ │ └── styles.css ├── javascript-to-do-list │ ├── IntermediateTodoList.zip-manifest │ ├── _deploying_your_site.md │ ├── _lesson_format.md │ ├── _teachers_note.md │ ├── adding_an_item.step │ ├── creating_a_list.step │ ├── deploying_your_site.step │ ├── developer_tools.step │ ├── img │ │ ├── browser_console.png │ │ ├── finished_app.png │ │ ├── network_tab.png │ │ └── text_editor_html.png │ ├── javascript-to-do-list.step │ ├── loading_items.step │ ├── marking_an_item_as_complete.step │ ├── next_steps.step │ ├── playing_with_jquery.step │ ├── programming_with_javascript.step │ ├── the_basics_of_a_website.step │ └── zip_content │ │ ├── app.js │ │ ├── debut_light.png │ │ ├── index.html │ │ └── styles.css ├── job-board │ ├── add_a_navbar.step │ ├── add_a_new_job_form.step │ ├── add_more_things.step │ ├── create_a_rails_app.step │ ├── crud_and_resourceful_routing.step │ ├── delete_job_listings.step │ ├── img │ │ ├── crud_grid.jpg │ │ ├── crud_rails_methods.jpg │ │ ├── rails-routes.png │ │ └── request-cycle.jpg │ ├── job-board.step │ ├── listing_the_jobs.step │ ├── make_a_jobs_home_page.step │ ├── make_the_form_work.step │ ├── store_jobs_in_the_database.step │ ├── the_request_cycle.step │ └── update_job_listings.step ├── learn-to-code │ ├── argv.md │ ├── arrays.md │ ├── computers.md │ ├── extra.md │ ├── functions.md │ ├── hashes.md │ ├── img │ │ ├── cookie-recipe.gif │ │ ├── dot.jpg │ │ ├── fruit-banana-snack-banana.svg │ │ ├── one-infinite-loop.jpg │ │ ├── snack-apple.svg │ │ ├── snack-fruit.svg │ │ ├── spoon.jpg │ │ ├── truthiness.png │ │ ├── warehouse.jpg │ │ └── wargames-terminal.jpg │ ├── input_and_output.md │ ├── learn-to-code.md │ ├── logic.md │ ├── loops.md │ ├── methods.md │ ├── next_steps.md │ ├── nil.md │ ├── numbers.md │ ├── objects.md │ ├── sinatra.md │ ├── strings.md │ ├── the_command_line.md │ ├── todo-learntocode.md │ └── variables.md ├── message-board │ ├── add_other_features_of_your_choosing.step │ ├── add_pages_to_create_and_look_at_individual_posts.step │ ├── add_replying.step │ ├── commands.md │ ├── create_a_new_rails_app_with_a_static_home_page.step │ ├── creating_a_new_controller.md │ ├── img │ │ ├── create_post.png │ │ ├── create_reply.png │ │ ├── header.png │ │ ├── inline_reply.png │ │ ├── post_index.png │ │ ├── request-cycle.jpg │ │ ├── show_post.png │ │ ├── show_replies.png │ │ └── static_home_page.png │ ├── inline_replying_on_a_post.step │ ├── install_devise.step │ ├── make_a_posts_index_page.step │ ├── make_it_pretty_with_bootstrap.step │ ├── message-board.step │ ├── mvc_overview.md │ └── the_request_cycle.md ├── ruby │ ├── arrays.step │ ├── booleans.step │ ├── classes.step │ ├── command_line.step │ ├── conditionals.step │ ├── datatypes.step │ ├── functions.step │ ├── hashes.step │ ├── how_to_write_a_program.step │ ├── input_and_output.step │ ├── irb.step │ ├── loops.step │ ├── nil.step │ ├── numbers_and_arithmetic.step │ ├── overview:_building_blocks.step │ ├── overview:_organizing.step │ ├── ruby.step │ ├── running_programs_from_a_file.step │ ├── strings.step │ ├── summary:_basics.step │ ├── summary:_tools.step │ ├── symbols.step │ ├── using_virtual_machines.step │ ├── variables.step │ ├── what_is_ruby.step │ └── working_with_collections.step ├── testing-rails-applications │ ├── additional_concepts.step │ ├── final_challenge.step │ ├── img │ │ └── rails-test-types.png │ ├── testing-rails-applications.step │ ├── testing_frameworks.step │ ├── types_of_tests.step │ └── what_are_tests.step └── workshop │ ├── activities.md │ ├── beginners.mw │ ├── closing.deck.md │ ├── command_prompt.mw │ ├── diagrams.mw │ ├── foundational_skills.deck.md │ ├── helpful_examples.mw │ ├── img │ ├── Win7_search_programs.jpg │ ├── acrobat.jpg │ ├── agile.jpg │ ├── cheatsheet.png │ ├── ey_logo_rgb.png │ ├── firefox.png │ ├── git.png │ ├── git_bash.png │ ├── itunes.png │ ├── linux_logo.gif │ ├── mac_terminal_sm.png │ ├── os_x_logo.jpg │ ├── rails_logo.jpg │ ├── railsbridge_logo.png │ ├── ruby-logo.jpg │ ├── rubygems.png │ ├── windows_logo.gif │ └── wordpress.jpg │ ├── more_teacher_training.deck.md │ ├── more_teacher_training_2016.deck.md │ ├── noobie-outline.txt │ ├── resources.md │ ├── ruby_for_beginners.deck.md │ ├── ruby_for_programmers.deck.md │ ├── ta_cheat_sheet.md │ ├── teacher_cheat_sheet.md │ ├── teaching_tips.md │ ├── topics.md │ ├── web_apps.deck.md │ ├── welcome.deck.md │ └── workshop.md ├── spec ├── app_deck_spec.rb ├── app_spec.rb ├── contents_spec.rb ├── markdown_spec.rb ├── media_wiki_spec.rb ├── site_index_spec.rb ├── site_spec.rb ├── site_syntax_spec.rb ├── sites │ └── meals │ │ ├── _find_utensils.step │ │ ├── breakfast.deck.md │ │ ├── clean_up.md │ │ ├── eat_a_meal.step │ │ ├── find_some_vegetables.step │ │ ├── meals.step │ │ ├── omnivorous.step │ │ ├── orphaned_page.step │ │ ├── prepare_a_meal.step │ │ └── vegetarian.step ├── spec_helper.rb ├── step_page_spec.rb ├── step_spec.rb ├── support │ ├── i18n_helper.rb │ └── matchers.rb └── titleizer_spec.rb └── step_file_reference.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/dealing-with-line-endings 2 | 3 | # Set default behaviour, in case users don't have core.autocrlf set. 4 | * text=auto 5 | 6 | -------------------------------------------------------------------------------- /.github/workflows/rspec.yml: -------------------------------------------------------------------------------- 1 | name: RSpec 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | rspec: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v3 17 | 18 | - name: Set up Ruby 19 | uses: ruby/setup-ruby@v1 20 | with: 21 | bundler-cache: true 22 | 23 | - name: Install dependencies 24 | run: bundle install 25 | 26 | - name: Run test and linter 27 | run: 28 | bundle exec rake 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .bundle 3 | .env 4 | .idea 5 | .rvmrc 6 | .sass-cache 7 | Thumbs.db 8 | .byebug_history 9 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.2.2 2 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | ruby 3.2.2 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | ruby '3.2.2' 4 | 5 | gem 'activesupport' 6 | gem "erector", github: "erector/erector" 7 | gem "sinatra" 8 | gem "sinatra-contrib" 9 | gem "nokogiri" 10 | gem "thin" 11 | gem 'rack-codehighlighter' 12 | gem 'coderay' 13 | gem "deckrb" 14 | gem "sass" 15 | gem "redcarpet" 16 | gem "rubyzip" 17 | gem "i18n" 18 | gem 'font-awesome-sass' 19 | gem 'bootstrap-sass' 20 | gem 'jquery-cdn' 21 | gem 'sprockets' 22 | gem 'ffi' 23 | gem 'backports' 24 | 25 | group :development do 26 | gem "rspec" 27 | gem "rerun" 28 | gem "rake" 29 | gem "rack-test" 30 | gem 'files', github: "alexch/files" 31 | gem 'rb-fsevent', :platform => :ruby 32 | end 33 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: rackup -s thin -p $PORT 2 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | def windows? 2 | Rake::Win32.windows? 3 | end 4 | 5 | begin 6 | require 'rspec/core/rake_task' 7 | 8 | task :default => :spec 9 | 10 | desc "Run all specs" 11 | RSpec::Core::RakeTask.new(:spec) do |t| 12 | t.pattern = "spec/**/*_spec.rb" 13 | t.rspec_opts = 14 | "--format d" 15 | t.rspec_opts += " --color" unless windows? 16 | # t.ruby_opts="-w" 17 | end 18 | rescue LoadError # swallow Heroku deploy error 19 | end 20 | 21 | def rerun cmd, rerun_opts = nil 22 | if windows? 23 | exec cmd 24 | else 25 | exec "rerun #{rerun_opts} -- #{cmd}" 26 | end 27 | end 28 | 29 | desc "run the site locally (visit http://localhost:9292)" 30 | task :run do 31 | rerun "rackup -s thin -p #{ENV['PORT'] || 9292}" 32 | end 33 | -------------------------------------------------------------------------------- /assets/javascripts/analytics.js: -------------------------------------------------------------------------------- 1 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 2 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 3 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 4 | })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); 5 | 6 | ga('create', 'UA-40977319-4', 'auto'); 7 | ga('send', 'pageview'); 8 | -------------------------------------------------------------------------------- /assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | //= require 'jquery' 2 | //= require 'doc_page' 3 | //= require 'bootstrap/dropdown' 4 | //= require 'analytics' 5 | //= require 'md5' 6 | //= require 'checkboxes' 7 | -------------------------------------------------------------------------------- /assets/javascripts/checkboxes.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | function saveCheckboxValue (hashcode, value) { 3 | try { 4 | localStorage['checkbox_' + hashcode] = value; 5 | } catch (e) { } 6 | } 7 | 8 | function fetchCheckboxValue (hashcode) { 9 | try { 10 | return localStorage['checkbox_' + hashcode]; 11 | } catch (e) { 12 | return false; 13 | } 14 | } 15 | 16 | var $checkboxes = $('.big_checkbox'); 17 | 18 | $checkboxes.each(function () { 19 | var $checkbox = $(this); 20 | var content = $checkbox.closest('.step').text(); 21 | var hashcode = md5(content); 22 | $checkbox.data('hashcode', hashcode); 23 | $checkbox.prop('checked', fetchCheckboxValue(hashcode) === 'true'); 24 | }); 25 | 26 | $checkboxes.on('change', function (event) { 27 | var $checkbox = $(event.target); 28 | saveCheckboxValue($checkbox.data('hashcode'), $checkbox.prop('checked')); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /assets/javascripts/doc_page.js: -------------------------------------------------------------------------------- 1 | // HTML5 Shims... 2 | document.createElement('main'); 3 | document.createElement('footer'); 4 | 5 | $(document).ready(function () { 6 | $('[data-toggle-selector]').on('click', function (event) { 7 | event.preventDefault(); 8 | var toToggle = $(event.target).data('toggle-selector'); 9 | var originallyVisible = $(toToggle).hasClass('visible'); 10 | $('.toc').removeClass('visible'); 11 | $(toToggle).toggleClass('visible', !originallyVisible); 12 | return false; 13 | }); 14 | 15 | $('.toggler').on('click', function (e) { 16 | e.preventDefault(); 17 | $(this).closest('.collapsable').toggleClass('closed'); 18 | }); 19 | 20 | $('.expand-all').on('click', function (e) { 21 | e.preventDefault(); 22 | $('.closed').removeClass('closed'); 23 | $('.expand-all').remove(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | //= require 'opensans' 2 | //= require 'aleo' 3 | //= require 'doc_page' 4 | //= require 'flags' 5 | //= require 'big_checkbox' 6 | //= require 'header' 7 | //= require 'toc' 8 | //= require 'step' 9 | //= require 'font_awesome' 10 | //= require 'coderay' 11 | -------------------------------------------------------------------------------- /assets/stylesheets/big_checkbox.scss: -------------------------------------------------------------------------------- 1 | $big_checkbox_size: 20px; 2 | 3 | input.big_checkbox[type=checkbox] { 4 | display:none; 5 | + label { 6 | height: $big_checkbox_size; 7 | width: $big_checkbox_size; 8 | display:inline-block; 9 | padding: 2px; 10 | margin: 0 12px -8px 0; 11 | background-color: white; 12 | z-index: 2; 13 | border: 2px solid #dadada; 14 | 15 | &:hover { 16 | background-image: url(/img/check-dim.png); 17 | background-size: cover; 18 | cursor: pointer; 19 | } 20 | } 21 | 22 | &:checked { 23 | + label { 24 | background-image: url(/img/check.png); 25 | background-size: cover; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /assets/stylesheets/flags.scss: -------------------------------------------------------------------------------- 1 | ul.flags { 2 | min-width: 0; 3 | position: relative; 4 | 5 | > li { 6 | display: block; 7 | 8 | > a { 9 | position: relative; 10 | display: block; 11 | padding: 10px 14px; 12 | line-height: 20px; 13 | } 14 | 15 | > img:hover { 16 | background-color: #eee; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /assets/stylesheets/font_awesome.scss: -------------------------------------------------------------------------------- 1 | $fa-font-path: '/fonts/font-awesome/'; 2 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | require 'rack/codehighlighter' 2 | require 'coderay' 3 | 4 | use Rack::ShowExceptions 5 | use Rack::ShowStatus 6 | use Rack::Static, :urls => ["/css", "/img"], :root => "public" 7 | use Rack::Codehighlighter, :coderay, :element => "pre.code", :pattern => /\A\s*:::(\w+)\s*\n/ 8 | use Rack::Codehighlighter, :coderay, 9 | :element => "pre>code", 10 | :markdown => true, 11 | :pattern => /\A[:@]{3}\s?(\w+)\s*(\n| )/i 12 | 13 | # require 'thin/logging' 14 | # Thin::Logging.debug = true 15 | 16 | require './app' 17 | run Rack::Cascade.new([ 18 | Deck::RackApp.public_file_server, 19 | InstallFest 20 | ]) 21 | -------------------------------------------------------------------------------- /lib/big_checkbox.rb: -------------------------------------------------------------------------------- 1 | require 'erector_scss' 2 | 3 | class BigCheckbox < Erector::Widget 4 | # for testing -- set the next number 5 | def self.number= checkbox_number 6 | @@checkbox_number = checkbox_number 7 | end 8 | 9 | def content 10 | # check.png from http://findicons.com/icon/251632/check?id=396591 11 | # technique thanks to http://nicolasgallagher.com/css-background-image-hacks/ 12 | # and http://stackoverflow.com/questions/3772273/pure-css-checkbox-image-replacement 13 | # and https://gist.github.com/592332 14 | checkbox_number = (@@checkbox_number ||= 0) 15 | input.big_checkbox type: "checkbox", name: "big_checkbox_#{checkbox_number}", value: "valuable", id: "big_checkbox_#{checkbox_number}" 16 | label for: "big_checkbox_#{checkbox_number}" 17 | @@checkbox_number += 1 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/erector_scss.rb: -------------------------------------------------------------------------------- 1 | require 'sass' 2 | 3 | class Erector::Widget 4 | def self.scss content 5 | Sass.compile(content) 6 | end 7 | end 8 | 9 | -------------------------------------------------------------------------------- /lib/flags.rb: -------------------------------------------------------------------------------- 1 | 2 | # Flag icons borrowed from https://www.gosquared.com/resources/flag-icons/ 3 | # Put them in public/flags 4 | class Flags < Erector::Widget 5 | needs :locale 6 | 7 | def initialize *args 8 | super 9 | @locales = ["en", "es", "zh-tw"] 10 | end 11 | 12 | def image_for_locale(locale) 13 | image_name = {"en" => "us"}[locale.to_s] || locale 14 | "/flags/#{image_name.upcase}.png" 15 | end 16 | 17 | def subdomain_for_locale(locale) 18 | {"en" => "docs"}[locale.to_s] || locale 19 | end 20 | 21 | def content 22 | li class: 'dropdown' do 23 | a class: 'dropdown-toggle', 'data-toggle' => 'dropdown', href: '#' do 24 | img src: image_for_locale(@locale) 25 | end 26 | ul class: 'flags dropdown-menu' do 27 | @locales.each do |locale| 28 | li { 29 | a(href:"http://#{subdomain_for_locale(locale)}.railsbridge.org") { 30 | img src: image_for_locale(locale) 31 | } 32 | } 33 | end 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/html5_page.rb: -------------------------------------------------------------------------------- 1 | class Html5ExternalRenderer < ExternalRenderer 2 | # render 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /sites/javascript-snake-game/zip_content/snake.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/javascript-snake-game/zip_content/snake.js -------------------------------------------------------------------------------- /sites/javascript-to-do-list-with-react/AdvancedTodoList.zip-manifest: -------------------------------------------------------------------------------- 1 | zip_content/app.js 2 | zip_content/debut_light.png 3 | zip_content/index.html 4 | zip_content/store.js 5 | zip_content/styles.css 6 | zip_content/console-polyfill.js 7 | -------------------------------------------------------------------------------- /sites/javascript-to-do-list-with-react/deploying_your_site.step: -------------------------------------------------------------------------------- 1 | insert '../javascript-to-do-list/_deploying_your_site' 2 | 3 | next_step "next_steps" -------------------------------------------------------------------------------- /sites/javascript-to-do-list-with-react/developer_tools.step: -------------------------------------------------------------------------------- 1 | insert '../frontend/_developer_tools' 2 | 3 | next_step 'creating_a_list' -------------------------------------------------------------------------------- /sites/javascript-to-do-list-with-react/next_steps.step: -------------------------------------------------------------------------------- 1 | message < 6 |

Step Title

7 |
8 |

Goal:

9 |

Description of the current step. 10 |

Red because big goals are scary. 11 |

12 |
13 |

Steps:

14 |
steps to take.
15 |

Yellow because we've gotten it done, but we have no clue what's going on. 16 |

17 |
18 |

Explanation

19 |

Details of what the steps actually did... spell out the cause and effect. 20 |

Green because we can tie everything together now. 21 |

22 | 23 | -------------------------------------------------------------------------------- /sites/javascript-to-do-list/_teachers_note.md: -------------------------------------------------------------------------------- 1 | ### A note for teachers 2 | 3 | The backend for this curriculum is hosted at http://listalous.herokuapp.com/ 4 | 5 | If it isn't working, you might be able to deploy it somewhere else using the code from https://github.com/raorao/headless_todos 6 | -------------------------------------------------------------------------------- /sites/javascript-to-do-list/deploying_your_site.step: -------------------------------------------------------------------------------- 1 | insert '_deploying_your_site' 2 | 3 | next_step "next_steps" -------------------------------------------------------------------------------- /sites/javascript-to-do-list/developer_tools.step: -------------------------------------------------------------------------------- 1 | insert '../frontend/_developer_tools' 2 | 3 | next_step 'programming_with_javascript' -------------------------------------------------------------------------------- /sites/javascript-to-do-list/img/browser_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/javascript-to-do-list/img/browser_console.png -------------------------------------------------------------------------------- /sites/javascript-to-do-list/img/finished_app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/javascript-to-do-list/img/finished_app.png -------------------------------------------------------------------------------- /sites/javascript-to-do-list/img/network_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/javascript-to-do-list/img/network_tab.png -------------------------------------------------------------------------------- /sites/javascript-to-do-list/img/text_editor_html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/javascript-to-do-list/img/text_editor_html.png -------------------------------------------------------------------------------- /sites/javascript-to-do-list/next_steps.step: -------------------------------------------------------------------------------- 1 | message < 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |

Your List App

10 |
11 |
12 | 13 |
14 |
    15 |
  • 16 | 17 |
    A gallon of milk
    18 | 19 |
  • 20 |
  • 21 | 22 |
    A stick of butter
    23 | 24 |
  • 25 |
26 |
27 |
28 | 29 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /sites/job-board/add_more_things.step: -------------------------------------------------------------------------------- 1 | message <<-MARKDOWN 2 | 3 | ## Time to add more things! 4 | 5 | The time where we tell you what to type in has finally ended. You should do one or all of the things below! 6 | 7 | Working independently or in pairs is super fun at this point. 8 | 9 | * Add a show page for each listing and move the Edit and Delete links to there. 10 | * Add validations — postings without titles or descriptions shouldn't be allowed, right? 11 | * Add other useful fields to jobs 12 | * Display jobs index in a table; make sortable with data_tables 13 | * Add tags (time for a has_many, folks!!!) 14 | * Make it look better 15 | * Add a user model and auth with Devise 16 | * Test it! Write a controller spec. 17 | 18 | ## Credits 19 | 20 | This curriculum was originally written by [Lillie Chilen](http://www.twitter.com/lilliealbert) 21 | and has been improved by all sorts of [lovely RailsBridge volunteers](https://github.com/railsbridge/docs/commits/master/sites/en/job-board). 22 | MARKDOWN 23 | -------------------------------------------------------------------------------- /sites/job-board/delete_job_listings.step: -------------------------------------------------------------------------------- 1 | message <<-MARKDOWN 2 | # What we're going to do 3 | 4 | * Remove postings 5 | 6 | Once a job is filled, we don't want a listing for it hanging out forever. Let's add a way to delete postings. 7 | 8 | # Postings be gone! 9 | 10 | If we look at our [handy Routes page](http://localhost:3000/rails/info/routes), we see this: 11 | MARKDOWN 12 | 13 | source_code :html, "job_path DELETE /jobs/:id(.:format) jobs#destroy" 14 | 15 | message "So we need to send the DELETE http verb to the server, so we can get to the destroy method on the jobs controller (that we will make soon). It turns out rails link_to helpers accept specific verbs as an argument, so we can add this line below the edit posting link that we just added:" 16 | 17 | source_code :erb, "
<%= link_to 'Delete Posting', job, method: :delete %>
" 18 | 19 | message "Go to the index, and try to delete something." 20 | 21 | error_box "The action 'destroy' could not be found for JobsController" 22 | 23 | message "This is like my favorite error now! First, let's add the method:" 24 | 25 | source_code :ruby, 26 | <<-RUBY 27 | def destroy 28 | end 29 | RUBY 30 | 31 | message <<-MARKDOWN 32 | This fixes the error. But just like updating, we still need to add the logic that actually deletes the job. 33 | 34 | See if you can figure out the right syntax for finding the job, deleting it, and then redirecting to a useful page. 35 | 36 | **Don't scroll down!!!** 37 | MARKDOWN 38 | 39 | message <<-MARKDOWN 40 | * here 41 | * is 42 | * even 43 | * more 44 | * strategic 45 | * white 46 | * space 47 | * so 48 | * the 49 | * answer 50 | * isn't 51 | * immediately 52 | * visible! 53 | 54 | Okay, here's the answer: 55 | MARKDOWN 56 | 57 | source_code :ruby, 58 | <<-RUBY 59 | @job = Job.find(params[:id]) 60 | @job.destroy 61 | redirect_to jobs_path 62 | RUBY 63 | 64 | message "Try it again, and... kablammo! We're destroying job listings left and right!" 65 | 66 | next_step "add_more_things" 67 | -------------------------------------------------------------------------------- /sites/job-board/img/crud_grid.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/job-board/img/crud_grid.jpg -------------------------------------------------------------------------------- /sites/job-board/img/crud_rails_methods.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/job-board/img/crud_rails_methods.jpg -------------------------------------------------------------------------------- /sites/job-board/img/rails-routes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/job-board/img/rails-routes.png -------------------------------------------------------------------------------- /sites/job-board/img/request-cycle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/job-board/img/request-cycle.jpg -------------------------------------------------------------------------------- /sites/job-board/job-board.step: -------------------------------------------------------------------------------- 1 | message <<-MARKDOWN 2 | We're going to build a job board in Rails using the tried-and-true method of following the errors that we make! 3 | 4 | Rails generators will help us avoid some tedious file creation, but provide a lot less magic than scaffolding (which is what is used in the Suggestotron to create *everything* for a Topic all at once). 5 | 6 | This means we'll a get a little less done today than we did when we built Suggestotron. But we're going to build an app in little pieces, so you can focus on understanding how the pieces fit together. 7 | MARKDOWN 8 | 9 | tip "This is not a self-paced curriculum. You should use the discussion sections on each page to make sure everyone is together!" 10 | 11 | message <<-MARKDOWN 12 | # Notable Things 13 | 14 | As you might have noticed, we're assuming you've already been to a RailsBridge workshop before or have otherwise already explored a Rails app, and are ready for deeper knowledge. 15 | 16 | We're also going to skip deploying to Heroku this time around, but you can definitely use the instructions from the Suggestotron curriculum to deploy your app to the internet! 17 | MARKDOWN 18 | 19 | important "This curriculum is written for Rails 5. Things will get awkward / broken if you're using an earlier version of Rails, so if you skipped the Installfest, you need to upgrade to Rails 5 now." 20 | 21 | message <<-MARKDOWN 22 | # Tips for everyone: 23 | 24 | * When adding code, it's awesome for students to walk through the code line by line and say out loud what is happening. (i.e., "The string is being stored in the instance variable" or "The method `snorgle` is being defined"). If you do it every time, you'll get really comfortable with the vocabulary of Rails! 25 | * Error messages are your friend! Read them carefully, and practice understanding what Rails is telling you. Seeing an error and just diving back into your code is a natural reaction, but stop! Then read, think, and talk about what the error means before fixing it. 26 | MARKDOWN 27 | 28 | insert '../intro-to-rails/working_effectively_and_efficiently' 29 | 30 | next_step "create_a_rails_app" 31 | -------------------------------------------------------------------------------- /sites/job-board/listing_the_jobs.step: -------------------------------------------------------------------------------- 1 | message <<-MARKDOWN 2 | # What we're going to do 3 | 4 | * Show the jobs! 5 | * Learn about ERB 6 | 7 | Going back to the jobs index (), we expect to see the new jobs. Let's actually build the job board part of this job board now! 8 | 9 | # Get all the jobs out of the database 10 | 11 | If we're going to show our jobs in view, first we have to get them out of the database and store them in an instance variable. Update the index method to look like this: 12 | MARKDOWN 13 | 14 | source_code :ruby, 15 | <<-RUBY 16 | def index 17 | @jobs = Job.all 18 | end 19 | RUBY 20 | 21 | message <<-MARKDOWN 22 | Before we show the jobs, let's actually look at what that is doing. Go back to your Rails console and run `Job.all`. 23 | MARKDOWN 24 | 25 | discussion_box "Rails Console", <<-MARKDOWN 26 | The Rails console is super fun! It's giving us direct access to our local database. 27 | 28 | * Try running `Job.all.to_sql`. What does that do? 29 | * Try selecting an individual Job record. 30 | * Try updating that individual record from the console! 31 | MARKDOWN 32 | 33 | message "# Show those jobs!" 34 | 35 | source_code_with_message "Add this to app/views/jobs/index.html.erb:", :erb, 36 | <<-RUBY 37 | <% @jobs.each do |job| %> 38 |

<%= job.title %>

39 |

<%= job.description %>

40 | <% end %> 41 | RUBY 42 | 43 | discussion_box "ERB", <<-MARKDOWN 44 | What is this doing? Go through this line by line, having one person explain each line. 45 | 46 | Compare the ERB to the HTML that shows up on the page. ("Inspect Element" is your friend!) 47 | 48 | What's the difference between a line with `<% %>` brackets and `<%= %>` brackets? 49 | MARKDOWN 50 | 51 | next_step "add_a_navbar" 52 | -------------------------------------------------------------------------------- /sites/job-board/the_request_cycle.step: -------------------------------------------------------------------------------- 1 | message "" 2 | 3 | discussion_box "What is this diagram?", <<-MARKDOWN 4 | Talk through this diagram of the request cycle! 5 | 6 | If there's room, act out a request being made as a tiny play, in which a small object is the request and the students are the various pieces of code that the request travels through. 7 | MARKDOWN 8 | 9 | next_step "make_a_jobs_home_page" 10 | -------------------------------------------------------------------------------- /sites/learn-to-code/argv.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # ARGV 4 | 5 | There is a magic array named `ARGV`. 6 | 7 | It contains the *command line arguments* to the program. 8 | 9 | If the user types: 10 | 11 | ruby hello.rb Alice Bob 12 | 13 | then ARGV contains: 14 | 15 | ["Alice", "Bob"] 16 | 17 | # Why ARGV? 18 | 19 | ARGV is a historical name. It means "Argument Vector" and has been around since the early 1970s. 20 | 21 | # Command-Line Hello 22 | 23 | Change `hello.rb` to contain: 24 | 25 | puts "Hello, " + ARGV[0] 26 | 27 | and run it a few times, e.g. 28 | 29 | ruby hello.rb Alice 30 | 31 | # LAB: Hello, Everyone! 32 | 33 | Change `hello.rb` to say hello to *every one* of its command line arguments. 34 | 35 | For instance: 36 | 37 | ruby hello.rb Alice Bob Charlie 38 | Hello, Alice! 39 | Hello, Bob! 40 | Hello, Charlie! 41 | 42 | # LAB: Add 43 | 44 | Write a program named `add.rb` that adds all of its command line arguments together. 45 | 46 | e.g. 47 | 48 | ruby add.rb 1 2 3 49 | 6 50 | 51 | Do you remember how to convert a string to an integer? 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /sites/learn-to-code/extra.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Extra Fun Ruby Stuff 4 | 5 | We've gone over the basics, but Ruby has lots of other language features. Here's a quick overview, with links to more info about them. 6 | 7 | [Iterators](http://codelikethis.com/lessons/ruby_blocks/iterators) are special loops that act on all the items in a collection. 8 | 9 | [Blocks](http://codelikethis.com/lessons/ruby_blocks) are like a cross between functions and methods. They allow Ruby to express many powerful algorithms in a compact writing style. 10 | 11 | [Symbols](http://codelikethis.com/lessons/ruby_basics/symbols) are like strings that start with a colon, and they're used all over the place. 12 | 13 | [Chaining](http://codelikethis.com/lessons/ruby_basics/chaining) is a compact way to express a chain of events. Properly executed, chaining turns Ruby from prose into poetry. 14 | 15 | [Methods](http://codelikethis.com/lessons/ruby_objects/objects#behavior) and [Classes](http://codelikethis.com/lessons/ruby_objects/classes) are the heart of [Object-Oriented Programming](https://en.wikipedia.org/wiki/Object-oriented_programming). They 16 | 17 | ## ...and [lots more](http://codelikethis.com/lessons)... 18 | -------------------------------------------------------------------------------- /sites/learn-to-code/functions.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Functions 4 | 5 | * just like a VARIABLE is a name for a chunk of data 6 | * a FUNCTION is a name for a chunk of code 7 | * if you have some code you want to run again and again 8 | * or just run once, but keep it organized 9 | 10 | # For example 11 | 12 | Here's a silly function: 13 | 14 | def add x, y 15 | x + y 16 | end 17 | 18 | * `def` means "define a function" 19 | * `add` is the *name* of the function 20 | * `x, y` are the *parameters* of the function 21 | * `x + y` is the *body* of the function 22 | * also the *return value* 23 | 24 | Lab: write a `multiply` method and use it to multiply 123 * 456 25 | 26 | # Rant!!! 27 | 28 | def rant s 29 | s.upcase.gsub(" ", "") + "!!!" 30 | end 31 | 32 | puts rant "i like pizza" 33 | 34 | Lab: use "rant" to rant about something really important!!! 35 | 36 | # Capitalize Just The First Character 37 | 38 | def initial_cap s 39 | s[0].upcase + s[1,s.length] 40 | end 41 | 42 | puts initial_cap("smith") 43 | puts initial_cap("deniro") 44 | 45 | Lab: capitalize a few things 46 | 47 | # Titleize 48 | 49 | def titleize string 50 | string.split(' ').map(&:capitalize).join(' ') 51 | end 52 | 53 | * The funny `&:` means "send this message" 54 | * `map(&:capitalize)` means "send the message `capitalize` to every item in the array" 55 | 56 | # LAB: titleize your favorite movies 57 | 58 | 59 | -------------------------------------------------------------------------------- /sites/learn-to-code/hashes.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hashes 4 | 5 | * `Hash` is a built-in type 6 | * aka Map, Dictionary, Associative Array 7 | * Like an array where the index can be *anything*, not just a number 8 | 9 | # TODO: 10 | 11 | * examples 12 | * labs 13 | 14 | 15 | -------------------------------------------------------------------------------- /sites/learn-to-code/img/cookie-recipe.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/learn-to-code/img/cookie-recipe.gif -------------------------------------------------------------------------------- /sites/learn-to-code/img/dot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/learn-to-code/img/dot.jpg -------------------------------------------------------------------------------- /sites/learn-to-code/img/one-infinite-loop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/learn-to-code/img/one-infinite-loop.jpg -------------------------------------------------------------------------------- /sites/learn-to-code/img/spoon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/learn-to-code/img/spoon.jpg -------------------------------------------------------------------------------- /sites/learn-to-code/img/truthiness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/learn-to-code/img/truthiness.png -------------------------------------------------------------------------------- /sites/learn-to-code/img/warehouse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/learn-to-code/img/warehouse.jpg -------------------------------------------------------------------------------- /sites/learn-to-code/img/wargames-terminal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/learn-to-code/img/wargames-terminal.jpg -------------------------------------------------------------------------------- /sites/learn-to-code/methods.md: -------------------------------------------------------------------------------- 1 | # Methods vs. Functions 2 | 3 | * a FUNCTION is a named chunk of code with PARAMETERS and a RETURN VALUE 4 | * a METHOD is a function that is *attached* to a specific object 5 | * it has privileged access to that object's data 6 | * in Ruby everything's an object, so the terms are mostly interchangeable 7 | 8 | -------------------------------------------------------------------------------- /sites/learn-to-code/next_steps.md: -------------------------------------------------------------------------------- 1 | # Next Steps 2 | 3 | * [Try Ruby](http://tryruby.org/) at 4 | * Sign up for Code School at 5 | * Code School's "Ruby Bits" class 6 | * Alex's online courses at [Code Like This](http://codelikethis.com) and [TestFirst.org](http://testfirst.org) 7 | * Chris Pine's book "[Learn to Program](http://www.amazon.com/gp/product/1934356360/ref=as_li_ss_il?ie=UTF8&camp=1789&creative=390957&creativeASIN=1934356360&linkCode=as2&tag=alexchaffeeco-20)" book 8 | * Attend or host a [RailsBridge Workshop](http://railsbridge.org) 9 | 10 | * _why's guide to Ruby (http://poignant.guide/) 11 | 12 | * 13 | * 14 | 15 | # Thanks 16 | 17 | * to all the TAs! 18 | * to all the students! 19 | * to [Alex Chaffee](http://alexchaffee.com/), the original author of this curriculum, and 20 | * to all the [RailsBridge volunteers](https://github.com/railsbridge/docs/commits/master/sites/en/learn-to-code) who have helped make it better! 21 | 22 | -------------------------------------------------------------------------------- /sites/learn-to-code/nil.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Nil 4 | 5 | *nil* is a magic object 6 | 7 | # There Is No Spoon 8 | 9 | ![](img/spoon.jpg) 10 | 11 | *nil* is the object that means "there is no object" 12 | 13 | # Experiment 14 | 15 | fruit = "apple" 16 | fruit = nil 17 | fruit.reverse 18 | 19 | *Read the error!* 20 | 21 | # Errors are good 22 | 23 | They tell you 24 | 25 | * you made a mistake 26 | * what that mistake was 27 | * (sometimes) how to fix it 28 | 29 | Interpret this error: 30 | 31 | fruit.reverse 32 | NoMethodError: undefined method `reverse' for nil:NilClass 33 | 34 | # Fail Fast, Fail Often 35 | 36 | * Ruby has a "fail fast" philosophy 37 | * Is this a good idea? 38 | * Why or why not? 39 | 40 | 41 | -------------------------------------------------------------------------------- /sites/learn-to-code/objects.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Objects 4 | 5 | An OBJECT is a location in computer memory where you can store DATA (aka VALUES). 6 | 7 | There are many kinds of objects, including String, Number, Array, Hash, Time, ... 8 | 9 | (The different kinds of objects are called CLASSES or TYPES. Some day soon you will create your own classes but for now, we will use the built-in ones.) 10 | 11 | # Numbers 12 | 13 | A NUMBER is what it sounds like. 14 | 15 | 10 16 | -12 17 | 3.14 18 | 19 | # Strings 20 | 21 | A STRING is an object that's a collection of characters, like a word or a sentence. 22 | 23 | "apple" 24 | "banana" 25 | "Cherry Pie" 26 | 27 | # Messages and Operators 28 | 29 | An object responds to MESSAGES. You send it messages using OPERATORS. 30 | 31 | The most powerful operator is DOT. 32 | 33 | On screen she looks like this... 34 | 35 | . 36 | 37 | # Dot up close 38 | 39 | ...but here's what she looks like up close: 40 | 41 | ![picture of Dot the Operator](img/dot.jpg) 42 | 43 | # Dot's job 44 | 45 | Dot can send any message she likes, by name, to any object. 46 | 47 | "apple".upcase 48 | 49 | The `upcase` message turns `"apple"` into `"APPLE"`. 50 | 51 | # Other Operators 52 | 53 | There are other operators, like PLUS (`+`) and TIMES (`*`), but they only send one message each. 54 | 55 | And remember, Dot is more powerful than any other operator! 56 | 57 | 2 + 7 58 | 59 | is the same as 60 | 61 | 2.+ 7 62 | 63 | Both send the message `+` to the object `2`. 64 | 65 | # Return Values 66 | 67 | Every time an object receives a message, it returns a response. 68 | 69 | The response is also called the VALUE or the RETURN VALUE. 70 | 71 | You can think of it as the answer to a question. 72 | 73 | 2 + 2 # Question: What is 2 + 2? 74 | 4 # Answer: 4 75 | 76 | "apple".upcase 77 | # Q: What is the upcase of the string "apple"? 78 | 79 | "APPLE" 80 | # A: the string "APPLE" 81 | 82 | -------------------------------------------------------------------------------- /sites/learn-to-code/sinatra.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Sinatra 4 | 5 | Sinatra is a Web Application Framework. It includes a Web Server and lets you write code to show when people request web pages. 6 | 7 | # Hi, Sinatra 8 | 9 | 1. install Sinatra by running `gem install sinatra` on the command line 10 | 11 | 2. create a file called `hi.rb` containing this: 12 | 13 | require 'sinatra' 14 | 15 | get '/hi' do 16 | "Hi!" 17 | end 18 | 19 | 3. run `ruby hi.rb` 20 | 21 | Now open a Web Browser (like Firefox or Chrome or Safari or Internet Explorer) and enter the following URL into the address bar: 22 | 23 | http://localhost:4567/hi 24 | 25 | # Congratulations 26 | 27 | You just wrote a web server. 28 | 29 | No, really. 30 | 31 | # Hello, Whoever 32 | 33 | Change `hi.rb` to look like this: 34 | 35 | require 'sinatra' 36 | 37 | get '/hi/:who' do 38 | "Hi " + params[:who] + "!" 39 | end 40 | 41 | Now visit the following URL: 42 | 43 | http://localhost:4567/hi/alice 44 | 45 | # LAB: Yeller 46 | 47 | Make a route in your Sinatra application so that when someone requests this: 48 | 49 | /yell/ahoy 50 | 51 | they see this: 52 | 53 | AHOY!!! 54 | 55 | and when someone requests this: 56 | 57 | /yell/dinnertime 58 | 59 | they see this: 60 | 61 | DINNERTIME!!! 62 | 63 | # Detour: Deploying to Heroku 64 | 65 | * Railsbridge pages describing account setup & deploy steps 66 | 67 | 68 | -------------------------------------------------------------------------------- /sites/learn-to-code/strings.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String Messages 4 | 5 | A string understands lots of messages. Here are a few: 6 | 7 | "banana".upcase 8 | "Cherry".downcase 9 | "titanic".capitalize 10 | "elderberry".reverse 11 | "fig".length 12 | "Fig Newton".swapcase 13 | "".empty? 14 | "syzygy".length 15 | 16 | Try all of these out in irb! 17 | 18 | # String Operators 19 | 20 | A string knows DOT, but also understands several other operators: 21 | 22 | "blue" + "berry" 23 | "yum" * 10 24 | "elderberry"[8] 25 | 26 | `+` `*` and `[]` are pronounced PLUS, TIMES, and SUB 27 | 28 | Try these out in irb! 29 | 30 | # Combining Messages and Operators 31 | 32 | You can combine messages and operators at will. 33 | 34 | "fig".upcase.reverse 35 | "grape".reverse * 10 + "!!!" 36 | 37 | Definitely try these out in irb! It's pretty fun. 38 | 39 | # LAB: Playing With Strings 40 | 41 | * What is the reverse of "stressed"? 42 | * How many characters long is your name? 43 | * What does your name look like, repeated 1000 times? 44 | * What is the tenth character of "Matz is nice"? (Trick question!) 45 | 46 | -------------------------------------------------------------------------------- /sites/learn-to-code/todo-learntocode.md: -------------------------------------------------------------------------------- 1 | # todo: 2 | 3 | * diagram: memory (variables+objects) 4 | * diagram: message passing 5 | 6 | * interpolation? 7 | * more on arrays 8 | * hashes 9 | * more labs (for students who "get it" before the rest of the room and don't want to sit around bored (or help others)) 10 | * functions 11 | * more array labs 12 | * methods 13 | * classes 14 | * File I/O 15 | * testing 16 | * symbols 17 | * rand 18 | 19 | -------------------------------------------------------------------------------- /sites/message-board/add_other_features_of_your_choosing.step: -------------------------------------------------------------------------------- 1 | message <<-MARKDOWN 2 | What other features do you want? 3 | 4 | Suggestions: 5 | 6 | * Profile pages for users (enter user’s name or details, have it display alongside posts). 7 | * Post/Comment history for individual users (on their profile page?). 8 | * Easy user profile pictures with [Gravatar](https://gravatar.com/). 9 | * Add login options with [Omniauth](https://github.com/intridea/omniauth), including Twitter, Facebook, GitHub, Google, and more. 10 | * Check out the Devise [documentation for integrating with Omniauth](https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview). 11 | * Fiddle with the layout of the show page so it doesn't look bad. If it looks bad. It probably looks great. 12 | * Perhaps fancier post markup with Markdown or something similar. 13 | * Deploy to Heroku and send your message board to all your friends! 14 | 15 | ## ...and that's that! Good luck! Make more things! Come back again! 16 | 17 | # Credits 18 | 19 | This curriculum was originally written by 20 | [Lillie Chilen](http://www.twitter.com/lilliealbert) and 21 | [Travis Grathwell](https://github.com/tjgrathwell), 22 | and has been improved by all sorts of [lovely RailsBridge volunteers](https://github.com/railsbridge/docs/commits/master/sites/en/message-board). 23 | MARKDOWN 24 | -------------------------------------------------------------------------------- /sites/message-board/add_replying.step: -------------------------------------------------------------------------------- 1 | requirements do 2 | message <<-MARKDOWN 3 | * The user should see a 'New Reply' link or button on a post's show page which takes them to a form. The form should include the title of the post being replied to. 4 | * The user should be able to create a new reply to a post using the 'New Reply' form. 5 | * The user should see all the replies to a post on the post’s show page. 6 | * If the user doesn't submit all required fields, they should see some error messaging, but they shouldn't lose any of their work. 7 | MARKDOWN 8 | table do 9 | tr do 10 | td do 11 | h2 'Create View', class: 'centered' 12 | end 13 | td do 14 | h2 'Show View', class: 'centered' 15 | end 16 | end 17 | tr do 18 | td do 19 | img class: 'noborder', src: 'img/create_reply.png' 20 | end 21 | td do 22 | img class: 'noborder', src: 'img/show_replies.png' 23 | end 24 | end 25 | end 26 | end 27 | 28 | discussion do 29 | message <<-MARKDOWN 30 | * What is a nested resource? When is it appropriate and how does it help? 31 | * How do the `RepliesController` and `PostsController` interact? 32 | * What should happen to the routes file for this nesting business to work? 33 | MARKDOWN 34 | end 35 | 36 | tools_and_references do 37 | message <<-MARKDOWN 38 | * RailsGuides - Rails Routing from the Outside In http://guides.rubyonrails.org/routing.html 39 | MARKDOWN 40 | end 41 | 42 | next_step "inline_replying_on_a_post" 43 | -------------------------------------------------------------------------------- /sites/message-board/commands.md: -------------------------------------------------------------------------------- 1 | ## Ruby 2 | 3 | Open an interactive Ruby terminal (type 'exit' to quit) 4 | 5 | irb 6 | 7 | Run a ruby program named FILENAME.rb 8 | 9 | ruby FILENAME.rb 10 | 11 | Installs a gem called GEMNAME 12 | 13 | gem install GEMNAME 14 | 15 | Installs gems listed in the `Gemfile` 16 | 17 | bundle install 18 | 19 | ## Rails 20 | 21 | Create a new rails project called `NAME` 22 | 23 | rails new NAME 24 | 25 | Auto-generate routes (this can also be done manually) 26 | 27 | rails generate scaffold 28 | 29 | Create a new [Rails model] 30 | 31 | rails generate model MODELNAME 32 | 33 | Update the database to match what you have described in your code 34 | 35 | rails db:migrate 36 | 37 | Run the application locally (Ctrl-C to quit) 38 | 39 | rails server 40 | 41 | Start an interactive Ruby session that knows about your Rails models (type 'exit' to quit) 42 | 43 | rails console 44 | 45 | Print the routes for your application 46 | 47 | rails routes 48 | 49 | ## Browser 50 | 51 | Go to the root page of your rails application 52 | 53 | http://localhost:3000 54 | 55 | ## Git 56 | 57 | Creates a new git repository in your current directory. 58 | 59 | git init 60 | 61 | Add the current directory, and all sub directories, to your git repository. 62 | 63 | git add . 64 | 65 | Tells you what you've added, deleted, and changed between your current directory and you local git repository. 66 | 67 | git status 68 | 69 | Prints the difference between FILENAME and what is in your local git repository. 70 | 71 | git diff FILENAME 72 | 73 | Commit the files you've added to the local repository. 74 | 75 | git commit -m "Describe what has changed, and why" . 76 | 77 | Push *committed* changes to the remote server. 78 | 79 | git push 80 | -------------------------------------------------------------------------------- /sites/message-board/create_a_new_rails_app_with_a_static_home_page.step: -------------------------------------------------------------------------------- 1 | requirements do 2 | message <<-MARKDOWN 3 | * You should have a new rails app with with a static home page that's under your control. Make sure the controller for this page is called **HomeController**. 4 | * You, the developer, should explain to a teacher, TA, or fellow student how Rails knows to render the home view. 5 | MARKDOWN 6 | img class: 'noborder', src: 'img/static_home_page.png' 7 | end 8 | 9 | discussion do 10 | message <<-MARKDOWN 11 | * In order to have a static home page, you will need a route, a controller, a view. Discuss! 12 | * Seriously. If you don't discuss this stuff, things will be SO much harder. 13 | * Generators! Rails has lots of them. Try exploring the output of `rails generate`. 14 | * We’re not using `rails generate scaffold` in this curriculum. Because you will generate all your Models, Views and Controllers yourself, this will force you, to do more understanding-building brain work. The teacher/TAs can perhaps comment on what they would do in the real world and their thoughts on the excellence of this choice for learning-purposes. 15 | * What do you need to add to your home controller (after you've made it) to have a static home page? 16 | * How does the home/index.html.erb view file relate to the layouts/application.html.erb view file? 17 | * What’s the significance of yield in the application view? 18 | * What does the home controller do? 19 | MARKDOWN 20 | end 21 | 22 | tools_and_references do 23 | message <<-MARKDOWN 24 | * RailsGuides - Setting the Application Home Page: . 25 | * RailsGuides - controllers overview: . 26 | MARKDOWN 27 | end 28 | 29 | hints do 30 | message <<-MARKDOWN 31 | * If you have no idea what to put in your home controller, maybe try looking back at a past-Railsbridge app? Or another rails app you have lying about? 32 | MARKDOWN 33 | end 34 | 35 | next_step "install_devise" 36 | -------------------------------------------------------------------------------- /sites/message-board/img/create_post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/message-board/img/create_post.png -------------------------------------------------------------------------------- /sites/message-board/img/create_reply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/message-board/img/create_reply.png -------------------------------------------------------------------------------- /sites/message-board/img/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/message-board/img/header.png -------------------------------------------------------------------------------- /sites/message-board/img/inline_reply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/message-board/img/inline_reply.png -------------------------------------------------------------------------------- /sites/message-board/img/post_index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/message-board/img/post_index.png -------------------------------------------------------------------------------- /sites/message-board/img/request-cycle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/message-board/img/request-cycle.jpg -------------------------------------------------------------------------------- /sites/message-board/img/show_post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/message-board/img/show_post.png -------------------------------------------------------------------------------- /sites/message-board/img/show_replies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/message-board/img/show_replies.png -------------------------------------------------------------------------------- /sites/message-board/img/static_home_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/message-board/img/static_home_page.png -------------------------------------------------------------------------------- /sites/message-board/inline_replying_on_a_post.step: -------------------------------------------------------------------------------- 1 | requirements do 2 | message <<-MARKDOWN 3 | * The user should see the 'New Reply' form at the bottom of a Post's show page. 4 | * The user should be able to make replies using the inlined 'New Reply' form. 5 | * Error handling (trying to reply without any content) should still work the same way as when replying was a separate page. 6 | MARKDOWN 7 | img class: 'noborder', src: 'img/inline_reply.png' 8 | end 9 | 10 | discussion do 11 | message <<-MARKDOWN 12 | * What needs to happen in the posts controller to allow inline replying? What needs to happen in the view? 13 | MARKDOWN 14 | end 15 | 16 | tools_and_references do 17 | message <<-MARKDOWN 18 | * RailsGuides - Form Helpers, section 2.2: 19 | MARKDOWN 20 | end 21 | 22 | next_step 'add_other_features_of_your_choosing' -------------------------------------------------------------------------------- /sites/message-board/make_a_posts_index_page.step: -------------------------------------------------------------------------------- 1 | requirements do 2 | message <<-MARKDOWN 3 | * The user should be able to see each post’s name, author, and date published on the overview page (aka the index page). 4 | * The name of the post should link to the post show page. 5 | * The index page should include a “New Post” link or button. 6 | MARKDOWN 7 | img class: 'noborder', src: 'img/post_index.png' 8 | end 9 | 10 | discussion do 11 | message <<-MARKDOWN 12 | * Maybe now would be a good time to discuss Active Record! Can anyone explain it? 13 | MARKDOWN 14 | end 15 | 16 | tools_and_references do 17 | message <<-MARKDOWN 18 | * RailsGuides - Listing All Posts: http://guides.rubyonrails.org/v4.0/getting_started.html#listing-all-posts 19 | * Feel free to disregard the JSON stuff on this page, if you're so inclined. 20 | * Bootstrap - Style that table! http://getbootstrap.com/css/#tables 21 | MARKDOWN 22 | end 23 | 24 | next_step "add_replying" -------------------------------------------------------------------------------- /sites/message-board/mvc_overview.md: -------------------------------------------------------------------------------- 1 | ## Explaining MVC and Records 2 | 3 | ![MVC Overview](/intro-to-rails/img/mvc.png) 4 | 5 | Rails implements a very specific notion of the **Model/View/Controller** pattern, which guides how you structure your web applications. 6 | 7 |

Model

8 | 9 | * saves data to the database 10 | * accesses data from the database 11 | * bridge between the database and objects 12 | 13 |

View

14 | 15 | * display the data for human (or machine) consumption 16 | * webpages are views 17 | 18 |

Controller

19 | 20 | * acts as the glue between the models and the views 21 | * combines data from multiple models 22 | * summarizes and filters data 23 | 24 | In MVC, models, views, and controllers have very specific jobs. Separating responsibilities like this make it easy to maintain and extend rails applications. When responsibilities become muddied it gets much harder to debug issues and add new functionality. -------------------------------------------------------------------------------- /sites/message-board/the_request_cycle.md: -------------------------------------------------------------------------------- 1 | ### How does typing in a URL result in a web page being rendered? Here's a rough overview. 2 | 3 | 4 | 5 | 1. The user types in a URL, hoping for a cool website. 6 | 1. After the DNS gets resolved (a topic for another day), the request hits a web server, which asks Rails what it's got. 7 | 1. Rails goes to the routes file first, which takes the URL and calls a corresponding controller action. 8 | 1. The controller goes and gets whatever stuff it needs from the database using the relevant model. 9 | 1. With the data the controller got from the model, it uses the view to make some HTML. 10 | 1. Rails packages up the response and gives it to the web server. 11 | 1. The web server delivers the response to the browser to display a cool website to the user. 12 | 13 | -------------------------------------------------------------------------------- /sites/ruby/classes.step: -------------------------------------------------------------------------------- 1 | goals do 2 | goal "Define a new object" 3 | goal "Create an instance of your object" 4 | goal "Call methods on your object" 5 | end 6 | 7 | step do 8 | message 'Create a new file called circle.rb' 9 | type_in_file 'circle.rb', <<-'CONTENTS' 10 | class Circle 11 | def initialize(radius) 12 | @radius = radius 13 | end 14 | 15 | def area 16 | Math::PI * (@radius ** 2) 17 | end 18 | 19 | def perimeter 20 | 2 * Math::PI * @radius 21 | end 22 | end 23 | 24 | print "What is the radius of your circle? > " 25 | radius = gets.to_i 26 | 27 | a_circle = Circle.new(radius) 28 | puts "Your circle has an area of #{a_circle.area}" 29 | puts "Your circle has a perimeter of #{a_circle.perimeter}" 30 | CONTENTS 31 | console 'ruby circle.rb' 32 | message 'When prompted, type in a radius for your circle.' 33 | end 34 | 35 | explanation do 36 | message "Functions by themselves aren't always enough to keep your program organized. **Object-oriented programming** was developed to keep related data (attributes) and functions that work on that data (methods) together." 37 | message "In Ruby, a new object is defined with the **class** keyword, followed by the name of your object (typically CamelCased). You finish the object definition later on with an **end**." 38 | message "Most objects define a special method, **initialize**, that saves the initial data your object is created with (here, a radius) and performs any other required set-up." 39 | message "You create an **instance** of your object with the **new** method. Arguments passed in to **new** are sent to your **initialize** method." 40 | message "Data is stored on your object using **instance variables** that start with an `@` sign. Instance variables behave like normal variables, but are only visible from inside a specific instance of your object. If you want the data to be externally accessible, you have to write more methods." 41 | end 42 | 43 | next_step 'how_to_write_a_program' -------------------------------------------------------------------------------- /sites/ruby/overview:_building_blocks.step: -------------------------------------------------------------------------------- 1 | 2 | goals do 3 | goal "Learn about different kinds of data: what they\'re called, what you can do with them" 4 | goal "Store data in a variable so you can use it later" 5 | goal "Make decisions with conditionals" 6 | goal "Hold collections of data in arrays and hashes" 7 | goal "Loop over a collection" 8 | end 9 | 10 | 11 | next_step 'variables' -------------------------------------------------------------------------------- /sites/ruby/overview:_organizing.step: -------------------------------------------------------------------------------- 1 | message "When your program gets longer than one screenful, it gets hard to keep track of. Most interesting problems have hundreds of lines of code. Let's look at tools that make it more manageable." 2 | goals do 3 | goal "Use functions to break up code into tasks" 4 | goal "Use classes to group variables and functions that naturally go together" 5 | end 6 | 7 | next_step 'functions' -------------------------------------------------------------------------------- /sites/ruby/summary:_basics.step: -------------------------------------------------------------------------------- 1 | message "We\'ve seen built in data types, input and output, making decisions with conditionals as well as some looping. We've also identified two interesting data structures: the **array** and the **hash**." 2 | 3 | message "Challenge yourself to create programs for the following situations." 4 | 5 | message <<-CONTENT 6 |
    7 |
  • Write a program that verifies whether someone can vote based on their supplied age.
  • 8 |
  • Write a program that plays back the message a user supplied.
  • 9 |
  • Write a program that adds up five user-supplied numbers.
  • 10 |
  • Make a hash for the people at your table, where the key is their name and the value is their favorite color.
  • 11 |
  • Make an array of the months in the year.
  • 12 |
13 | CONTENT 14 | 15 | 16 | message "When programs get big, they get disorganized and hard to read. Next we'll look at how to keep things tidy with functions and classes." 17 | next_step "overview:_organizing" 18 | 19 | -------------------------------------------------------------------------------- /sites/ruby/summary:_tools.step: -------------------------------------------------------------------------------- 1 | 2 | message <<-SUMMARY 3 | We\'ve explored the basic tools for writing and running Ruby programs. 4 |
    5 |
  • How do you open the console on your laptop? 6 |
  • How do you find out what directory you\'re in on the command line? How can you move to a different directory? 7 |
  • How do you start the RailsBridge VM and connect to it? 8 |
  • Where should you save files when you're using the RailsBridge VM? Can you show it in Finder or File Explorer? 9 |
  • How do you run a Ruby program? 10 |
  • How can you experiment with Ruby interactively? 11 |
  • 12 |
13 | Let's dive into the ABCs of Ruby. 14 | 15 | SUMMARY 16 | 17 | next_step 'overview:_building_blocks' -------------------------------------------------------------------------------- /sites/ruby/what_is_ruby.step: -------------------------------------------------------------------------------- 1 | goals do 2 | goal "Discuss what a programming language is" 3 | goal "Discuss some of the characteristics of the Ruby language" 4 | end 5 | 6 | explanation do 7 | message <<-CONTENTS 8 | Every application on your computer was written by somebody, from the operating system to your web browser. Every program was written in some kind of programming language. 9 | 10 | Programming languages come in all shapes and sizes. Some are optimized for the speed at which the computer will execute them, and some are optimized for the speed at which a human can program in them. 11 | 12 | Ruby was invented in the mid-1990s by Yukihiro Matsumoto -- Matz for short. Matz\' goals were to make programming faster and easier. \'Ruby is designed to make programmers happy.\' 13 | 14 | Ruby\'s popularity soared with the invention of the **Ruby on Rails** web framework, but Ruby is useful for many more things than just websites. 15 | CONTENTS 16 | end 17 | 18 | further_reading do 19 | message '[Wikipedia\'s article on Ruby](https://en.wikipedia.org/wiki/Ruby_\(programming_language\))' 20 | message 'If you know another programming language, see [Ruby From Other Languages](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages) for a comparison' 21 | end 22 | 23 | next_step "command_line" 24 | -------------------------------------------------------------------------------- /sites/ruby/working_with_collections.step: -------------------------------------------------------------------------------- 1 | message <<-CONTENTS 2 | We usually work with multiple things - print a list of groceries, add several numbers, etc. 3 | 4 | We often repeat the same action on each thing in a group - frost a dozen cupcakes. 5 | 6 | Ruby provides a couple of containers, plus ways to perform an action on each item in a collection. 7 | 8 | CONTENTS 9 | 10 | goals do 11 | goal "Hold multiple things with arrays and hashes" 12 | goal "Loop over all the members of a group" 13 | goal "Do a function to each member of a group" 14 | end 15 | 16 | next_step 'arrays' -------------------------------------------------------------------------------- /sites/testing-rails-applications/final_challenge.step: -------------------------------------------------------------------------------- 1 | message <<-MARKDOWN 2 | 3 | Congratulations! Take a second and give yourself a pat on your back. You've come far, my young padawan. This is the final test (no pun intended haha!) :) 4 | 5 | # The final challenge 6 | Essentially, you will clone this repo (https://github.com/akanshmurthy/railsbridge-testfest) that has broken tests and fix all the broken tests. The broken tests will consist of a variety of different types of tests, incorporating everything you have learned thus far. Good luck, keep calm, and test on! 7 | 8 | MARKDOWN 9 | -------------------------------------------------------------------------------- /sites/testing-rails-applications/img/rails-test-types.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/testing-rails-applications/img/rails-test-types.png -------------------------------------------------------------------------------- /sites/testing-rails-applications/testing-rails-applications.step: -------------------------------------------------------------------------------- 1 | message <<-MARKDOWN 2 | ### Goal 3 | 4 | To teach you testing we are going to start with the basics and have you learn by doing through small challenges and then a final large. 5 | 6 | When you have completed this curriculum you should understand: 7 | 8 | * what tests are 9 | * why they're used 10 | * how they're used 11 | * what types of tests exist 12 | * what types of frameworks exist 13 | * some additional concepts in testing such as doubles, stubs, spies, and Webmock 14 | * how to write tests 15 | * how to break tests 16 | * how to fix tests 17 | 18 | ### Requirements 19 | 20 | We're going to be working with: 21 | 22 | * Ruby on Rails 23 | * A command line program 24 | * A text editor of your choice 25 | 26 | MARKDOWN 27 | 28 | tip "This is not a self-paced curriculum. You should use the discussion sections on each page to make sure everyone is together!" 29 | 30 | message <<-MARKDOWN 31 | ### Notable things 32 | 33 | As you might have noticed, we're assuming you've already been to a RailsBridge workshop before or have otherwise already explored a Rails app, and are ready for deeper knowledge. 34 | 35 | MARKDOWN 36 | 37 | important "This curriculum is written for Rails 5. Things will get awkward / broken if you're using an earlier version of Rails, so if you skipped the Installfest, you need to upgrade to Rails 5 now." 38 | 39 | message <<-MARKDOWN 40 | ### Tips for everyone 41 | 42 | * When adding code, it's awesome for students to walk through the code line by line and say out loud what is happening. (i.e., "The string is being stored in the instance variable" or "The method `snorgle` is being defined"). If you do it every time, you'll get really comfortable with the vocabulary of Rails! 43 | * Error messages are your friend! Read them carefully, and practice understanding what Rails is telling you. Seeing an error and just diving back into your code is a natural reaction, but stop! Then read, think, and talk about what the error means before fixing it. 44 | MARKDOWN 45 | 46 | insert '../intro-to-rails/working_effectively_and_efficiently' 47 | 48 | next_step "what_are_tests" 49 | -------------------------------------------------------------------------------- /sites/workshop/beginners.mw: -------------------------------------------------------------------------------- 1 | * What's a program? Operating system? 2 | * What's a framework? 3 | ** something that makes it faster to build an application because it contains most of the things you would commonly write 4 | * Workflow - how do you write a program? 5 | ** Learn about customer's requirements -> translate to "stories" 6 | ** Pick a story that seems doable and start writing code that does it 7 | ** Show your work to the customer, get feedback 8 | ** Based on feedback, adjust stories (customer's "up front" requirements vs. changes once they see something working) 9 | ** Once story is finished, go back to "pick a story"...keep going until you're done! (This is an example of looping!) 10 | * alternate [[programming intro]] 11 | * Basic programming structures - or, how to do the "start writing code" step 12 | ** variables - words that hold information 13 | ** types of information - text, numbers, collections 14 | ** operators - doing stuff with variables 15 | ** loops - doing the same action a bunch of times 16 | ** printing - to the screen, or to a file 17 | * Writing a simple program 18 | ** opening the editor 19 | ** opening the command line 20 | ** adding two numbers together, storing in a variable 21 | ** printing variable to the screen 22 | ** save and run 23 | -------------------------------------------------------------------------------- /sites/workshop/closing.deck.md: -------------------------------------------------------------------------------- 1 | 2 | # You have completed RailsBridge #38! 3 | * Congratulations! 4 | 5 | 6 | 7 | # Please thank our awesome sponsor! 8 | ![EngineYard](img/ey_logo_rgb.png) 9 | 10 | 11 | # Celebrate! 12 | * After-party 13 | * Conference Party 14 | 15 | 16 | # What did we learn? 17 | * Ruby as a language 18 | * Rails as a framework 19 | * MVC design pattern 20 | 21 | 22 | # Resources: 23 | * http://installfest.railsbridge.org/workshop/resources 24 | * http://pinterest.com/pvnrtmol/ruby-and-rails-resources/ 25 | * http://pinterest.com/eanakashima/learn-the-front-end/ 26 | * Follow-up: 27 | * Ruby Users of Minnesota — a fine group of Ruby enthusiasts from around the Twin Cities metro area, or pretty much wherever they feel like driving from. Our group meets on the last Monday of each month at 7 PM http://ruby.mn/ 28 | * RailsBridge IRC channel 29 | * DevChix E-mail list http://www.devchix.com/ 30 | * Systers mailing list 31 | * Want to organize a workshop? join railsbridge-workshops@googlegroups.com 32 | 33 | 34 | # RIGHT NOW 35 | * TAKE THIS SURVEY RIGHT NOW: http://bit.ly/workshop_survey 36 | -------------------------------------------------------------------------------- /sites/workshop/command_prompt.mw: -------------------------------------------------------------------------------- 1 | There are several ways of opening a terminal window. You'll be using it often, so the best way is creating an shortcut icon on the Taskbar. 2 | 3 | == Opening a terminal == 4 | === Windows 7 === 5 | * Click the Windows Icon. In the "Search programs and files" field, type: cmd and press the [enter] key 6 | 7 | [[File:img/Win7_search_programs.jpg]] 8 | 9 | == Creating a terminal shortcut icon on the Taskbar == 10 | === Windows 7 === 11 | * Click: Windows Icon, "All Programs", "Accessories". Right click on "Terminal", click on "Pin to Taskbar". 12 | 13 | == Recommended setup for command-line windows == 14 | 15 | * Right-click on the menu bar and select "Properties" 16 | * Under the Options tab, check the box for "QuickEdit Mode" (this will let you visually cut and paste) 17 | * Under the Font tab, select Lucida Console from the font chooser box. This lets you view non-ascii characters. 18 | * Under the Layout tab, adjust Window Size so the window spans the screen horizontally and takes up about half the window space vertically (this may require some trial and error). Increase Screen Buffer Size Height to 1000. 19 | * Hit OK. In the dialog that comes up, select "Modify shortcut that started this window." 20 | -------------------------------------------------------------------------------- /sites/workshop/diagrams.mw: -------------------------------------------------------------------------------- 1 | * Git Geography: http://github.com/alexch/mission/raw/master/git.png 2 | 3 | * MVC: http://github.com/alexch/mission/raw/master/mvc.png 4 | 5 | * MVC: https://www.railstutorial.org/book/toy_app#sec-exercises_mvc_in_action 6 | 7 | * REST: 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 39 | 46 | 53 | 60 |
DBHTTPRESTRailsNotes
19 | GET 20 | /topics/new 21 | new 22 | shows the page with the "new topic" form 23 | 24 |
CreatePOST/topicscreatecreates a new topic in the database
Read 33 | GET 34 | /topics 35 | index 36 | shows the list of all topics 37 | 38 |
Read 40 | GET 41 | /topics/2 42 | show 43 | shows only topic number 2 44 | 45 |
Read 47 | GET 48 | /topics/2/edit 49 | edit 50 | shows the page with the "edit topic 2" form 51 | 52 |
Update 54 | PUT 55 | /topics/2 56 | update 57 | changes topic number 2 58 | 59 |
Delete 61 | DELETE 62 | /topics/2 63 | destroy 64 | deletes topic number 2 65 | 66 |
67 | -------------------------------------------------------------------------------- /sites/workshop/helpful_examples.mw: -------------------------------------------------------------------------------- 1 | The right example or diagram can go a long way toward helping a beginner grasp an abstract concept. Add examples, metaphors, similies, diagram, or approach to teaching concepts or terms here. 2 | 3 | = Classes and Methods = 4 | 5 | == Verbing a noun. == 6 |
> "word".upcase
 7 |  => "WORD" 
 8 | 
9 | This follows the format "object.method". 10 | Method is a verb, and object is our direct object (the thing the method is acting on). 11 | So in this case, we are saying "please take 'word' and make it uppercase" 12 | 13 | == You can also use classes to retrieve characteristics of an object. == 14 |
> 1.class
15 |  => Fixnum 
16 | So in this case, we are saying "hey 1, what is your class?" 17 | To which it replies, "I'm a FixNum, of course!" 18 | 19 | = MVC = 20 | 21 | This image was really, really helpful to me as I was learning it: 22 | 23 | [[File:http://php-html.net/tutorials/wp-content/uploads/2009/08/mvc-collaboration.png]] 24 | -------------------------------------------------------------------------------- /sites/workshop/img/Win7_search_programs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/Win7_search_programs.jpg -------------------------------------------------------------------------------- /sites/workshop/img/acrobat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/acrobat.jpg -------------------------------------------------------------------------------- /sites/workshop/img/agile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/agile.jpg -------------------------------------------------------------------------------- /sites/workshop/img/cheatsheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/cheatsheet.png -------------------------------------------------------------------------------- /sites/workshop/img/ey_logo_rgb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/ey_logo_rgb.png -------------------------------------------------------------------------------- /sites/workshop/img/firefox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/firefox.png -------------------------------------------------------------------------------- /sites/workshop/img/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/git.png -------------------------------------------------------------------------------- /sites/workshop/img/git_bash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/git_bash.png -------------------------------------------------------------------------------- /sites/workshop/img/itunes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/itunes.png -------------------------------------------------------------------------------- /sites/workshop/img/linux_logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/linux_logo.gif -------------------------------------------------------------------------------- /sites/workshop/img/mac_terminal_sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/mac_terminal_sm.png -------------------------------------------------------------------------------- /sites/workshop/img/os_x_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/os_x_logo.jpg -------------------------------------------------------------------------------- /sites/workshop/img/rails_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/rails_logo.jpg -------------------------------------------------------------------------------- /sites/workshop/img/railsbridge_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/railsbridge_logo.png -------------------------------------------------------------------------------- /sites/workshop/img/ruby-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/ruby-logo.jpg -------------------------------------------------------------------------------- /sites/workshop/img/rubygems.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/rubygems.png -------------------------------------------------------------------------------- /sites/workshop/img/windows_logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/windows_logo.gif -------------------------------------------------------------------------------- /sites/workshop/img/wordpress.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsbridge/docs/80901fbf7a5a4ad48bbcb6f4d63dcaa064c209b2/sites/workshop/img/wordpress.jpg -------------------------------------------------------------------------------- /sites/workshop/ta_cheat_sheet.md: -------------------------------------------------------------------------------- 1 | First, thanks for volunteering your time to TA a workshop. Here we've tried to 2 | capture tips to make your experience, and your student's, better. 3 | 4 | # First, Do No Harm 5 | 6 | The most important thing you can do as a TA is to make people 7 | feel they are in a safe learning environment. The worst outcome 8 | is for a student to leave frustrated, confused, or belittled and never wanting 9 | to try programming again. 10 | 11 | # Troubleshoot Problems 12 | 13 | The most important job of a TA is to help students who are stuck on a step so 14 | that the whole class does not have to wait for them. 15 | 16 | ## Make yourself available for questions and troubleshooting 17 | 18 | Some amount of struggling is part of learning, but if someone looks frustrated, 19 | offer a simple "Anything I can help with?" At the same time, try not to hover. 20 | 21 | # Help the Teacher Read the Room 22 | 23 | In general, teachers, especially new ones, tend to go too quickly. If you can 24 | tell students are confused, try offering to repeat your own explanation 25 | of a concept. Even just hearing it again can help and spark new questions. 26 | 27 | If you can tell someone is flying through the material (which often manifests 28 | as impatiently checking their phone as they wait for others) casually mention they 29 | are free to move up to the next level class if this class is moving too slowly. 30 | 31 | # Help with Logistics 32 | 33 | Volunteer to keep track of when it's time for breaks. This is super helpful! 34 | 35 | # Learn from Your Teacher 36 | 37 | Most teachers begin as TAs. Note what does and doesn't work about the class and 38 | use that if you get the opportunity to teach. 39 | -------------------------------------------------------------------------------- /sites/workshop/web_apps.deck.md: -------------------------------------------------------------------------------- 1 | !SLIDE 2 | ## Web App Network Architecture 3 | ![](img/web-application.png) 4 | 5 | !SLIDE 6 | ## Web App MVC Architecture 7 | ![](img/mvc_simple.png) 8 | 9 | !SLIDE 10 | # REST 11 | * Representational State Transfer 12 | * Application state and functionality are abstracted into resources 13 | * Each resource may be referenced with a global identifier (URI over HTTP) 14 | * Resources share a uniform interfaces 15 | * Note 16 | * introduced in 2000 in the doctoral dissertation of Roy Fielding 17 | * http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm 18 | 19 | !SLIDE 20 | # REST URIs and HTTP actions 21 | * GET http://myserver.com/topics - a list of all the topics 22 | * GET http://myserver.com/topics/1 - the first topic 23 | * POST http://myserver.com/topics - create a topic 24 | * PUT http://myserver.com/topics/1 - modify the first topic 25 | * DELETE http://myserver.com/topics/1 - delete the first topic 26 | 27 | -------------------------------------------------------------------------------- /sites/workshop/workshop.md: -------------------------------------------------------------------------------- 1 | # Materials for Teachers 2 | 3 | * [Foundational Skills](foundational_skills) 4 | * [Ruby for Beginners](ruby_for_beginners) 5 | * [Ruby for Programmers](ruby_for_programmers) 6 | * [Diagrams (Git, MVC, REST) ](diagrams) 7 | * [Activities](activities) 8 | 9 | ### Teacher Training 10 | * [Teacher Training Deck](more_teacher_training) 11 | * [Teacher Training Deck 2016](more_teacher_training_2016) 12 | * [Teacher Cheat Sheet](teacher_cheat_sheet) - A TL;DR version of the deck 13 | * [TA Cheat Sheet](ta_cheat_sheet) - A doc geared especially for first-time TAs 14 | 15 | # Materials for Organizers 16 | 17 | ### Workshop Intro & Closing Presentation Slide Decks 18 | 19 | If you can edit HTML, this is the presentation for you. It's the prettiest: 20 | 21 | * [Welcome and Closing Reveal.js deck (zip file)](http://cl.ly/0T341w3X130q) 22 | 23 | Download, then open up the index.html file in a text editor. Edit pages 0 24 | (dates, location, logo), 1 (sponsor logos), and 7 (after party location), and 25 | you're good to go. (Run it locally for the presentation itself.) 26 | 27 | #### Or copy one of these other formats: 28 | 29 | Google Docs presentations 30 | 31 | * [Welcome (google doc)](https://docs.google.com/presentation/d/1VT8J6CTuN8ot_-0ZElLv49_-cxuNmXTp83DBonD1x5w/edit#slide=id.p) 32 | * [Closing (google doc)](https://docs.google.com/presentation/d/19ik5tm_enCNRIM4zaY9rIoeRhDoMMfFUDgNXnd2lW6A/edit#slide=id.p) 33 | 34 | deck.rb 35 | 36 | * [Welcome](welcome) 37 | * [Closing](closing) 38 | 39 | Or make a presentation in the format of your choice. Powerpoint, Keynote, your own [reveal.js](http://lab.hakim.se/reveal-js/) deck — follow your heart! 40 | 41 | # Other? 42 | See the Table of Contents for a full list of materials. 43 | -------------------------------------------------------------------------------- /spec/app_deck_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | require_relative "../app" 4 | require "rack/test" 5 | 6 | describe InstallFest do 7 | include Rack::Test::Methods 8 | 9 | # todo: move to shared module 10 | def get! *args 11 | get *args 12 | expect(last_response.status).to eq(200) 13 | end 14 | 15 | def app 16 | Rack::Builder.parse_file(File.join(File.dirname(__FILE__), '..', 'config.ru')).first 17 | end 18 | 19 | describe "an app with slides" do 20 | require "deck" 21 | before do 22 | here = File.expand_path(File.dirname(__FILE__)) 23 | allow(Site).to receive(:sites_dir).and_return(File.join(here, 'sites')) 24 | end 25 | 26 | it "renders a deck" do 27 | get! "/meals/breakfast" 28 | # rendered_breakfast = Deck::SlideDeck.new(:slides => Deck::Slide.split(@breakfast)).to_pretty # for some reason it's not rendering pretty from the app even though the app uses .to_pretty 29 | expect(last_response.body).to include("Raisin Bran") 30 | end 31 | 32 | # todo: include deck.js source right inside the HTML 33 | it "serves up deck.js and other public assets" do 34 | get! "/deck.js/core/deck.core.js" 35 | expect(last_response.body).to include("Deck JS - deck.core") 36 | 37 | get! "/deck.js/jquery-1.7.2.min.js" 38 | expect(last_response.body).to include("jQuery v1.7.2 jquery.com") 39 | 40 | get! "/assets/application.css" 41 | expect(last_response.body).to include("/* Code ray css */") 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /spec/markdown_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | require "site" 3 | require "markdown_page" 4 | 5 | describe MarkdownPage do 6 | before do 7 | setup_test_translations 8 | end 9 | 10 | it "renders markdown into html" do 11 | src = <<-MARKDOWN.strip_heredoc 12 | # This is a heading 13 | 14 | ## This is a subheading 15 |

This text is preformatted and escaped

16 | 17 | ```html 18 | This text is preformatted and ready to be syntax highlighted as HTML source. 19 | ``` 20 | MARKDOWN 21 | 22 | page = MarkdownPage.new( 23 | src: src, 24 | site: Site.new("greetings"), 25 | page_name: 'hello', 26 | doc_title: "Hello", 27 | doc_path: "/tmp/hello.step", 28 | locale: "en" 29 | ) 30 | 31 | html_doc = Nokogiri.parse(page.to_html) 32 | main_html = html_doc.css("main").first.serialize(:save_with => 0).chomp 33 | 34 | expect(main_html).to loosely_equal(<<-HTML.strip_heredoc) 35 |
36 | Slides 37 |

Hello

38 |
39 |

This is a heading

40 |

This is a subheading

41 |
<h2>This text is preformatted and escaped</h2>
42 |
This text is preformatted and ready to be <strong>syntax highlighted</strong> as HTML source.
43 |
44 |
45 | HTML 46 | end 47 | end 48 | 49 | -------------------------------------------------------------------------------- /spec/media_wiki_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require "media_wiki" 3 | 4 | include MediaWiki 5 | 6 | describe "mw2md" do 7 | it "converts [[]]" do 8 | expect(mw2md("[[OS X 10.7 (Lion)]]")).to eq("[OS X 10.7 Lion](os_x_10_7_lion)") 9 | end 10 | end 11 | 12 | =begin 13 | * Mac users: [[OS X 10.7 (Lion)]] | [[OS_X_10.6_(Snow_Leopard) | OS X 10.6 (Snow Leopard)]] | [[OS X 10.6 or 10.5 (Snow Leopard or Leopard)]]. [[Determining your OS X version|Click here if you're not sure what version of OS X you have.]] 14 | * Linux users: [[Ubuntu 10.04 - Rails 3 |Ubuntu 10.04]] 15 | * Windows users: [[WindowsInstaller - Rails 3|Windows 7/Vista/XP]] 16 | =end 17 | 18 | -------------------------------------------------------------------------------- /spec/site_index_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | require_relative "../app" 4 | require_relative "../lib/site_index" 5 | 6 | describe SiteIndex do 7 | before :all do 8 | @site_index = SiteIndex.new(site_name: 'frontend', locale: 'en') 9 | end 10 | 11 | it "lists all sites in the /sites/ directory" do 12 | all_sites = Dir['sites/**'].map { |site_path| site_path.sub('sites/', '') } 13 | @site_index.sites.should =~ all_sites 14 | end 15 | 16 | it "only references existing sites in the 'categorized_sites' method" do 17 | @site_index.sites.should include(*@site_index.categorized_sites.values.flatten) 18 | end 19 | 20 | it "emboldens the current site, links other sites" do 21 | index_html = Nokogiri.parse(@site_index.to_html) 22 | 23 | current_site = index_html.css("li.current").first.text.capitalize 24 | current_site.should == 'Frontend' 25 | 26 | pretty_sites = @site_index.sites.map { |x| Titleizer.title_for_page(x) } 27 | 28 | other_sites = index_html.css('a').map(&:text) 29 | other_sites.should =~ (pretty_sites - ['Frontend']) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/site_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | require "site" 4 | 5 | describe Site do 6 | it "lists all sites" do 7 | sites = Site.all 8 | site_names = sites.map(&:name) 9 | site_names.should include("installfest") 10 | site_names.should include("intro-to-rails") 11 | end 12 | 13 | it "has doc files" do 14 | installfest = Site.named("installfest") 15 | doc_filenames = installfest.docs.map(&:filename) 16 | doc_filenames.should include("configure_git.step") 17 | end 18 | 19 | it "finds the default sites_dir" do 20 | Site.sites_dir.should == File.expand_path(File.join(File.dirname(__FILE__), "..", "sites")) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /spec/site_syntax_spec.rb: -------------------------------------------------------------------------------- 1 | require "cgi" 2 | require "spec_helper" 3 | require_relative "../app" 4 | 5 | require "site" 6 | 7 | require "rack/test" 8 | 9 | here = File.expand_path File.dirname(__FILE__) 10 | 11 | describe "Syntax check all sites" do 12 | include Rack::Test::Methods 13 | 14 | def app 15 | @app ||= InstallFest.new 16 | end 17 | 18 | InstallFest::AVAILABLE_LOCALES.each do |locale| 19 | describe "in locale '#{locale}'" do 20 | Site.all.each do |site| 21 | describe "#{site.name} pages..." do 22 | it 'uses all images in the /img folder' do 23 | site_folder = File.expand_path(File.join(here, '..', 'sites', locale, site.name)) 24 | unused_images = Dir[File.join(site_folder, 'img', '*')].select do |image_path| 25 | image_file = File.basename(image_path) 26 | system("grep -q -R -I img/#{image_file} #{site_folder} > /dev/null") ? nil : image_file 27 | end 28 | expect(unused_images).to eq([]) 29 | end 30 | 31 | site.docs.each do |doc| 32 | it "renders #{doc.filename}" do 33 | path = CGI.escape "/#{site.name}/#{doc.name}" 34 | get path, locale: locale 35 | if (last_response.status != 200) 36 | errors = last_response.errors 37 | meaningful_errors = errors.each_line.select do |l| 38 | l.include? path or l !~ %r{^\t} 39 | end.join 40 | puts "#{path}: #{meaningful_errors}" 41 | fail("Syntax errors in #{path} -- see above") 42 | end 43 | 44 | last_response_status = last_response.status 45 | expect(last_response_status).to eq(200) 46 | 47 | if doc.filename.end_with?('.step') 48 | expect(last_response.body).not_to match(/FUZZY/) 49 | end 50 | end 51 | end 52 | end 53 | end 54 | end 55 | end 56 | 57 | end 58 | -------------------------------------------------------------------------------- /spec/sites/meals/_find_utensils.step: -------------------------------------------------------------------------------- 1 | message "Maybe they are in the drawer?" -------------------------------------------------------------------------------- /spec/sites/meals/breakfast.deck.md: -------------------------------------------------------------------------------- 1 | # Eggs 2 | 3 | * scrambled 4 | * fried 5 | 6 | # Cereal 7 | 8 | * Frosted Mini-Wheats 9 | * Corn Flakes 10 | * Raisin Bran 11 | -------------------------------------------------------------------------------- /spec/sites/meals/clean_up.md: -------------------------------------------------------------------------------- 1 | Throw all your things away! ![garbage](garbage.jpg) 2 | 3 | YOU'RE DONE!! 4 | 5 | ![successful person](success.jpg) -------------------------------------------------------------------------------- /spec/sites/meals/eat_a_meal.step: -------------------------------------------------------------------------------- 1 | message "Put the food in your mouth!" 2 | 3 | next_step "clean_up" -------------------------------------------------------------------------------- /spec/sites/meals/find_some_vegetables.step: -------------------------------------------------------------------------------- 1 | Green ones are good. 2 | 3 | next_step "eat_a_meal" -------------------------------------------------------------------------------- /spec/sites/meals/meals.step: -------------------------------------------------------------------------------- 1 | Here is your meals file. 2 | 3 | link "breakfast" 4 | 5 | next_step "prepare_a_meal" -------------------------------------------------------------------------------- /spec/sites/meals/omnivorous.step: -------------------------------------------------------------------------------- 1 | You could use meat if you wanted to. 2 | 3 | insert 'find_utensils' 4 | 5 | next_step "eat_a_meal" -------------------------------------------------------------------------------- /spec/sites/meals/orphaned_page.step: -------------------------------------------------------------------------------- 1 | No page links to me! Why? -------------------------------------------------------------------------------- /spec/sites/meals/prepare_a_meal.step: -------------------------------------------------------------------------------- 1 | message "Are you" 2 | link "vegetarian" 3 | message "or" 4 | link "omnivorous" -------------------------------------------------------------------------------- /spec/sites/meals/vegetarian.step: -------------------------------------------------------------------------------- 1 | message "Make sure not to use any meat!" 2 | 3 | insert 'find_utensils' 4 | 5 | link "find_some_vegetables" -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | here = File.expand_path File.dirname(__FILE__) 2 | top = File.expand_path "#{here}/.." 3 | $: << "#{top}/lib" 4 | 5 | require "rspec" 6 | require "nokogiri" 7 | require "files" 8 | require 'active_support/core_ext/string/strip' 9 | 10 | Dir[File.join(top, "spec/support/**/*.rb")].each {|f| require f} 11 | 12 | RSpec.configure do |c| 13 | c.include Files 14 | c.include I18nHelper 15 | 16 | c.expect_with :rspec do |expectations| 17 | expectations.syntax = [:expect, :should] 18 | end 19 | 20 | c.mock_with :rspec do |mocks| 21 | mocks.syntax = [:should, :expect] 22 | end 23 | end 24 | 25 | -------------------------------------------------------------------------------- /spec/step_page_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | require "site" 3 | require "step_page" 4 | 5 | describe StepPage do 6 | before do 7 | setup_test_translations 8 | end 9 | 10 | # functional test -- brittle 11 | it "renders a step file" do 12 | BigCheckbox.number = 1 13 | 14 | src = "step 'hello'" 15 | page = StepPage.new( 16 | src: src, 17 | site: Site.new("greetings"), 18 | page_name: 'hello', 19 | doc_title: "Hello", 20 | doc_path: "/tmp/hello.step", 21 | locale: "en" 22 | ) 23 | 24 | html_doc = Nokogiri.parse(page.to_html) 25 | main_html = html_doc.css("main").first.serialize(:save_with => 0).chomp 26 | checkbox_html = %q{} 27 | 28 | expect(main_html).to loosely_equal(<<-HTML.strip_heredoc) 29 |
30 |

Hello

31 |
32 | 33 |
34 |

#{checkbox_html}Step 1: hello

35 |
36 |
37 |
38 | HTML 39 | end 40 | 41 | end 42 | 43 | -------------------------------------------------------------------------------- /spec/support/i18n_helper.rb: -------------------------------------------------------------------------------- 1 | require 'i18n' 2 | require_relative '../../app' 3 | 4 | module I18nHelper 5 | def setup_test_translations 6 | here = File.expand_path File.dirname(__FILE__) 7 | top = File.expand_path "#{here}/../.." 8 | 9 | I18n::Backend::Simple.include(I18n::Backend::Fallbacks) 10 | I18n.load_path = Dir[File.join(top, 'locales', '**/*.yml')] 11 | I18n.backend.load_translations 12 | 13 | I18n.available_locales = ::InstallFest::AVAILABLE_LOCALES 14 | I18n.locale = :en 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/matchers.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :loosely_equal do |expected| 2 | match do |actual| 3 | actual.gsub(/\n\s*/, '') == expected.gsub(/\n\s*/, '') 4 | end 5 | 6 | diffable 7 | end 8 | -------------------------------------------------------------------------------- /spec/titleizer_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require "titleizer" 3 | 4 | describe Titleizer do 5 | it 'uppercases acronyms' do 6 | { 7 | 'rvm_is_a_thing' => 'RVM Is A Thing', 8 | 'ssh_into_all_the_things' => 'SSH Into All The Things', 9 | 'CRUD_with_scaffolding' => 'CRUD With Scaffolding', 10 | 'why_cant_my_vhs_play_this_dvd' => 'Why Cant My Vhs Play This DVD', 11 | 'whats_the_deal_with_html' => 'Whats The Deal With HTML' 12 | }.each do |initial, expected| 13 | expect(Titleizer.title_for_page(initial)).to eq(expected) 14 | end 15 | end 16 | 17 | it 'uppercases osx as OS X' do 18 | expect(Titleizer.title_for_page('osx_ive_never_heard_of_it')).to eq('OS X Ive Never Heard Of It') 19 | end 20 | 21 | it 'uppercases argv' do 22 | expect(Titleizer.title_for_page('argv')).to eq('ARGV') 23 | end 24 | 25 | it 'keeps irb lowercase' do 26 | expect(Titleizer.title_for_page('irb_as_a_service')).to eq('irb As A Service') 27 | end 28 | 29 | it 'capitalizes sentences' do 30 | expect(Titleizer.title_for_page('sandwich_parade_on_tuesday')).to eq('Sandwich Parade On Tuesday') 31 | end 32 | end 33 | --------------------------------------------------------------------------------