利用Discourse变量个性化嵌入的Typeform

In @sam’s example of an embedded Typeform, the url for the Typeform is:

https://basvanleeuwen1.typeform.com/to/NzdRpx?typeform-embed=embed-widget

That’s great, but I would like to personalize my Typeforms using hidden fields. If the Discourse username could be added to the url, then I could use it in the form. So when I visit, the url would be:

https://basvanleeuwen1.typeform.com/to/NzdRpx?typeform-embed=embed-widget&username=markschmucker

Is there a way to do that? Is it a candidate for a plugin?

Note you need a paid Typeform account for this to work.

Sounds a bit too fancy to be in the core onebox, the good news is that you will probably not need a plugin here a theme component can do the trick.

2 个赞

Thanks Sam. So something like this?

<script type="text/discourse-plugin" version="0.8">
  $( document ).ready(function() {
    const user = api.getCurrentUser(),
      username = user.username;

    $('h1.hello-world').html('Hello there '+username+"!")
  });
</script>

Except find and replace the url instead of saying Hello?

Yeah this is not the approach I would take, what you are looking for is decorate cooked in the plugin API.

2 个赞

Here is my (somewhat clumsy) solution, in case it helps someone. I added this code under Admin > Customize > Themes > Edit CSS/HTML > /head:

    <script type="text/discourse-plugin" version="0.8">
        api.decorateCooked($elem => {
            var i, j;
            var selector = 'https://example.typeform.com';
            // seems like this should work but it doesn't:
            // var typeforms = $elem[0].querySelectorAll('src^=[' + selector + ']');
            var ps = $elem[0].querySelectorAll('p');
            for (i=0; i<ps.length; i++) {
                p = ps[i];
                var iframes = p.querySelectorAll('iframe');
                for (j=0; j<iframes.length; j++) {
                    var iframe = iframes[j];
                    if (iframe.src.startsWith(selector)) {
                        var oldsrc = iframe.getAttribute('src');
                        var username = api.getCurrentUser()['username'];
                        var newsrc = oldsrc + '?username=' + username;
                        iframe.setAttribute('src', newsrc);
                    }
                }
            }
        });
    </script>

Then add a Hidden Field “username” in your Typeform. The username can be used in your form, and will also be sent to the destination (integrations or webhook) when the user hits Submit.

When you get the Typeform link to embed in Discourse, it will be something like:

https://example.typeform.com/to/dr8oAa?username=xxxxx

Remove the ?username=xxxxx before embedding; the js above will add it back, with the proper Discourse username.

1 个赞

如果您稍后看到此内容,我有一个@mark78的精彩帖子的更新版本:

将此代码添加到“管理”>“自定义”>“主题”>“编辑 CSS/HTML”>“HEAD”下

️如果您使用的是企业版,则必须创建一个空主题组件来添加此内容。

<script type="text/discourse-plugin" version="0.8.25">
    api.decorateCooked(($elem) => {
        const iframes = $elem[0].querySelectorAll('iframe[src^="https://form.typeform.com"]');
        const userName = api.getCurrentUser()?.username;
        
        if(!userName){ return; }
        
        for (let i = 0; i < iframes.length; i++) {
            iframes[i].setAttribute('src', `${iframes[i].getAttribute('src')}?username=${userName}`);
        }
    });
</script>
  • 在您的Typeform中添加一个名为“username”的隐藏字段
  • 只需分享链接即可在您的帖子中嵌入Typeform。不要使用Typeform的嵌入功能。您还需要在管理员设置中允许嵌入Typeform URL https://forms.typeform.com