嵌入式生成自定义id

tech2022-09-10  108

嵌入式生成自定义id

One great way of organically promoting your application is to provide “badges”; snippets of content that people can embed on their own websites.

有机地促进您的应用程序的一种好方法是提供“徽章”。 人们可以在自己的网站上嵌入的内容片段。

This can contain up-to-the-minute information from your application about a user, piece of content or another object, dynamically generated and inserted into other websites. This is probably best illustrated with some examples:

它可以包含来自应用程序的有关用户,内容或其他对象的最新信息,这些信息是动态生成并插入到其他网站中的。 最好用一些示例来说明:

In this article I’m going to take a look at some of the ways you can implement this.

在本文中,我将介绍一些实现此目标的方法。

设置示例应用程序 (Setting up our Example Application)

All the code from this tutorial is available on Github. There’s also an online demo.

本教程中的所有代码都可以在Github上找到 。 还有一个在线演示 。

First, we’ll define our application’s dependencies using Composer:

首先,我们将使用Composer定义应用程序的依赖项:

"silex/silex": "~2.0@dev", "twig/twig": ">=1.8,<2.0-dev", "smottt/wideimage": "dev-master"

Now, in index.php, let’s pull in the Composer-generated autoloader, add our use statement, initialize our Silex application and setup Twig templating:

现在,在index.php ,让我们引入Composer生成的自动加载器,添加我们的use语句,初始化我们的Silex应用程序并设置Twig模板:

require_once __DIR__.'/../vendor/autoload.php'; use Symfony\Component\HttpFoundation\Request, Symfony\Component\HttpFoundation\Response, WideImage\WideImage; $app = new Silex\Application(); // Register the Twig service provider $app->register(new Silex\Provider\TwigServiceProvider(), array( 'twig.path' => __DIR__.'/../views', ));

Let’s create a data-store of users, with some information about them which will form the basis of our example “badges”. For simplicity, we’ll use a static array; in practice you’d use a database, but it ought to be pretty simple to swap this out for something more dynamic. We’ll inject it into the application container like so:

让我们创建一个用户数据存储,其中包含有关用户的一些信息,这些信息将构成示例“徽章”的基础。 为了简单起见,我们将使用静态数组。 在实践中,您将使用数据库,但是将其替换为更动态的内容应该非常简单。 我们将其注入到应用程序容器中,如下所示:

/** * For simplicity, our datastore is a really simple, static array */ $app['datastore'] = function(){ return [ 'users' => [ 'dave' => [ 'avatar' => 'man1.png', 'trophies' => 1, 'rank' => 'Novice', ], 'jim' => [ 'avatar' => 'man2.png', 'trophies' => 2, 'rank' => 'Intermediate', ], 'helen' => [ 'avatar' => 'woman1.png', 'trophies' => 4, 'rank' => 'Grand Master', ], ] ]; };

Now that we’ve got a basic application set up along with some data, let’s go through three approaches to how you can provide an embeddable “badge” which displays this data for a given user.

现在,我们已经建立了基本的应用程序以及一些数据,下面让我们通过三种方法来提供可嵌入的“徽章”,以显示给定用户的数据。

内嵌框架 (IFrames)

IFrames are arguably a dirty word in web circles, perhaps deservedly so. But they are a common and practical approach to embedding content from one site into another.

在网络圈子里,iframes可以说是一个肮脏的词,也许理应如此。 但是,它们是将内容从一个站点嵌入另一个站点的一种常见且实用的方法。

Let’s start with this approach; later we can reuse some of the code when we try out the JavaScript method.

让我们从这种方法开始; 稍后,当我们尝试JavaScript方法时,我们可以重用一些代码。

Start with a simple Twig template, which creates some HTML – with inlined styles, to minimize HTTP requests – which contains our “badge” as a <div>:

从一个简单的Twig模板开始,该模板创建一些带有内联样式HTML以最小化HTTP请求,该模板包含我们的“徽章”作为<div> :

<!-- /views/badge.twig --> <html> <head> <title>{{ username }}</title> <style> .badge { width: 250px; height: 80px; border: solid 1px #ccc; clear: both; } .avatar { float: left; width: 80px; } .badge .avatar img { margin: 10px 0 0 10px } .badge .info { width: 170px; float: right; } .badge .info h3 { margin: 0.25em 0; } .badge .info h4 { margin: 0.25em 0; color: #666; } </style> </head> <body> <div class="badge"> <div class="avatar"> <img src="{{ imagepath }}/{{ user.avatar }}"> </div> <div class="info"> <h3>{{ username }}</h3> <h4>{{ user.rank }}</h4> <div class="trophies"> {% for i in 1..user.trophies %} <img src="{{ imagepath }}/trophy.png"> {% endfor %} </div> </div> </div> </body> </html>

This is all pretty straightforward. Notice how we’re incorporating a variable named imagepath which we’ll set server-side, which is going to take care of one very important aspect – any images we incorporate must be referenced using absolute URLs.

这一切都非常简单。 请注意,我们如何合并一个名为imagepath的变量,该变量将在服务器端进行设置,这将处理一个非常重要的方面–我们合并的任何图像都必须使用绝对URL进行引用。

Now the corresponding route:

现在对应的路线:

/** * Dynamically-generated HTML for embedding in an iFrame */ $app->get('/iframe/{username}', function(Request $request, $username) use ($app) { // Check that the user in question exists if (!isset($app['datastore']['users'][$username])) { // No user with that username, throw a 404 $app->abort(404, "User $username does not exist."); } // Get the user record $user = $app['datastore']['users'][$username]; return $app['twig']->render('badge.twig', [ 'username' => $username, 'imagepath' => ( ($request->server->get('HTTP_PORT') == 443) ? 'https' : 'http' ) . '://' . $request->server->get('HTTP_HOST') . '/images', 'user' => $user, ] ); });

All pretty straightforward. The bit which populates $imagepath is a bit quick-and-dirty, but it’ll do the job for now.

一切都很简单。 填充$imagepath的位有点$imagepath ,但现在就可以完成。

Embedding this into a third-party site is really simple:

将其嵌入第三方网站非常简单:

<iframe src="/iframe/dave" width="300" height="100"></iframe>

Later we’ll look at some of the things you need to think about with the iframe approach; for now, let’s move onto method number two.

稍后,我们将介绍iframe方法需要考虑的一些事项; 现在,让我们进入第二种方法。

动态创建的图像 (Dynamically Created Images)

One of the simplest ways to implement this is to provide a URL to an image, which gets created server-side.

实现此目的的最简单方法之一是提供图像的URL,该图像在服务器端创建。

Here’s a screenshot of the sort of image we’re going to create:

这是我们将要创建的图像的屏幕截图:

Okay, it won’t win any awards for design, but you can use the same approach to create much more visually appealing images than this.

好的,它不会赢得任何设计奖项,但是您可以使用相同的方法来创建视觉上更具吸引力的图像。

You’ll find the necessary resources – the background and trophy images, avatars and fonts – in the example application’s repository.

您将在示例应用程序的存储库中找到必要的资源-背景和奖杯图片,化身和字体。

Here’s some example code to dynamically generate an embeddable image:

这是一些示例代码,用于动态生成可嵌入的图像:

/** * Dynamically-generated image */ $app->get('/image/{username}', function($username) use ($app) { // Check that the user in question exists if (!isset($app['datastore']['users'][$username])) { // No user with that username, throw a 404 $app->abort(404, "User $username does not exist."); } // Get the user record $user = $app['datastore']['users'][$username]; // Load the background $background = WideImage::load(__DIR__.'/../resources/images/background.png'); // Load the avatar $avatar = WideImage::load(__DIR__.'/images/' . $user['avatar']); // Load the trophy image $trophy = WideImage::load(__DIR__.'/images/trophy.png'); // Paste the avatar onto the background $im = $background->merge($avatar, 10, 20); // Get the canvas $canvas = $im->getCanvas(); // Set the font for the username $canvas->useFont(__DIR__.'/../resources/fonts/VeraBd.ttf', 12, $im->allocateColor(0, 0, 0)); // Write the username onto the canvas $canvas->writeText(70, 15, $username); // Choose a slightly smaller, non-bold font $canvas->useFont(__DIR__.'/../resources/fonts/Vera.ttf', 9, $im->allocateColor(0, 0, 0)); // Write the rank $canvas->writeText(70, 35, $user['rank']); // Now add the appropriate number of trophies $x = 70; for ($i = 0; $i < $user['trophies']; $i++) { $im = $im->merge($trophy, $x, 55); $x += 20; } // Finally, output the image to the screen return $im->output('png'); });

It’s pretty much self-documented, and should be pretty simple to adapt to your needs or with better images. Note that we’re taking the background image from a non-web accessible directory (resources), but the avatars and trophy icon are in the public directory.

它几乎是自我记录的,并且应该很简单以适应您的需求或具有更好的图像。 请注意,我们是从不可通过网络访问的目录( resources )中获取背景图片的,但头像和奖杯图标位于public目录中。

Embedding this into a third-party website couldn’t be simpler:

将其嵌入第三方网站再简单不过了:

<img src="http://example.com/image/helen">

You’ll note that there’s no file extension; this doesn’t matter, though, since WideImage’s output() method will set the appropriate headers for you.

您会注意到没有文件扩展名。 但这无关紧要,因为WideImage的output()方法将为您设置适当的标头。

There are a couple of improvements we could make. For one thing, we’re generating a new image on each request. However you can use WideImage’s saveToFile() method to cache the results, like so:

我们可以进行一些改进。 一方面,我们正在为每个请求生成一个新图像。 但是,您可以使用WideImage的saveToFile()方法来缓存结果,如下所示:

$im->saveToFile('/path/to/badge.png');

It might also be better to provide a default image when the requested user cannot be found, rather than issuing a 404 error.

当找不到请求的用户时,最好提供一个默认图像,而不是发出404错误。

Now onto the third and final approach.

现在进入第三种也是最后一种方法。

Java脚本 (Javascript)

Using JavaScript to dynamically create embedded content is amongst the most common, and perhaps the most flexible approach.

使用JavaScript动态创建嵌入式内容是最常见的方法,也是最灵活的方法之一。

Again we’re going to generate some HTML, but this time we’ll return a simple snippet of JavaScript that will write it to the host page. All that requires is that the host website insert a simple <script> tag where they want our content to appear.

再次,我们将生成一些HTML,但是这一次,我们将返回一个简单JavaScript片段,将其写入宿主页面。 所需要的只是在宿主网站上插入一个简单的<script>标记,以便他们在其中显示我们的内容。

We’ll re-use the Twig template from earlier, but this time the route looks slightly different:

我们将重用之前的Twig模板,但是这次的路线看起来略有不同:

/** * Dynamically-generated JavaScript */ $app->get('/js/{username}', function(Request $request, $username) use ($app) { // Check that the user in question exists if (!isset($app['datastore']['users'][$username])) { // No user with that username, throw a 404 $app->abort(404, "User $username does not exist."); } // Get the user record $user = $app['datastore']['users'][$username]; // Build the HTML $html = $app['twig']->render('badge.twig', [ 'username' => $username, 'imagepath' => ( ($request->server->get('HTTP_PORT') == 443) ? 'https' : 'http' ) . '://' . $request->server->get('HTTP_HOST') . '/images', 'user' => $user, ] ); // Minify the HTML, ensuring we wind up with one long string $minified = preg_replace( array( '/ {2,}/', '/<!--.*?-->|\t|(?:\r?\n[ \t]*)+/s' ), array( ' ', '' ), $html ); // Return a document.write with the minified, populated HTML as its argument return new Response( sprintf('document.write(\'%s\');', $minified), 200, [ 'Content-Type', 'text/javascript' ] ); });

The first part is identical to the iframe approach. This time, though, we’re generating a simple document.write. Before we can do that, we use a little preg_replace magic to minify the resulting HTML – which also ensures it will all be on one line – then insert it into some very simple dynamically created JavaScript.

第一部分与iframe方法相同。 不过,这一次,我们正在生成一个简单的document.write 。 在我们做到这一点之前,我们使用一点preg_replace魔术来最小化最终HTML,这也确保了所有HTML都在一行上,然后将其插入到一些非常简单的动态创建JavaScript中。

Embedding this into a page is just as simple:

将其嵌入页面很简单:

<div><script src="/js/jim"></script></div>

Strictly speaking, we don’t even need that container DIV, but it can be used to apply styling on the host site.

严格来说,我们甚至不需要该容器DIV,但是它可以用于在宿主站点上应用样式。

Now that we’ve examined three approaches, let’s look at some of the things you need to think about when deciding which of these approaches to take.

现在,我们已经研究了三种方法,下面让我们看一下在决定采用哪种方法时需要考虑的一些事项。

注意事项 (Considerations)

When choosing an approach to this problem, there are a few things you need to weigh up.

选择解决此问题的方法时,您需要权衡一些事项。

CMS的 (CMS’s)

If you’re intending people to be able to embed content into the body of CMS-driven content or within blog posts, it’s worth bearing in mind that any CMS or blog software worth its salt will block certain types of content. Inline scripts are almost certainly out. IFrames are probably going to be stripped out. That probably just leaves image tags.

如果您打算让人们能够将内容嵌入CMS驱动的内容主体或博客帖子中,则请记住,任何值得其关注的CMS或博客软件都将阻止某些类型的内容。 内联脚本几乎可以确定。 iframe可能会被剥离。 可能只剩下图像标签。

造型 (Styling)

There are a few ways to approach styling; perhaps you want to control everything, keeping your badges consistent across sites. Alternatively, you could provide default styles but allow site owners the flexibility to override them to better fit the design of their site.

有几种方法可以处理样式。 也许您想控制一切,使各个站点的徽章保持一致。 另外,您可以提供默认样式,但允许网站所有者灵活地覆盖它们,以更好地适应其网站设计。

Obviously images cannot be customized; aside, perhaps, their sizing. If you use iframes, it’s worth noting that any styling applied to the parent page will not be inherited by your content. On the other hand if you use the JavaScript approach, it may well be possible to override the styling, depending on specificity and how you incorporate your styles. The demo page that comes with the example application shows this in action.

显然,图像无法自定义; 除了它们的大小。 如果您使用iframe,则值得注意的是,应用于父页面的任何样式都不会被您的内容继承。 另一方面,如果使用JavaScript方法,则很可能有可能覆盖样式,具体取决于具体性以及样式的合并方式。 示例应用程序随附的演示页面显示了这一操作。

客制化 (Customization)

Perhaps, like Stackoverflow and their “User Flair” badges, you want to provide a number of alternative styles – light and dark, for example. This is entirely possible with any of the approaches I’ve outlined, though it’s arguably slightly more difficult with the image tag approach.

也许像Stackoverflow及其“ User Flair”徽章一样,您想要提供多种替代样式-例如浅色和深色。 使用我概述的任何方法,这都是完全可能的,尽管使用图像标签方法可能会稍微困难一些。

高级 (Advanced)

So far our embeddable content has been dynamically generated, but in no way interactive. A Facebook “like” button, for example, doesn’t just provide a count – it also allows people to perform the “like” action from within the page. That sort of interactivity will be covered in a later article.

到目前为止,我们的可嵌入内容是动态生成的,但绝不是交互式的。 例如,Facebook的“喜欢”按钮不仅提供了计数,还允许人们从页面内执行“喜欢”动作。 这种交互性将在以后的文章中介绍。

摘要 (Summary)

Embeddable content is great way to promote your site. It can be used not only to link back to your site but to provide “live” content, right there on a third-party “host” website.

可嵌入的内容是推广您的网站的好方法。 它不仅可以用于链接回您的网站,还可以在第三方“托管”网站上提供“实时”内容。

We’ve looked at three common approaches to this – images, iframes and JavaScript. We’ve looked at some of the things you need to think about when deciding which one to use, along with some pitfalls to be wary of.

我们已经研究了三种常见的方法–图像,iframe和JavaScript。 我们已经研究了在决定使用哪一种时需要考虑的一些事项,以及一些需要警惕的陷阱。

翻译自: https://www.sitepoint.com/3-ways-implement-embeddable-custom-badges/

嵌入式生成自定义id

相关资源:jdk-8u281-windows-x64.exe
最新回复(0)