برنامه رایگان در این زمینه وب سایت کلور کامپوننت هست:
http://www.clevercomponents.com/downloads/dbcomparer/dbcdownload.asp
البته این برنامه هم اشکالاتی دارد ولی به نظر من که نسخه تیم سوییت رو ندارم خوب بود.
اینبار نوع دستور را به PUT و آدرس را به http://localhost:8080/docs/questions/1 تنظیم میکنیم. همچنین در قسمت Request body، مقداری را که قرار است در سؤال یک درج شود، با فرمت JSON وارد میکنیم.
List<string> scope = newList<string>() { "email", "user_about_me", "user_hometown", "friends_about_me", "friends_photos" }; var x = newFacebookAuthenticationOptions(); x.Scope.Add("email"); x.Scope.Add("friends_about_me"); x.Scope.Add("friends_photos"); x.AppId = "636919159681109"; x.AppSecret = "f3c16511fe95e854cf5885c10f83f26f"; x.Provider = newFacebookAuthenticationProvider() { OnAuthenticated = async context => { //Get the access token from FB and store it in the database and //use FacebookC# SDK to get more information about the user context.Identity.AddClaim( new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken)); } }; x.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie; app.UseFacebookAuthentication(x);
<li> @Html.ActionLink("FacebookInfo", "FacebookInfo","Account") </li>
// // GET: /Account/LinkLoginCallback publicasyncTask<ActionResult> LinkLoginCallback() { var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId()); if (loginInfo == null) { return RedirectToAction("Manage", new { Message = ManageMessageId.Error }); } var result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login); if (result.Succeeded) { var currentUser = await UserManager.FindByIdAsync(User.Identity.GetUserId()); //Add the Facebook Claim await StoreFacebookAuthToken(currentUser); return RedirectToAction("Manage"); } return RedirectToAction("Manage", new { Message = ManageMessageId.Error }); }
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl) { if (User.Identity.IsAuthenticated) { return RedirectToAction("Manage"); } if (ModelState.IsValid) { // Get the information about the user from the external login provider var info = await AuthenticationManager.GetExternalLoginInfoAsync(); if (info == null) { return View("ExternalLoginFailure"); } var user = newApplicationUser() { UserName = model.Email }; var result = await UserManager.CreateAsync(user); if (result.Succeeded) { result = await UserManager.AddLoginAsync(user.Id, info.Login); if (result.Succeeded) { await StoreFacebookAuthToken(user); await SignInAsync(user, isPersistent: false); return RedirectToLocal(returnUrl); } } AddErrors(result); } ViewBag.ReturnUrl = returnUrl; return View(model); }
// // GET: /Account/ExternalLoginCallback [AllowAnonymous] publicasyncTask<ActionResult> ExternalLoginCallback(string returnUrl) { var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); if (loginInfo == null) { return RedirectToAction("Login"); } // Sign in the user with this external login provider if the user already has a login var user = await UserManager.FindAsync(loginInfo.Login); if (user != null) { //Save the FacebookToken in the database if not already there await StoreFacebookAuthToken(user); await SignInAsync(user, isPersistent: false); return RedirectToLocal(returnUrl); } else { // If the user does not have an account, then prompt the user to create an account ViewBag.ReturnUrl = returnUrl; ViewBag.LoginProvider = loginInfo.Login.LoginProvider; return View("ExternalLoginConfirmation", newExternalLoginConfirmationViewModel { Email = loginInfo.Email }); } }
privateasyncTask StoreFacebookAuthToken(ApplicationUser user) { var claimsIdentity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); if (claimsIdentity != null) { // Retrieve the existing claims for the user and add the FacebookAccessTokenClaim var currentClaims = await UserManager.GetClaimsAsync(user.Id); var facebookAccessToken = claimsIdentity.FindAll("FacebookAccessToken").First(); if (currentClaims.Count() <=0 ) { await UserManager.AddClaimAsync(user.Id, facebookAccessToken); }
public class FacebookViewModel { [Required] [Display(Name = "Friend's name")] public string Name { get; set; } public string ImageURL { get; set; } }
//GET: Account/FacebookInfo [Authorize] publicasyncTask<ActionResult> FacebookInfo() { var claimsforUser = await UserManager.GetClaimsAsync(User.Identity.GetUserId()); var access_token = claimsforUser.FirstOrDefault(x => x.Type == "FacebookAccessToken").Value; var fb = newFacebookClient(access_token); dynamic myInfo = fb.Get("/me/friends"); var friendsList = newList<FacebookViewModel>(); foreach (dynamic friend in myInfo.data) { friendsList.Add(newFacebookViewModel() { Name = friend.name, ImageURL = @"https://graph.facebook.com/" + friend.id + "/picture?type=large" }); } return View(friendsList); }
@model IList<WebApplication96.Models.FacebookViewModel> @if (Model.Count > 0) { <h3>List of friends</h3> <div class="row"> @foreach (var friend in Model) { <div class="col-md-3"> <a href="#" class="thumbnail"> <img src=@friend.ImageURL alt=@friend.Name /> </a> </div> } </div> }
این یک مثال ساده از کار کردن با تامین کنندگان اجتماعی بود. همانطور که مشاهده میکنید، براحتی میتوانید دادههای بیشتری برای کاربر جاری درخواست کنید و تجربه کاربری و امکانات بسیار بهتری را در اپلیکیشن خود فراهم کنید.
public class PersonFormViewModel { public long Id { get; set; } public long RequestId { get; set; } [DisplayName("نام کاربری"), Required(ErrorMessage = "نام کاربری الزامی میباشد.")] public string Username { get; set; } public bool Accepted { get; set; } [DisplayName("مدل")] public string DeviceModel { get; set; } public DateTime? ExpireDate { get; set; } public RequestViewModel RequestViewModel { get; set; } }
public class RequestViewModel { public long Id { get; set; } public string Username { get; set; } [DisplayName("توضیحات")] [DataType(DataType.MultilineText)] public string Description { get; set; } public DateTime CreateDate { get; set; } public Nullable<long> DeviceId { get; set; } public Nullable<long> ParentId { get; set; } public long RequestTypeId { get; set; } public bool IsFinalized { get; set; } public virtual PersonFormViewModel PersonFormViewModel { get; set; } }
_requestService.Add(requestViewModel); _uow.SaveChanges();
var addedRequest = _requestService.Add(requestViewModel ); var personViewModel = requestViewModel .PersonFormViewModel; _personFormService.Add(personViewModel); _uow.SaveChanges();
زمانی که سیستم عامل های GUI مثل ویندوز به بازار آمدند، یکی از قسمتهای گرافیکی آنها AddressBar نام داشت که مسیر حرکت آنها را در فایل سیستم نشان میداد و در سیستم عاملهای متنی CLI با دستور cd یا pwd انجام میشد. بعدها در وب هم همین حرکت با نام BreadCrumb صورت گرفت که به عنوان مثال مسیر رسیدن به صفحهی یک محصول یا یک مقاله را نشان میداد. در یک پروژهی اندرویدی نیاز بود تا یک ساختار درختی را پیاده سازی کنم، ولی در برنامههای اندروید ایجاد یک درخت، کار هوشمندانه و مطلوبی نیست و روش کار به این صورت است که یک لیست از گروههای والد را نمایش داده و با انتخاب هر آیتم لیست به آیتمهای فرزند تغییر میکند. حالا مسئله این بود که کاربر باید مسیر حرکت خودش را بشناسد. به همین علت مجبور شدم یک BreadCrumb را برای آن طراحی کنم که در زیر تصویر آن را مشاهده میکنید.
از نکات جالب توجه در مورد این ماژول میتوان گفت که قابلیت این را دارد تا تصمیمات خود را بر اساس اندازههای مختلف صفحه نمایش بگیرد. به عنوان مثال اگر آیتمهای بالا بیشتر از سه عدد باشد و در صفحه جا نشود از یک مسیر جعلی استفاده میکند و همهی آیتمها با اندیس شماره 1 تا index-3 را درون یک آیتم با عنوان (...) قرار میدهد که من به آن میگویم مسیر جعلی. به عنوان نمونه مسیر تصویر بالا در صفحه جا شده است و نیازی به این کار دیده نشده است. ولی تصویر زیر از آن جا که مسیر، طول width صفحه نمایش رد کرده است، نیاز است تا چنین کاری انجام شود. موقعیکه کاربر آیتم ... را کلیک کند، مسیر باز شده و به محل index-3 حرکت میکند. یعنی دو مرحله به عقب باز میگردد.
نگاهی به کارکرد ماژول
قبل از توضیح در مورد سورس، اجازه دهید نحوهی استفاده از آن را ببینیم.
این سورس شامل دو کلاس است که سادهترین کلاس آن AndBreadCrumbItem میباشد که مشابه کلاس ListItem در بخش وب دات نت است و دو مقدار، یکی متن و دیگری Id را میگیرد:
سورس:
public class AndBreadCrumbItem { private int Id; private String diplayText; public AndBreadCrumbItem(int Id, String displayText) { this.Id=Id; this.diplayText=displayText; } public String getDiplayText() { return diplayText; } public void setDiplayText(String diplayText) { this.diplayText = diplayText; } public int getId() { return Id; } public void setId(int id) { Id = id; } }
به عنوان مثال میخواهیم یک breadcrumb را با مشخصات زیر بسازیم:
AndBreadCrumbItem itemhome=new AndBreadCrumbItem(0,"Home"); AndBreadCrumbItem itemproducts=new AndBreadCrumbItem(12,"Products"); AndBreadCrumbItem itemdigital=new AndBreadCrumbItem(15,"Digital"); AndBreadCrumbItem itemhdd=new AndBreadCrumbItem(56,"Hard Disk Drive");
AndBreadCrumb breadCrumb=new AndBreadCrumb(this); breadCrumb.AddNewItem(itemhome); breadCrumb.AddNewItem(itemproducts); breadCrumb.AddNewItem(itemdigital); breadCrumb.AddNewItem(itemhdd);
breadCumb.setContext(this);
پس از افزودن آیتم ها، تنظیمات زیر را اعمال نمایید:
LinearLayout layout=(LinearLayout)getActivity().findViewById(R.id.breadcumblayout); layout.setPadding(8, 8, 8, 8); breadCrumb.setLayout(layout); breadCrumb.SetTinyNextNodeImage(R.drawable.arrow); breadCrumb.setTextSize(25); breadCrumb.SetViewStyleId(R.drawable.list_item_style);
breadCrumb.UpdatePath();
breadCrumb.setRTL(true);
در صورتیکه قصد دارید تنظیمات بیشتری چون رنگ متن، فونت متن و ... را روی هر المان اعمال کنید، از رویداد زیر استفاده کنید:
breadCrumb.setOnTextViewUpdate(new ITextViewUpdate() { @Override public TextView UpdateTextView(Context context, TextView tv) { tv.setTextColor(...); tv.setTypeface(...); return tv; } });
breadCumb.setOnClickListener(new IClickListener() { @Override public void onClick(int position, int Id) { //... } });
آخرین متد موجود که کمترین استفاده را دارد، متد SetNoResize است. در صورتیکه این متد با True مقداردهی گردد، عملیات تنظیم بر اساس صفحهی نمایش لغو میشود. این متد برای زمانی مناسب است که به عنوان مثال شما از یک HorozinalScrollView استفاده کرده باشید. در این حالت layout شما هیچ گاه به پایان نمیرسد و بهتر هست عملیات اضافه را لغو کنید.
نگاهی به سورس
کلاس زیر شامل بخشهای زیر است:
//=-=--=-=-=-=-=-=-=-=-=-=-=- Private Properties -=-=-=-=-=-=-=--=-=-= private List<AndBreadCrumbItem> items=null; private List<TextView> textViews; private int tinyNextNodeImage; private int viewStyleId; private Context context; private boolean RTL; private float textSize=20; private boolean noResize=false; LinearLayout layout; IClickListener clickListener; ITextViewUpdate textViewUpdate; LinearLayout.LayoutParams params ;
//=-=---=-=-=-=-- Constructor =--=-=-=-=-=--=-=- public AndBreadCrumb(Context context) { this.context=context; params = new LinearLayout.LayoutParams (LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); } //=-=-=--=--=-=-=-=-=-=-=-=- Public Properties --=-=-=-=-=-=--=-=-=-=-=-=- //each category would be added to create path public void AddNewItem(AndBreadCrumbItem item) { if(items==null) items=new ArrayList<>(); items.add(item); } // if you want a pointer or next node between categories or textviews public void SetTinyNextNodeImage(int resId) {this.tinyNextNodeImage=resId;} public void SetViewStyleId(int resId) {this.viewStyleId=resId;} public void setTextSize(float textSize) {this.textSize = textSize;} public boolean isRTL() { return RTL; } public void setRTL(boolean RTL) { this.RTL = RTL; } public void setLayout(LinearLayout layout) { this.layout = layout; } public void setContext(Context context) { this.context = context; } public boolean isNoResize() { return noResize; } public void setNoResize(boolean noResize) { this.noResize = noResize; }
//primary method for render objects on layout private void DrawPath() { //stop here if essentail elements aren't present if (items == null) return ; if (layout == null) return; if (items.size() == 0) return; //we need to get size of layout,so we use the post method to run this thread when ui is ready layout.post(new Runnable() { @Override public void run() { //textviews created here one by one int position = 0; textViews = new ArrayList<>(); for (AndBreadCrumbItem item : items) { TextView tv = MakeTextView(position, item.getId()); tv.setText(item.getDiplayText()); textViews.add(tv); position++; } //add textviews on layout AddTextViewsOnLayout(); //we dont manage resizing anymore if(isNoResize()) return; //run this code after textviews Added to get widths of them TextView last_tv=textViews.get(textViews.size()-1); last_tv.post(new Runnable() { @Override public void run() { //define width of each textview depend on screen width BatchSizeOperation(); } }); } }); }
TextView tv=new TextView(this); tv.getWidth(); //return 0 layout.add(tv); tv.getWidth(); //return 0
TextView tv=new TextView(this); tv.post(new Runnable() { @Override public void run() { tv.getWidth(); //return x } });
private TextView MakeTextView(final int position, final int Id) { //settings for cumbs TextView tv=new TextView(this.context); tv.setEllipsize(TextUtils.TruncateAt.END); tv.setSingleLine(true); tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); tv.setBackgroundResource(viewStyleId); /*call custom event - this event will be fired when user click on one of textviews and returns position of textview and value that user sat as id */ tv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SetPosition(position); clickListener.onClick(position, Id); } }); //if user wants to update each textviews if(textViewUpdate!=null) tv=textViewUpdate.UpdateTextView(context,tv); if(isRTL()) tv.setRotationY(180); return tv; }
//this method calling by everywhere to needs add textviews on the layout like master method :drawpath private void AddTextViewsOnLayout() { //prepare layout //remove everything on layout for recreate it layout.removeAllViews(); layout.setOrientation(LinearLayout.HORIZONTAL); layout.setVerticalGravity(Gravity.CENTER_VERTICAL); if(isRTL()) layout.setRotationY(180); //add textviews one by one int position=0; for (TextView tv:textViews) { layout.addView(tv,params); //add next node image between textviews if user defined a next node image if(tinyNextNodeImage>0) if(position<(textViews.size()-1)) { layout.addView(GetNodeImage(), params); position++; } } }
//set textview width depend on screen width private void BatchSizeOperation() { //get width of next node between cumbs Bitmap tinyBmap = BitmapFactory.decodeResource(context.getResources(), tinyNextNodeImage); int tinysize=tinyBmap.getWidth(); //get sum of nodes tinysize*=(textViews.size()-1); ... }
//get width size of screen(layout is screen here) int screenWidth=GetLayoutWidthSize(); //get sum of arrows and cumbs width int sumtvs=tinysize; for (TextView tv : textViews) { int width=tv.getWidth(); sumtvs += width; }
private int GetLayoutWidthSize() { int width=layout.getWidth(); int padding=layout.getPaddingLeft()+layout.getPaddingRight(); width-=padding; return width; }
private void BatchSizeOperation() { .... //if sum of cumbs is less than screen size the state is good so return same old textviews if(sumtvs<screenWidth) return ; if(textViews.size()>3) { //make fake path MakeFakePath(); //clear layout and add textviews again AddTextViewsOnLayout(); } //get free space without next nodes -> and spilt rest of space to textviews count to get space for each textview int freespace =screenWidth-tinysize; int each_width=freespace/textViews.size(); //some elements have less than each_width,so we should leave size them and calculate more space again int view_count=0; for (TextView tv:textViews) { if (tv.getWidth()<=each_width) freespace=freespace-tv.getWidth(); else view_count++; } if (view_count==0) return; each_width=freespace/view_count; for (TextView tv:textViews) { if (tv.getWidth()>each_width) tv.setWidth(each_width); } }
//if elements are so much(mor than 3),we make a fake path to decrease elements private void MakeFakePath() { //we make 4 new elements that index 1 is fake element and has a rest of real path in its heart //when user click on it,path would be opened textViews=new ArrayList<>(4); TextView[] tvs=new TextView[4]; int[] positions= {0,items.size()-3,items.size()-2,items.size()-1}; for (int i=0;i<4;i++) { //request for new textviews tvs[i]=MakeTextView(positions[i],items.get(positions[i]).getId()); if(i!=1) tvs[i].setText(items.get(positions[i]).getDiplayText()); else { tvs[i].setText("..."); //override click event and change it to part of code to open real path by call setposition method and redraw path tvs[i].setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int pos = items.size() - 3; int id = items.get(pos).getId(); SetPosition(items.size() - 3); clickListener.onClick(pos, id); } }); } textViews.add(tvs[i]); } }
public void Configure(ILoggerFactory loggerFactory, IApplicationBuilder app, IHostingEnvironment env) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug();
{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } } }
{ "dependencies": { //same as before "Microsoft.Extensions.Logging": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Extensions.Logging.Debug": "1.0.0" } }
[Route("[controller]")] public class AboutController : Controller { private readonly ILogger<AboutController> _logger; public AboutController(ILogger<AboutController> logger) { _logger = logger; } [Route("")] public ActionResult Hello() { _logger.LogInformation("Running Hello"); return Content("Hello from DNT!"); }
loggerFactory.AddDebug(minLevel: LogLevel.Information);
public enum LogLevel { Trace, Debug, Information, Warning, Error, Critical, None, }
using System.Web; namespace Intellisense.Models { public class Persons { // کلید public int Id { get; set; } // نام public string FirstName { get; set; } // نام خانوادگی public string LastName { get; set; } // نام پدر public string FatherName { get; set; } // سن public int Age { get; set; } // شماره تلفن public int Mobile { get; set; } // آدرس public string Address { get; set; } } }
using System.Collections.Generic; using System.Web.Mvc; using Intellisense.Models; namespace Intellisense.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { // List of person var listOfPerson = new List<Persons> { new Persons() {Id = 1, FirstName = "Jone", LastName = "liy", FatherName = "Sobin", Age = 36, Mobile = +982015222, Address = "..."}, new Persons() {Id = 2, FirstName = "kety", LastName = "sory", FatherName = "petter", Age = 19, Mobile = +962222155, Address = "..."}, }; // Set ViewBag.Persons data from listOfPerson ViewBag.Persons = listOfPerson; // Show and send ViewBag.Persons to view return View(); } } }
@{ ViewBag.Title = "ViewBag"; } <table> <thead> <tr> <th> Id </th> <th> First Name </th> <th> Last Name </th> <th> Father Name </th> <th> Age </th> <th> Mobile </th> <th> Address </th> </tr> </thead> <tbody> @{foreach (var item in ViewBag.Persons) { <tr> <td> @item.Id </td> <td> @item.FirstName </td> <td> @item.LastName </td> <td> @item.FatherName </td> <td> @item.Age </td> <td> @item.Mobile </td> <td> @item.Address </td> </tr> } } </tbody> </table>
@using Intellisense.Models @{ ViewBag.Title = "ViewBag"; // روش اول // پیشنهاد میشود که از روش اول استفاده شود // var listOfPerson = ViewBag.Persons as IEnumerable<Persons>; // روش دوم // var listOfPerson = (IEnumerable<Persons>)ViewBag.Persons; var listOfPerson = ViewBag.Persons as IEnumerable<Persons>; } <table> <thead> <tr> <th> Id </th> <th> First Name </th> <th> Last Name </th> <th> Father Name </th> <th> Age </th> <th> Mobile </th> <th> Address </th> </tr> </thead> <tbody> @{foreach (var item in listOfPerson) { <tr> <td> @item.Id </td> <td> @item.FirstName </td> <td> @item.LastName </td> <td> @item.FatherName </td> <td> @item.Age </td> <td> @item.Mobile </td> <td> @item.Address </td> </tr> } } </tbody> </table>
public class CustomerServiceReport { public string ReportTitle { get; set; } public string ReportDate { get; set; } //... public List<CustomerRow> Customers { get; set; } = new List<CustomerRow>(); } public class CustomerRow { public int CustomerId { get; set; } public string CustomerName { get; set; } public string Phone { get; set; } //... public List<ServiceRow> Services { get; set; } = new List<ServiceRow>();
} public class ServiceRow { public int ServiceId { get; set; } public string ServiceName { get; set; } public int Count { get; set; } public long Price { get; set; } }
var data = new CustomerServiceReport { ReportDate = "1399/09/04", ReportTitle = "گزارش سرویسهای مشتریان" }; for (int i = 0; i < 5; i++) { var customer = new CustomerRow { CustomerId = i + 1, CustomerName = $"مشتری شماره {i + 1}", Phone = "001122" }; for (int j = 0; j < 3; j++) { var service = new ServiceRow { ServiceId = j + 1, ServiceName = $"سرویس شماره {j + 1}", Count = (j + 1) * 10, Price = (j + 1) * 10000 }; customer.Services.Add(service); //اضافه کردن سرویس به هر مشتری } data.Customers.Add(customer); // اضافه کردن مشتری به گزارش } var report = new StiReport(); report.RegBusinessObject("CustomerServiceReport", data); report.Dictionary.SynchronizeBusinessObjects();
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Blueprint test page</title> <!-- Framework CSS --> <link rel="stylesheet" href="blueprint/screen.css" type="text/css" media="screen, projection"> <link rel="stylesheet" href="blueprint/print.css" type="text/css" media="print"> <!--[if lt IE 8]><link rel="stylesheet" href="blueprint/ie.css" type="text/css" media="screen, projection"><![endif]--> </head> <body> <div class="container showgrid"> test <hr class="space" /> <hr class="space" /> <hr class="space" /> <hr class="space" /> <hr class="space" /> test </div> </body> </html>
<div class="container"> page </div>
<body> <div class="container showgrid"> <div class="span-12"> row1-col1 </div> <div class="span-12 last"> row1-col2 </div> <div class="span-12"> row2-col1 </div> <div class="span-12 last"> row2-col2 </div> </div> </body>
<body> <div class="container showgrid"> <div class="span-8"> row1-col1 </div> <div class="span-8"> row1-col2 </div> <div class="span-8 last"> row1-col3 </div> </div> </body>
<body> <div class="container showgrid"> <div class="span-8"> <div class="span-4"> row-1, col1 : cell-1 </div> <div class="span-4 last"> row-1, col1 : cell-2 </div> </div> <div class="span-8"> row1-col2 </div> <div class="span-8 last"> row1-col3 </div> </div> </body>
<body> <div class="container showgrid"> <div class="span-8"> <div class="prepend-1 span-3 border"> row-1, col1 : cell-1 </div> <div class="span-4 last"> row-1, col1 : cell-2 </div> </div> <div class="span-8"> row1-col2 </div> <div class="span-8 last"> row1-col3 </div> </div> </body>