জ্যাঙ্গো টেমপ্লেটে কীভাবে একটি "ব্লক" পুনরাবৃত্তি করবেন


126

আমি একই j% ব্লক%} একই জাঙ্গো টেমপ্লেটে দুবার ব্যবহার করতে চাই । আমি চাই এই বেসটি আমার বেস টেমপ্লেটে একাধিকবার প্রদর্শিত হবে:

# base.html
<html>
    <head>
        <title>{% block title %}My Cool Website{% endblock %}</title>
    </head>
    <body>
        <h1>{% block title %}My Cool Website{% endblock %}</h1>
    </body>
</html>

এবং তারপরে এটি প্রসারিত করুন:

# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}

# pictures.html
{% extends 'base.html' %}
{% block title %}My Pictures{% endblock %}

# cats.html
{% extends 'base.html' %}
{% block title %}My Cats{% endblock %}

আমি একটি ব্যতিক্রম পাব, যেহেতু জাঙ্গো ব্লকটি কেবল একবার প্রদর্শিত হবে:

টেমপ্লেস সিনট্যাক্স এয়ার / এ

'শিরোনাম' নামের 'ব্লক' ট্যাগটি একাধিকবার উপস্থিত হয় appears

একটি দ্রুত এবং ময়লা সমাধান ব্লক অনুরূপ হবে উপাধি মধ্যে TITLE1 এবং TITLE2 :

# blog.html
{% extends 'base.html' %}
{% block title1 %}My Blog{% endblock %}
{% block title2 %}My Blog{% endblock %}

তবে এটি ডিআরওয়াই নীতি লঙ্ঘন । আমার কাছে উত্তরাধিকার সূত্রে প্রাপ্ত অনেকগুলি টেম্পলেট রয়েছে এবং এটি খুব খারাপ হবে কারণ আমি জাহান্নামে যেতে চাই না ;-)

এই সমস্যাটির কি কোনও কৌশল বা কাজ আছে? সমস্ত কোডের নকল না করে আমি কীভাবে আমার টেমপ্লেটে একই ব্লকের পুনরাবৃত্তি করতে পারি?


1
এই প্রশ্নে সমাধান দেখতে stackoverflow.com/q/1178743/168034
phunehehe

2
এই উত্তরটি দেখুন, বিশেষ করে ফোনের সাথে সম্পর্কিত লিঙ্কগুলির প্রশ্নের।
টুবু

উত্তর:


69

আমি মনে করি প্রসঙ্গে প্রসেসরের ব্যবহার এই ক্ষেত্রে একটি ওভারকিল। আপনি সহজেই এটি করতে পারেন:

#base.html
<html>
    <head>
        <title>{% block title %}My Cool Website{% endblock %}</title>
    </head>
    <body>
        {% block content %}{% endblock %}
    </body>
</html>

এবং তারপর:

# blog.html
{% extends 'base.html' %}
{% block content %}
    <h1>{% block title %}My Blog{% endblock %}</h1>
    Lorem ipsum here...
{% endblock %}

এবং এই জাতীয় ... DRY- সামঞ্জস্যপূর্ণ মনে হচ্ছে।


1
আমি আগামীকাল এটি চেষ্টা করতে পারি - আমি কীভাবে টেমপ্লেটগুলিতে কিছুটা পুনরাবৃত্তি সংরক্ষণ করব তা ভাবছিলাম এবং এটি একটি ভাল পদ্ধতির মতো বলে মনে হচ্ছে। ধন্যবাদ।
thebigLive

1
এই পদ্ধতির দুর্দান্ত। আমি আমার বেস এইচটিএমএলকে বেস হিটটিএমটিএল এবং সুপারবেস এইচটিএমএলে বিভক্ত করেছি, সুতরাং আপনি যদি ভাগ করা টেম্পলেটগুলিতে একটি মানক শিরোনাম মার্কআপ (এইচ 1 এর মতো) রাখতে চান তবে এটিও কাজ করে। পৃষ্ঠাগুলি এখনও শিরোনাম ব্লকের সামগ্রীতে ওভাররাইড করতে পারে এবং এটি উভয় জায়গায় আপডেট হবে।
সিস্টেমপারাডক্স

2
এটি পাঠ্যের দ্বিগুণের বেশি ব্যবহার করতে দেয় না, তাই না?
ডেনিস গোলোমাজোভ 23'15

1
ডেনিস গোলোমাজভ: না। সেক্ষেত্রে ম্যাক্রো প্লাগইন ব্যবহার করা ভাল (নীচে দেখুন)।
dqd

1
সংজ্ঞা: এছাড়াও অন্যান্য উপায় কাছাকাছি প্রয়োগ করা যেতে পারে h1ব্লক যে সংজ্ঞায়িত ভিতরে বিষয়বস্তু title। বা এমন একটি ব্লক যা এর একটি অংশকে সংজ্ঞায়িত করে title
মিকায়েল লিন্ডল্ফ

83

জাজানো টেমপ্লেট ম্যাক্রোস প্লাগইনটি ব্যবহার করুন:

https://gist.github.com/1715202 (django> = 1.4)

অথবা

http://www.djangosnippets.org/snippets/363/ (জাজানো <1.4)

জ্যাঙ্গো> = 1.4

# base.html
{% kwacro title %}
    {% block title %}My Cool Website{% endblock %}
{% endkwacro %}

<html>
    <head>
        <title>{% usekwacro title %}</title>
    </head>
    <body>
        <h1>{% usekwacro title %}</h1>
    </body>
</html>

এবং

# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}

জ্যাঙ্গো <1.4

# base.html
{% macro title %}
    {% block title %}My Cool Website{% endblock %}
{% endmacro %}

<html>
    <head>
        <title>{% usemacro title %}</title>
    </head>
    <body>
        <h1>{% usemacro title %}</h1>
    </body>
</html>

এবং

# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}

2
এটি চমৎকার! জাজানো লুপ এবং এজাক্স ডেটা লুপের সাথে টেমপ্লেটগুলি ভাগ করে নিয়ে আমি যে সমস্যাগুলি পেয়েছি তা সত্যিই পরিষ্কার করতে পারে।
গ্লিসারিন

1
ভাল সমাধান। তবে এটি "ব্যবহার_ম্যাক্রো"। "Usemacro" ভুল wrong
রামটিন

অবশ্যই ডিফল্টরূপে জ্যাঙ্গোতে তৈরি করা উচিত।
zepp.lee

19

আপনি সম্ভবত একটি ব্লক ব্যবহার করতে চান না বরং কেবল একটি ভেরিয়েবল ব্যবহার করতে চান:

# base.html
<html>
    <head>
        <title>{{ title|default:"My Cool Website" }}</title>
    </head>
    <body>
        <h1>{{ title|default:"My Cool Website" }}</h1>
    </body>
</html>

তারপরে আপনি প্রসঙ্গে শিরোনামটি সেট করলেন।


17
সম্ভবত শুকনো। তবে আপনি ভিউয়ের মধ্যে শিরোনামটি সেট করতে চান না; কিন্তু টেমপ্লেটগুলিতে।
লক্ষ্মণ প্রসাদ

6
শিরোনামগুলি টেমপ্লেটগুলির মধ্যে থেকেই সেট করা উচিত, প্রসঙ্গ দ্বারা সরবরাহ করা হবে না, আপনার এই "শিরোনাম" ভেরিয়েবল সংজ্ঞায়নের একটি উপায় থাকা দরকার, অন্যথায় এটি কোনও ভাল সমাধান নয়।
গিলাইম এস্কোভিন

জাঙ্গো অ্যাডমিন টেমপ্লেটগুলি এটাই করে ({{শিরোনাম} for এর জন্য), তবে সরানোর সময় শিরোনাম নির্ধারণ করা অসুবিধাজনক।
তোবু

13

নিজে একই জিনিসটি করার চেষ্টা করার সময় আমি এখানে একটি উপায় আবিষ্কার করেছি:

# base_helper.html
<html>
    <head>
        <title>{% block _title1 %}{% endblock %}</title>
    </head>
    <body>
        <h1>{% block _title2 %}{% endblock %}</h1>
    </body>
</html>


# base.html
{% extends "base_helper.html" %}

# Copy title into _title1 & _title2, using "My Cool Website" as a default.
{% block _title1 %}{% block _title2 %}{% block title %}My Cool Website{% endblock %}{% endblock %}{% endblock %}

দুর্ভাগ্যক্রমে একটি অতিরিক্ত ফাইলের প্রয়োজন, তবে আপনাকে ভিউ থেকে শিরোনামটি পাস করার দরকার নেই।


শেষ পর্যন্ত আমি {% ম্যাক্রো%} সমাধানের জন্য স্থির হয়েছি, যার জন্য কোনও নতুন ফাইলের প্রয়োজন নেই এবং সামগ্রিকভাবে আমাকে ঠিক কী প্রকাশ করতে চাই তা প্রকাশ করতে দেয়।
রোমান স্টারকভ

সহজ এবং দক্ষ। @ ডিকিডিএস এর উত্তরের বিপরীতে, ব্লকগুলিকে নেস্ট করা দরকার না, উদাহরণস্বরূপ ফেসবুক ও ট্যাগগুলির জন্য, এতে অন্যান্য প্রধান বৈশিষ্ট্যগুলির মতো একই বিষয়বস্তু থাকতে পারে। ভোট দিন!
বেনজকিজি

2
দুর্দান্ত উত্তর। এটি @ dqd- এর উত্তরের চেয়েও DRYer বলে মনে হচ্ছে যেহেতু প্রতিটি টেম্পলেটে <h1> ট্যাগটি আপনার উত্তরাধিকার সূত্রে উত্তোলন করতে হবে না। এটি গ্রহণযোগ্য উত্তর হতে পারে।
অনুপম

অসাধারণ! আমি এটি আরও জটিল পরিস্থিতিতে ব্যবহার করেছি যেখানে আমি শীর্ষের টেবিলের পাদদেশ সারি পুনরাবৃত্তি করতে চেয়েছিলাম। এবং <tr>সারি বরং জটিল ছিল।
করম

12

আপনি {% include subtemplate.html %}একাধিকবার ব্যবহার করতে পারেন । এটি ব্লকগুলির মতো নয়, তবে কৌশলটি করে।


এটি একই সমস্যা আছে। বেস টেমপ্লেটটি অন্তর্ভুক্ত করতে হবে তা জানে না to
ভ্যান গালে

দয়া করে নোট করুন যে includeএটির চেয়ে ধীর blockdocs.djangoproject.com/en/1.10/topics/performance/…
ওয়াটওয়ার

5

এখানে কিছু আলোচনা রয়েছে: http://code.djangoproject.com/ticket/4529 স্পষ্টতই জাঙ্গো কোর দল এই টিকিটটি প্রত্যাখ্যান করে কারণ তারা মনে করে যে এটি কোনও সাধারণ ব্যবহৃত দৃশ্য নয়, তবে আমি একমত নই।

পুনরাবৃত্তি ব্লক এর জন্য সহজ এবং পরিষ্কার বাস্তবায়ন: https://github.com/SmileyChris/django-repeat block

টেমপ্লেট ম্যাক্রোগ হ'ল অন্যটি, তবে লেখক উল্লেখ করেছেন যে এটি সাবধানতার সাথে পরীক্ষা করা হয়নি: http://www.djangosnippets.org/snippets/363/

আমি রিপিটব্লক ব্যবহার করেছি।


4
আসল জ্যাঙ্গো-রিপিটব্লক সংগ্রহস্থলটি মুছে ফেলা হয়েছে বলে মনে হয়। এর সেরা কাঁটাচামচটি github.com/phretor/django-repeat block বলে মনে হচ্ছে ; আমি github.com/ydm/django-sameas ও পেয়েছি , যার জন্য 'ওন্টফিক্স' জাজানো প্যাচ দরকার নেই।
নাতেভ

4

এটি জুড়ে আসা যে কোনও ব্যক্তির জন্য আপডেট হিসাবে, আমি উপরে উল্লিখিত স্নিপেট নিয়েছি এবং এটি একটি টেমপ্লেট ট্যাগ লাইব্রেরিতে পরিণত করেছি, জাজানো-ম্যাক্রোস, ম্যাক্রোগুলিকে আরও শক্তিশালী করে তোলে এবং স্পষ্টভাবে একটি পুনরাবৃত্ত ব্লক প্যাটার্ন প্রয়োগ করে: জ্যাঞ্জো-ম্যাক্রোস


4

এখানে উপরের do_setএবং do_getটেমপ্লেট ট্যাগ উত্তরের মতো হালকা ওজনের সমাধান solution জ্যাঙ্গো আপনাকে পুরো টেমপ্লেট প্রসঙ্গে একটি ট্যাগে পাস করার অনুমতি দেয় যা আপনাকে বিশ্বব্যাপী পরিবর্তনশীল সংজ্ঞায়িত করতে দেয় allow

base.html:

<!DOCTYPE html>
<html lang="en">
<head>
  {% block head %}
    <title>{{ title }}</title>
  {% endblock %}
</head>
<body>
  <h1>{{ title }}</h1>
</body>
</html>

page.html:

{% extends "base.html" %}

{% block head %}
  {% define 'title' 'Homepage | title' %}
  {{ block.super }}
{% endblock %}

কাস্টম ট্যাগ (ধারণাটি এখানে পেয়েছে: https://stackoverflow.com/a/33564990/2747924 ):

@register.simple_tag(takes_context=True)
def define(context, key, value):
    context.dicts[0][key] = value
    return ''

এছাড়াও {% load %}আপনার কাস্টম ট্যাগগুলিতে ভুলে যাবেন না বা সেগুলি টেম্পলেট বিকল্পগুলি অন্তর্নির্মিত তালিকায় যুক্ত করুন যাতে আপনাকে সেগুলি প্রতিটি টেমপ্লেটে লোড করতে না হয়। এই পদ্ধতির একমাত্র সীমাবদ্ধতা হ'ল {% define %}একটি ব্লগ ট্যাগের মধ্যে থেকে কল করা উচিত কারণ শিশু টেম্পলেটগুলি কেবল পিতামাতাদের ট্যাগগুলির সাথে মেলে এমন ব্লক ট্যাগ সরবরাহ করে। আশেপাশে কোনও উপায় আছে কিনা তা নিশ্চিত নয়। এছাড়াও defineআপনি নিশ্চিতভাবে এটি ব্যবহার করার চেষ্টা করার আগে কলটি এসেছিল তা নিশ্চিত করুন।


3

ভ্যান গালের পরামর্শের ভিত্তিতে আপনি নিজের টেম্পলেটট্যাগস.পি ফাইলটিতে নিম্নলিখিতগুলি যুক্ত করে ট্যাগ তৈরি এবং সেট তৈরি করতে পারেন:

register = template.Library()

Stateful = {}
def do_set(parser, token):
    _, key = token.split_contents()
    nodelist = parser.parse(('endset',))
    parser.delete_first_token()  # from the example -- why?
    return SetStatefulNode(key,nodelist)

class SetStatefulNode(template.Node):
    def __init__(self, key, nodes):
        Stateful[key] = nodes
    def render(self, context):
        return ''
register.tag('set', do_set)

def do_get(parser, token):
    tag_name, key = token.split_contents()
    return GetStatefulNode(key)

class GetStatefulNode(template.Node):
    def __init__(self, key):
       self.key = key
    def render(self, context):
        return ''.join( [x.render(context) for x in Stateful[self.key]] )

register.tag('get', do_get)

তারপরে একটি টেম্পলেটে মানগুলি সেট করুন {% set foo %}put data here{% endset %}এবং সেগুলি {% get foo %}অন্য কোনও মাধ্যমে পান।


আমি মনে করি এটিই সবচেয়ে মার্জিত সমাধান। ধন্যবাদ কিরান এবং ভ্যান গাল!
রবার্ট ল্যাক্রিক্স

এটি বেশ চতুর, তবে মনে হয় সেট ট্যাগের সমস্ত নোড রেন্ডার করা আরও ভাল হতে পারে, অন্যথায় তারা গেটের মাধ্যমে বার বার রেন্ডার হয়ে যায়। আমি এমন কারণগুলি সম্পর্কে ভাবতে পারি যেগুলি একটি ভাল ধারণা হতে পারে (একটি পৃষ্ঠায় বিভিন্ন ব্লকের একই সঞ্চিত ব্লককে রেন্ডারিং) তবে আমি কেবল ভেবেছিলাম এটি চিহ্নিত করব।
আকজাই

3

আমিও আমার টেম্পলেট ফাইলগুলিতে বারবার।% ব্লক% for এর জন্য একই প্রয়োজনটি পূরণ করেছি। সমস্যাটি হ'ল আমি চাই যে একটি জ্যাঙ্গো block% ব্লক% a জ্যাঙ্গো শর্তসাপেক্ষে উভয় ক্ষেত্রেই ব্যবহার করা হোক এবং আমি চাই যে file% ব্লক%} পরবর্তী ফাইলগুলির দ্বারা অতিরিক্ত-লিখনযোগ্য হতে পারে যা বর্তমান ফাইলটি প্রসারিত করতে পারে। (সুতরাং এই ক্ষেত্রে, আমি যা চাই তা অবশ্যই ভেরিয়েবলের চেয়ে একটি ব্লকের বেশি কারণ আমি প্রযুক্তিগতভাবে এটি পুনরায় ব্যবহার করি না, এটি শর্তাধীন উভয় প্রান্তে প্রদর্শিত হয় appears

সমস্যাটি:

নিম্নলিখিত জ্যাঙ্গো টেমপ্লেট কোডটি একটি টেম্পলেট সিনট্যাক্স ত্রুটির ফলাফল করবে, তবে আমি মনে করি এটি একটি শর্তসাপেক্ষে defined% ব্লক%} পুনরায় ব্যবহার করা বৈধ "চান" বৈধ (IE, কেন জ্যাঙ্গো পার্সার বৈধকরণ সিনট্যাক্সটি উভয় প্রান্তে শেষ হবে) শর্তসাপেক্ষে, এটি কেবল সত্যের শর্তটি বৈধ করে তোলা উচিত নয়?)

# This example shows a {{ DEBUG }} conditional that loads 
#   Uncompressed JavaScript files if TRUE 
#   and loads Asynchronous minified JavaScript files if FALSE.  

# BASE.html
{% if DEBUG %}
    <script src="{{MEDIA_URL}}js/flatfile.1.js"></script>
    <script src="{{MEDIA_URL}}js/flatfile.2.js"></script>
    <script src="{{MEDIA_URL}}js/flatfile.3.js"></script>
    <script type="text/javascript">
        {% block page_js %}
            var page = new $site.Page();
        {% endblock page_js %}
    </script>
{% else %}
    <script type="text/javascript">
        // load in the PRODUCTION VERSION of the site
        // minified and asynchronosly loaded
        yepnope([
            {
                load : '{MEDIA_URL}}js/flatfiles.min.js',
                wait : true,
                complete : function() {
                    {% block page_js %} // NOTE THE PAGE_JS BLOCK
                        var page = new $site.Page();
                    {% endblock page_js %}
                }
            }
        )];
    </script>
{% endif %}

# ABOUT.html
{% extends 'pages/base.html' %}
{% block page_js %}
var page = new $site.Page.About();
{% endblock page_js %}

সমাধান:

আপনি শর্তসাপেক্ষে একবারে {% ব্লক% once সন্নিবেশ করতে {% অন্তর্ভুক্ত% use ব্যবহার করতে পারেন। এটি আমার পক্ষে কাজ করেছে কারণ জ্যাঙ্গো সিনট্যাক্স পরীক্ষকটিতে কেবল সত্য {% অন্তর্ভুক্ত রয়েছে%}} নীচে ফলাফল দেখুন:

# partials/page.js
{% block page_js %}
    var page = new $site.Page();    
{% endblock %}

# base.html
{% if DEBUG %}
    <script src="{{MEDIA_URL}}js/flatfile.1.js"></script>
    <script src="{{MEDIA_URL}}js/flatfile.2.js"></script>
    <script src="{{MEDIA_URL}}js/flatfile.3.js"></script>
    <script type="text/javascript">
        {% include 'partials/page_js.html' %}
    </script>
{% else %}
    <script type="text/javascript">
        yepnope([
            {
                load : '{MEDIA_URL}}js/flatfiles.min.js',
                wait : true,
                complete : function() {
                    {% include 'partials/page_js.html' %}
                }
            }
        )];
    </script>
{% endif %}


1

এর জন্য দুটি সহজ সমাধান রয়েছে।

আপনার শিরোনামটিকে প্রসঙ্গের ভেরিয়েবলের মধ্যে রাখাই সবচেয়ে সহজ। আপনি আপনার দৃষ্টিতে প্রসঙ্গের পরিবর্তনশীল সেট করবেন।

আপনি যদি জেনেরিক ভিউয়ের মতো কিছু ব্যবহার করছেন এবং ছবি, বিড়াল ইত্যাদির জন্য ভিউ.পি নেই তবে আপনি একটি কাস্টম টেম্পলেট ট্যাগের পথে যেতে পারেন যা প্রসঙ্গে একটি পরিবর্তনশীল সেট করে

এই রুটে যেতে আপনাকে এমন কিছু করতে সক্ষম করবে:

{% extends "base.html" %}
{% load set_page_title %}
{% page_title "My Pictures" %}
...

তারপরে আপনার বেস html এ:

...
{% block title %}{{ page_title }}{% endblock %}
...
<h1>{{ page_title }}</h1>

তবেAny variable set in the context will only be available in the same block of the template in which it was assigned. This behavior is intentional; it provides a scope for variables so that they don’t conflict with context in other blocks.
জোনাথন

0

বাছাই করা উত্তরগুলি উভয়কে একই মান দেওয়ার জন্য চাইল্ড টেম্পলেটে অন্য একটি ট্যাগের মধ্যে একটি ট্যাগ জড়ানোর জন্য একটি সহজ কাজের লক্ষ্যে নির্দেশ দেয়। আমি এটির মতো সামাজিক চিত্রগুলির জন্য এটি ব্যবহার করি।

শিশু টেমপ্লেট:

{% extends 'base.html' %}
...
{% block meta_image %}
{% block meta_image_secure %}
{% if object.cover_pic %}
{{ object.cover_pic.url }}
{% else %}
https://live-static.welovemicro.com/static/img/device-dark.png
{% endif %}
{% endblock %}
{% endblock %}
...

তারপরে পিতামাতায় base.html:

...
<meta property="og:image" itemprop="image" content="{% block meta_image %}https://live-static.welovemicro.com/static/img/device-dark.png{% endblock %}">
<meta property="og:image:secure_url" itemprop="image" content="{% block meta_image_secure %}https://live-static.welovemicro.com/static/img/device-dark.png{% endblock %}">
...

-3

ইন পল্লব আপনি ভালো করতে পারেন:

# base.html
<html>
    <head>
        <title>{{ block('title') }}</title>
    </head>
    <body>
        <h1>{{ block('title') }}</h1>
    </body>
</html>

# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}

# pictures.html
{% extends 'base.html' %}
{% block title %}My Pictures{% endblock %}

# cats.html
{% extends 'base.html' %}
{% block title %}My Cats{% endblock %}

3
এটি জ্যাঙ্গো সম্পর্কে একটি প্রশ্ন।
ফ্রান্সোইস কনস্ট্যান্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.