استبدال الصورة الرمزية واسم المستخدم لمشاركة معينة

المشكلة: أريد أن يتمكن المستخدمون من النشر كشخصيات ألعاب تقمص الأدوار. أود أن يتمكنوا من إدراج قالب في منشور - شيء مثل ما يلي:

[wrap="characterpost"]
[characterav]https://image.link.example.png[/characterav]
[charactername][[اسم الشخصية]][/charactername]
[/wrap]

ثم استخدام برنامج نصي لاستبدال الصورة بالصورة الرمزية الأصلية ووضع رابط موضوع اسم الشخصية قبل اسم المستخدم. على سبيل المثال، إذا كان المنشور يقول عادةً “اسم المستخدم”، فأريد استبداله بـ “اسم الشخصية التي يلعبها اسم المستخدم”.
(سيشمل “اسم الشخصية” رابطًا إلى موضوع يحتوي على ورقة الشخصية، على أمل استخدام مكون سمة الويكي لسهولة الاستخدام.)

لقد قمت بلصق هيكل منشور في Codepen وتمكنت من كتابة بعض جافا سكريبت التي ستقوم بذلك بالضبط. ومع ذلك، عندما يتعلق الأمر بإضافتها إلى مزخرف المنشور وجعلها تعمل مباشرة مع واجهة برمجة التطبيقات، فقد اصطدمت بحائط.

إليك ما لدي في رأس الصفحة المشتركة حاليًا:

<script type="text/discourse-plugin" version="0.8">
api.decorateCookedElement(
  element => {
    
    // العثور على علامة characterpost داخل المنشور
    const characterPost = element.querySelector('[data-wrap="characterpost"]');
	
    // العثور على العنصر الأب لعلامة characterpost، والذي يحتوي على الصورة الرمزية واسم المستخدم
    const characterPostParent = characterPost.closest('article');
	
    // جعله أحمر لمعرفة ما إذا كان يعمل
    characterPostParent.style.backgroundColor = "red";
    
  },
  {
    id: 'render-character-post', onlyStream: true, afterAdopt: true
  }
);
</script>

كان هذا يرمي خطأ. هل من الممكن الوصول إلى غلاف “المقال” للمنشورات باستخدام decorateCookedElement حتى أتمكن من الوصول إلى اسم المستخدم والصورة الرمزية؟ إذا لم يكن الأمر كذلك، فكيف يمكنني المضي قدمًا في هذا؟

4 إعجابات

مرحباً، يا غير عادل،

لقد عثرت على هذا المنشور، واعتقدت أنني أستطيع تجربته!

إليك الإصدار الأول؛ آمل ألا يكون الكود فظيعًا جدًا. :slightly_smiling_face:
لم أختبر جميع الحالات الطرفية بشكل شامل. إنها نقطة انطلاق.

  • التنسيق المتوقع للغلاف: [wrap=character avatar=\"<URL>\"]<Name>[/wrap]
  • تأكد من وجود سطر فارغ أسفل [wrap]
  • يمكنك تخصيص اسم الشخصية باستخدام CSS (انظر فئات character و character-extra)

أخبرني إذا واجهت أي مشاكل :slight_smile:

الرأس
<script type="text/discourse-plugin" version="0.8.13">

let characters = new Map();

function searchTag(obj, tag) {
  if (!obj || !obj.firstObject) return;
  
  const firstObj = obj.firstObject;
  return firstObj.tagName === tag ? firstObj : searchTag(firstObj.children, tag);
}
            
api.addPostTransformCallback(post => 
{
    if (post.post_number <= 1 || post.post_type !== 1) {
        return;
    }

    const matches = post.cooked.match(/data-wrap="character"\s+data-avatar="(?<avatar>[^"]+)"\s+data-name="(?<name>[^"]+)"/i);
    
    if (!matches) {
        characters.delete(post.id);
        return;
    }
    
    // TODO: sanity check for avatar/name
    
    const {name, avatar} = matches.groups;
    
    characters.set(post.id, {name, avatar});
    
});

api.reopenWidget("post-avatar", {
    html(attrs) {
        const html = this._super(attrs);
        
        if (attrs.id && characters.has(attrs.id)) {
            const imageHtml = searchTag(html, 'IMG');
    
            if (imageHtml) {
                imageHtml.properties.attributes.src = characters.get(attrs.id).avatar;
            }
        }
        
        return html;
    }
});

api.reopenWidget("poster-name", {
    html(attrs) {
        let html = this._super(attrs);
        
        if (attrs.id && characters.has(attrs.id)) {
            const h = require("virtual-dom").h;
            
            html = [
                h('span.character', this.userLink(attrs, characters.get(attrs.id).name)),
                h('span.character-extra', 'played by'), // optional
                ...html
            ];
        }
        
        return html;
    }
});

</script>
CSS
.names {
    .character a {
        font-weight: bold;
        color: var(--tertiary-high);
    }
    
    .character-extra {
        
    }
}

.cooked, .d-editor-preview {
    p:has(> [data-wrap="character"]) {
        display: none;
    }
    
    p:has(> [data-wrap="character"]) + * {
        margin-top: 0;
    }
}

إليك عرض توضيحي صغير لكيف بدا الأمر:

7 إعجابات

هذا رائع جدًا، شكرًا لك على المشاركة! كنت أبحث عن شيء مشابه أيضًا. هل تعرف ما إذا كان هذا يؤثر على كيفية ظهور المنشورات في البحث أيضًا؟

سؤال جيد! اسم العلامة ومحتواها جزء من محتوى المنشور؛ قد يؤثر هذا على نتيجة البحث.
سأجرب شيئًا أنظف، مثل استخدام نافذة منبثقة والحفظ في حقول مخصصة بدلاً من ذلك.

تعديل: أعتقد أنني أسأت الفهم :ابتسامة: إذا كنت تتحدث عن ظهور التغييرات في نتيجة البحث، فالإجابة هي لا (ولن يظهر كود HTML أيضًا).

إعجابَين (2)

هذا رائع جداً. الفيديو الخاص بك يمر بسرعة. هل الرابط موجود على موقع المنتدى؟

يا دان. ماذا تقصد؟

عنوان الصورة الرمزية. هل هو مجرد صورة تم تحميلها أم يشير إلى موقع خارجي؟

هذا عنوان URL خارجي. يجب أن يكون من الممكن العمل مع عنوان URL محلي.

إعجابَين (2)

شكرا لك

إعجاب واحد (1)

قد يكون من المفيد اقتراح دليل قوالب المنتدى في الويكي المجتمعي. غالبًا ما يبحث الأشخاص عن أفكار حول أنواع مختلفة من إعدادات المنتديات. في هذه الحالة، قد يكون الأمر متخصصًا. ولكن قالب لعبة تقمص الأدوار على الطاولة يتضمن هذه الميزة التي أنشأتها.