আমার মতে, টেমপ্লেটগুলি স্থিতিবদ্ধভাবে টাইপ করা প্রকৃতপক্ষে একটি ভাল জিনিস: আপনার গ্যারান্টিযুক্ত যে আপনার টেম্পলেটটি কল করলে এটি সংকলন করে ব্যর্থ হবে না।
যাইহোক, এটি প্রকৃতপক্ষে কলিং সাইটগুলিতে কিছু বয়লারপ্লেট যুক্ত করে। তবে আপনি এটি হ্রাস করতে পারেন (স্ট্যাটিক টাইপিং সুবিধাগুলি না হারিয়ে)।
স্কালায় আমি এটি অর্জনের দুটি উপায় দেখতে পাচ্ছি: ক্রিয়া সংমিশ্রণের মাধ্যমে বা অন্তর্নিহিত পরামিতি ব্যবহার করে। জাভাতে আমি এটি ব্যবহার করার পরামর্শ দিইHttp.Context.args
মানচিত্রটি দরকারী মানগুলি সংরক্ষণ করতে এবং টেম্পলেটগুলির পরামিতি হিসাবে স্পষ্টভাবে পাস না করে টেমপ্লেটগুলি থেকে পুনরুদ্ধার করার ।
অন্তর্নিহিত পরামিতি ব্যবহার করে
menus
আপনার main.scala.html
টেম্পলেট প্যারামিটারের শেষে প্যারামিটারটি রাখুন এবং এটিকে "অন্তর্নিহিত" হিসাবে চিহ্নিত করুন:
@(title: String)(content: Html)(implicit menus: Seq[Menu])
<html>
<head><title>@title</title></head>
<body>
<div>
@for(menu<-menus) {
<a href="#">@menu.name</a>
}
</div>
@content
</body>
</html>
এখন আপনার যদি এই প্রধান টেম্পলেটটিকে কল করে টেম্পলেট থাকে, আপনি যদি এই টেমপ্লেটগুলিতেও অন্তর্নিহিত পরামিতি হিসাবে ঘোষিত menus
হয়ে থাকেন তবে আপনি প্যারামিটারটি main
স্কেল সংকলক দ্বারা স্পষ্টভাবে আপনার জন্য টেম্পলেটটিতে পৌঁছে দিতে পারেন:
@()(implicit menus: Seq[Menu])
@main("SubPage") {
...
}
তবে আপনি যদি এটিকে আপনার নিয়ামকের কাছ থেকে সুস্পষ্টভাবে প্রেরণ করতে চান তবে আপনাকে এটিকে একটি অন্তর্নিহিত মান হিসাবে সরবরাহ করতে হবে, যেখানে আপনি টেমপ্লেটটি কল করেন সেখান থেকে পাওয়া যায়। উদাহরণস্বরূপ, আপনি আপনার নিয়ামকটিতে নিম্নলিখিত পদ্ধতিটি ঘোষণা করতে পারেন:
implicit val menu: Seq[Menu] = Menu.findAll
তারপরে আপনার ক্রিয়াকলাপে আপনি কেবল নিম্নলিখিতগুলি লিখতে সক্ষম হবেন:
def index = Action {
Ok(views.html.index())
}
def index2 = Action {
Ok(views.html.index2())
}
আপনি এই ব্লগ পোস্ট এবং এই কোড নমুনায় এই পদ্ধতির সম্পর্কে আরও তথ্য সন্ধান করতে পারেন ।
আপডেট : এই নিদর্শনটি প্রদর্শন করে একটি দুর্দান্ত ব্লগ পোস্টও এখানে লেখা হয়েছে ।
ক্রিয়া রচনা ব্যবহার করে
প্রকৃতপক্ষে, প্রায়শই RequestHeader
টেমপ্লেটগুলিতে মান পাস করার জন্য দরকারী (উদাহরণস্বরূপ এই নমুনা )। এটি আপনার নিয়ামক কোডটিতে এত বেশি বয়লারপ্লেট যুক্ত করে না কারণ আপনি সহজেই একটি অন্তর্ভুক্ত অনুরোধের মান গ্রহণ করে ক্রিয়া লিখতে পারেন:
def index = Action { implicit request =>
Ok(views.html.index()) // The `request` value is implicitly passed by the compiler
}
সুতরাং, যেহেতু টেমপ্লেটগুলি প্রায়শই কমপক্ষে এই অন্তর্নিহিত প্যারামিটারটি গ্রহণ করে, আপনি এটিকে আপনার মেনুগুলি সমেত আরও সমৃদ্ধ মানের সাথে প্রতিস্থাপন করতে পারেন। আপনি প্লে 2 এর ক্রিয়া সংমিশ্রণ প্রক্রিয়াটি ব্যবহার করে এটি করতে পারেন ।
এটি করার জন্য আপনাকে Context
অন্তর্নিহিত অনুরোধটি মোড়ানো, আপনার শ্রেণি সংজ্ঞায়িত করতে হবে :
case class Context(menus: Seq[Menu], request: Request[AnyContent])
extends WrappedRequest(request)
তারপরে আপনি নিম্নলিখিত ActionWithMenu
পদ্ধতিটি নির্ধারণ করতে পারেন :
def ActionWithMenu(f: Context => Result) = {
Action { request =>
f(Context(Menu.findAll, request))
}
}
যা এর মতো ব্যবহার করা যেতে পারে:
def index = ActionWithMenu { implicit context =>
Ok(views.html.index())
}
এবং আপনি আপনার টেমপ্লেটগুলিতে একটি অন্তর্নিহিত প্যারামিটার হিসাবে প্রসঙ্গটি নিতে পারেন। যেমন main.scala.html
:
@(title: String)(content: Html)(implicit context: Context)
<html><head><title>@title</title></head>
<body>
<div>
@for(menu <- context.menus) {
<a href="#">@menu.name</a>
}
</div>
@content
</body>
</html>
ক্রিয়া সংমিশ্রণটি ব্যবহার করা আপনাকে আপনার টেমপ্লেটগুলির জন্য প্রয়োজনীয় সমস্ত অন্তর্নিহিত মানগুলিকে একক মান হিসাবে সংযুক্ত করতে দেয় তবে অন্যদিকে আপনি কিছুটা নমনীয়তা হারাতে পারেন ...
Http.Context (জাভা) ব্যবহার করে
যেহেতু জাভাতে স্কালার জড়িত প্রক্রিয়া বা অনুরূপ নেই, আপনি যদি স্পষ্টভাবে টেম্পলেটগুলির পরামিতিগুলি এড়াতে চান তবে একটি সম্ভাব্য উপায় হ'ল এটি Http.Context
কেবলমাত্র একটি অনুরোধের সময়কালে অবজায় থাকা অবজেক্টে সংরক্ষণ করা। এই অবজেক্টে args
টাইপের মান রয়েছে Map<String, Object>
।
সুতরাং, আপনি ডকুমেন্টেশনে বর্ণিত হিসাবে একটি ইন্টারসেপ্টার লিখে শুরু করতে পারেন :
public class Menus extends Action.Simple {
public Result call(Http.Context ctx) throws Throwable {
ctx.args.put("menus", Menu.find.all());
return delegate.call(ctx);
}
public static List<Menu> current() {
return (List<Menu>)Http.Context.current().args.get("menus");
}
}
স্ট্যাটিক পদ্ধতিটি বর্তমান প্রসঙ্গে মেনুগুলি পুনরুদ্ধার করার জন্য কেবলমাত্র একটি সংক্ষিপ্তকরণ। তারপরে Menus
অ্যাকশন ইন্টারসেপ্টারের সাথে মিশ্রিত হওয়ার জন্য আপনার নিয়ামককে টিকিয়ে দিন :
@With(Menus.class)
public class Application extends Controller {
// …
}
অবশেষে, menus
আপনার টেমপ্লেটগুলি থেকে মানটি পুনরুদ্ধার করুন :
@(title: String)(content: Html)
<html>
<head><title>@title</title></head>
<body>
<div>
@for(menu <- Menus.current()) {
<a href="#">@menu.name</a>
}
</div>
@content
</body>
</html>