<object>, <embed> и валидный код
В детстве нас всех учили, что для встраивания флэша на страницу нужно пользоваться тегами object и embed. Объясняли это тем, что object используется Internet Explorer'ом на винде, а браузеры, основанные на Netscape понимают только embed.
Казалось бы, вставляй оба тега и будет счастье. Только вот счастья нет, потому что embed — это нестандартный тег, которого нет в спецификации HTML4.01 / XHTML1.0. (однако, он включён в черновик HTML5).
Но это ещё не вся шокирующая правда. Дело в том, что все более-менее современные браузеры поддерживают стандартный тег object.
В своём блоге я часто использую флэш, чтобы показывать видяшки и вставлять музыку. При этом я просто копирую под плеера с сайта и вставляю его в запись, либо использую oembed (о котором я скоро напишу заметку). В большинстве случаев этот кусок кода содержит оба тега, а иногда и вовсе только embed.
Все знают, что валидный HTML код — это мой пунктик. Поэтому я не стал терпеть этих невалидных корявок в своём собственном блоге и решил разобраться. Погуглив, я нашёл рецепт (написанный аж в 2002 году), описывающий, как вставлять объекты на страницу, используя при этом только валидный код. Вкратце суть его такова:
- Для тега
objectнужно указать атрибутtype, напримерtype="application/x-shockwave-flash" - Также для
objectнужно указать атрибутdata. В нём указывается URL объекта, который вы хотите вставить - После этого нужно удалить тег
embedнафиг
Чтобы не заниматься такой чисткой вручную, я написал простенькую функцию, которая автоматически исправляет HTML код перед отображением на странице. Вот она:
from BeautifulSoup import BeautifulSoup, Tag def fix_embeds(value): soup = BeautifulSoup(value) for object in soup.findAll("object"): movie = None for param in object.findAll("param"): if param["name"] == "movie": movie = param["value"] embeds = object.findAll("embed") if embeds: embed = embeds[0] else: embed = None data = object.get("data") if not data: if movie: object["data"] = movie elif embed and embed.get("src"): object["data"] = embed["src"] else: continue if not object.get("type") and embed.get("type"): object["type"] = embed["type"] del object["classid"] for embed in object.findAll("embed"): embed.extract() for embed in soup.findAll("embed"): src = embed.get("src") type = embed.get("type") if not src or not type: continue width = embed.get("width") height = embed.get("height") object = Tag(soup, "object") object["data"] = src object["type"] = type if width: object["width"] = width if height: object["height"] = height embed.replaceWith(object) return unicode(soup)
На её основе можно, например, сделать фильтр для шаблонов Django.
Обратите внимание, что я принудительно удаляю атрибут classid из тегов object. Его назначение остаётся для меня загадкой, однако если он присутствует, то не отображается музыкальный проигрыватель с Jamendo.
Пользуйтесь на здоровье. Если обнаружите какие-то косяки — пишите.
P.S. Теперь у меня полностью валидный бложек.
Комментарии