Upgrade to Pro — share decks privately, control downloads, hide ads and more …

HHGTTWD

 HHGTTWD

Hitchhiker's Guide to the Web Development

Carlos Hernando

March 21, 2013
Tweet

More Decks by Carlos Hernando

Other Decks in Programming

Transcript

  1. The Hitchhiker's Guide to the Web Development Carlos Hernando @chernando

  2. 1,220,000,000 results

  3. DON’T PANIC

  4. PHP Python Ruby Java JavaScript ?

  5. Model View Controller

  6. Model View Controller

  7. Object-Relational Mapping

  8. Object-Relational Mapping Post.comments SELECT * FROM comment where post_id =

    2;
  9. Model View Controller

  10. None
  11. None
  12. Model View Controller

  13. http://www.ticketea.com/try-it-general http://www.ticketea.com/ URL Controller: Index URL Controller: event ‘try-it’

  14. GET POST HTTP REQUEST

  15. None
  16. Config CLI Tools Module/Application URLs

  17. Model View Controller Template MVT

  18. Model Template View

  19. class Post(models.Model): title = models.CharField(max_length=45) author = models.ForeignKey(AUTH_USER_MODEL) content =

    models.TextField()
  20. class Comment(models.Model): author = models.ForeignKey(AUTH_USER_MODEL) post = models.ForeignKey(Post) content =

    models.TextField()
  21. Model Template View

  22. {% extends "base.html" %} {% block content %} {% for

    post in posts %} <div> <h2><a href="{{ post.get_absolute_url }}"> {{ post.title }} </a></h2> <h3>by {{ post.author }}</h3> <p> {{ post.content }} </p> <p>{{ post.comments }} comments</p> </div> {% endfor %} {% endblock %}
  23. class Post(models.Model): title = models.CharField(max_length=45) author = models.ForeignKey(AUTH_USER_MODEL) content =

    models.TextField() @property def comments(self): return self.comment_set.count() def __unicode__(self): return self.title def get_absolute_url(self): return reverse('post', args=[self.pk]) ;-(
  24. class PostForm(forms.ModelForm): class Meta: model = Post exclude = ('author',)

    <form action="{% url 'publish' %}" method="post"> {{ form.as_p }} <input type="submit" value="Submit" /> {% csrf_token %} </form> forms.py post_create.html
  25. Model Template View

  26. from . import views urlpatterns = patterns('', url(r'^$', views.index, name='index'),

    url(r'^publish/$', views.post_create, name='publish'), url(r'^post/(?P<post_id>\d+)/$', views.post_detail, name='post'), url(r'^post/(?P<post_id>\d+)/comment/$', views.comment_create, name='comment'), )
  27. def index(request): last_posts = Post.objects\ .order_by('-pk')[:5] context = {'posts': last_posts}

    return render(request, 'blog/post_list.html', context)
  28. {% extends "base.html" %} {% block content %} {% for

    post in posts %} <div> <h2><a href="{{ post.get_absolute_url }}"> {{ post.title }} </a></h2> <h3>by {{ post.author }}</h3> <p> {{ post.content }} </p> <p>{{ post.comments }} comments</p> </div> {% endfor %} {% endblock %}
  29. def comment_create(request, post_id): post = get_object_or_404(Post, pk=post_id) form = CommentForm(request.POST

    or None) if form.is_valid(): comment = Comment() comment.author = request.user comment.post = post comment.content=form.cleaned_data['content'] comment.save() return HttpResponseRedirect( post.get_absolute_url()) else: return render(request, 'blog/post_detail.html', {'post': post, 'form': form})
  30. None
  31. Config CLI Tools Module/Bundle Controller Model Views and Routes

  32. Model View Controller

  33. /** * Post * * @ORM\Table() * @ORM\Entity */ class

    Post { /** * @var integer * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var string * * @ORM\Column(name="title", type="string", length=45) */ private $title;
  34. /** * @ORM\OneToMany(targetEntity="Comment", mappedBy="post") */ private $comments; /** * @ORM\ManyToOne(targetEntity="Post",

    inversedBy="comments") * @ORM\JoinColumn(name="post_id", referencedColumnName="id") */ private $post; Post.php Comment.php
  35. Model View Controller

  36. {% extends "base.html.twig" %} {% block content %} {% for

    post in posts %} <div> <h2><a href="{{ path('try_it_blog_post_detail', {'post_id': post.id}) }}"> {{ post.title }}</a></h2> <p> {{ post.content }} </p> <p>{{ post.comments.count }} comments</p> </div> {% endfor %} {% endblock %}
  37. $post = new Post(); $form = $this->createFormBuilder($post) ->add('title', 'text') ->add('content',

    'textarea') ->getForm(); <form action="{{ path('try_it_blog_post_create') }}" method="post"> {{ form_widget(form) }} <input type="submit" /> </form> PostController.php detail.html.twig
  38. Model View Controller

  39. try_it_blog_homepage: pattern: / defaults: { _controller: TryItBlogBundle:Post:index } try_it_blog_post_create: pattern:

    publish/ defaults: { _controller: TryItBlogBundle:Post:create } try_it_blog_post_detail: pattern: post/{post_id}/ defaults: { _controller: TryItBlogBundle:Post:detail } try_it_blog_comment_create: pattern: post/{post_id}/comment/ defaults: { _controller: TryItBlogBundle:Comment:create }
  40. class PostController extends Controller { public function indexAction() { $posts

    = $this->getDoctrine() ->getRepository('TryItBlogBundle:Post') ->findBy(array(), // ALL array('id' => 'desc'), 7); return $this->render( 'TryItBlogBundle:Post:index.html.twig', array('posts' => $posts)); }
  41. public function createAction(Request $request) { /* $post and $form missing

    */ if ($request->isMethod('POST')) { $form->bind($request); if ($form->isValid()) { $em = $this->getDoctrine() ->getManager(); $em->persist($post); $em->flush(); return $this->redirect($this ->generateUrl('try_it_blog_post_detail', array('post_id' => $post->getId()))); } } return $this->render( 'TryItBlogBundle:Post:create.html.twig', array('form' => $form->createView()));
  42. None
  43. AJAX RESTful API

  44. Micro framework VS Framework

  45. Model View Controller

  46. Models.Comment = Backbone.Model.extend({ }); Collections.Comments = Backbone.Collection.extend({ model: Models.Comment });

    Model Collection
  47. Models.Post = Backbone.Model.extend({ defaults: { title: 'No title', content: 'No

    content', comments: new Collections.Comments() }, initialize: function() { this.get('comments').on('all', function() { this.trigger('change') }, this); } }); See fetch!
  48. Model View Controller

  49. Templates.Post = _.template([ '<h2>{{ title }}</h2>', '<p>', '{{ content }}',

    '</p>', '<p>', ' <a href="#" class="showComments btn"> Show comments</a>', ' <a href="#" class="comment btn btn-primary"> Comment!</a>', '</p>', ].join(''));
  50. Model View Controller

  51. Views.Post = Backbone.View.extend({ initialize: function() { this.model.on('all', this.render, this); this.render();

    }, render: function() { this.$el.html( Templates.Post(this.model.toJSON())); var n_comments = this.model.get('comments') .length; this.$el.append($('<p>') .html('' + n_comments + ' comments')); return this; },
  52. events: { 'click .showComments': 'showComments', 'click .comment': 'createComment' }, showComments:

    function() { var comments = $('#comments'); var body = comments.find('.modal-body').empty(); this.model.get('comments').each( function(comment) { body.append( Templates.Comment(comment.toJSON())); }); comments.modal('show'); }, createComment: function() { var view = new Views.CreateComment( { post: this.model }); },
  53. None
  54. Routes?

  55. PHP Python Ruby Java JavaScript MVC

  56. HTML5 / CSS3 Bootstrap / Boilerplate Responsive Accessibility Developer’s tools

    Sessions Migrations Database performance NoSQL Cache Load balance Deploy Scalability Security ...
  57. Web Development https://www.udacity.com/course/cs253 CS169.1x: Software as a Service https://www.edx.org/courses/BerkeleyX/CS169.1x/2013_March/about HTML5

    Game Development https://www.udacity.com/course/cs255
  58. 42

  59. https://github.com/chernando/ https://speakerdeck.com/chernando/hhgttwd

  60. So Long, and Thanks for All the Fish

  61. ABOUT This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike

    3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/ 3.0/. Product names, logos and trademarks of other companies which are referenced in this document remain the property of those other companies.