code: def _placeholders_recursif(nodelist, plist, blist):
      
      # I needed to do this lazy import to compile the documentation
      from django.template.loader_tags import BlockNode
  
      for node in nodelist:
  
          # extends node?
          if hasattr(node, 'parent_name'):
              _placeholders_recursif(node.get_parent(dummy_context).nodelist,
                                                          plist, blist)
          # include node?
          elif hasattr(node, 'template') and hasattr(node.template, 'nodelist'):
              _placeholders_recursif(node.template.nodelist, plist, blist)
  
          # Is it a placeholder?
          if hasattr(node, 'page') and hasattr(node, 'parsed') and \
                  hasattr(node, 'as_varname') and hasattr(node, 'name'):
              already_in_plist = False
              for placeholder in plist:
                  if placeholder.name == node.name:
                      already_in_plist = True
              if not already_in_plist:
                  if len(blist):
                      node.found_in_block = blist[len(blist) - 1]
                  plist.append(node)
              node.render(Context())
  
          for key in ('nodelist', 'nodelist_true', 'nodelist_false'):
              if isinstance(node, BlockNode):
                  # delete placeholders found in a block of the same name
                  offset = 0
                  _plist = [(i, v) for i, v in enumerate(plist)]
                  for index, pl in _plist:
                      if pl.found_in_block and \
                              pl.found_in_block.name == node.name \
                              and pl.found_in_block != node:
                          del plist[index - offset]
                          offset += 1
                  blist.append(node)
  
              if hasattr(node, key):
                  try:
                      _placeholders_recursif(getattr(node, key), plist, blist)
                  except:
                      pass
              if isinstance(node, BlockNode):
                  blist.pop()
docs: Recursively search into a template node list for PlaceholderNode
      node.