10 nhà hàng hàng đầu ở thung lũng napa năm 2022

The Most Beautiful Wineries in Napa Valley

Best Brunch Spots in Napa Valley

Most Romantic Places to Stay in Napa Valley

Sparkling Napa Valley: Best Bubbles in the valley

The Most Beautiful European-Style Wineries in Napa Valley

Cabana Lounging in the Napa Valley

require[[ 'jquery', 'plugins_collections_custom_collection_helper', 'plugins_common_custom_quickview/site_quickview', 'sv_siteSlick' ], function[$, collectionHelper, quickview] { var root = $['[data-guid="de77c0e4-5dd7-4cda-8760-944317500b81"]']; root.addClass['js-loaded']; collectionHelper.init[{ root : root, slide: '.slide', lazyLoad: false }, function[] { var slider = root.find['[data-slides]']; var settings = { lazyLoad: 'progressive', infinite: true, centerMode: false, slidesToShow: 5, slidesToScroll: 1, prevArrow : root.find['.prev'], nextArrow : root.find['.next'] } settings.responsive = [ { breakpoint: 1440, settings: { slidesToShow: 4 } }, { breakpoint: 1120, settings: { slidesToShow: 3 } }, { breakpoint: 640, settings: { slidesToShow: 1 } } ] slider.slick[settings]; var buttons = root.find['[data-quickview-button]']; quickview.initButtons[buttons]; var qvWrappers = root.find['[data-qv-wrap]'].not['[data-qv-wrap="false"]']; quickview.initWrappers[qvWrappers]; }]; }];
 
{"leo":{"apply":"Apply","clear_filters":"Clear Filters","reset":"Reset","filter":"Filter","sort":"Sort","view":"View","keyword":"Keyword","search_placeholder":"Search","regions":"Towns","categories":"Categories","grid":"Grid","list":"List","map":"Map","show_map":"Show Map","hide_map":"Hide Map","recommended":"Recommended","near_me":"Near Me","read_more":"Read More","quick_view":"Quick View","featured_title":"Partner","visit_website":"Visit Website","email":"E-mail","tollfree":"Toll Free","tab_about":"About","tab_map":"Map","show_more":"Show $1 more","show_less":"Show Less","results":"$1 results","no_results":"There are no results that match your filter.","miles_from_you":"Miles from You","meeting_rooms":"Meeting Rooms","square_feet":"Total Sq. Ft.","largest_room":"Largest Room","sleeping_rooms":"Sleeping Rooms","banquet":"Banquet Capacity","reception":"Reception Capacity","theatre":"Theater Capacity","classroom":"Classroom Capacity","compare":"Compare","close_compare_dropdown":"Close compare dropdown","compare_add":"Add to compare","compare_remove":"Remove from compare","compare_clear_all":"Clear All","compare_limit_message":"You can only compare four [4] items at a time","location":"Location","locations":"Locations","details":"Details","address":"Address","err_loc_timeout":"We're unable to determine your location at this time.","err_loc_blocked":"You must allow location access for distance sorting.","err_loc_radius":"You must be within $1 miles to sort by distance.","date_range_title":"Show Events For","date_range_day":"Day","date_range_week":"Week","date_range_weekend":"Weekend","date_range_month":"Month","date_range_year":"Year","date_range_selected_dates":"Selected Dates","tb_add":"Add to Favorites","tb_remove":"Remove from Favorites","tb_view":"View Your Favorites","facilities":"Facilities"},"listings":{"clear_filters":"Clear Filters","amenities":"Amenities","tab_amenities":"Amenities","tab_meeting_facilities":"Meeting Facilities","tab_offers":"Offers","tab_events":"Events","tab_hours":"Hours","tab_tripadvisor":"TripAdvisor","tab_yelp":"Yelp","yelp_closed":"Closed","facility_info":"Facility Info","meeting_rooms":"Meeting Rooms","m_exhibits_space":"Exhibits Space","m_description":"Description","m_exhibits":"Exhibits","m_floorplan_file":"Floorplan File","m_largest_room":"Largest Room","m_toll_free":"Toll Free","m_total_sq_ft":"Total Sq. Ft.","m_reception_capacity":"Reception Capacity","m_space_notes":"Space Notes","m_theater_capacity":"Theater Capacity","m_link":"Link","m_villas":"Villas","m_banquet_capacity":"Banquet Capacity","m_number_of_rooms":"Number of Rooms","m_booths":"Booths","m_large_floor_plan_pdf":"Large floor Plan PDF","m_suites":"Suites","m_classroom_capacity":"Classroom Capacity","m_sleeping_rooms":"Sleeping Rooms","m_width":"Width","m_length":"Length","m_height":"Height","m_booth_capacity":"Booth Capacity","m_amphitheater_present":"Amphitheater Present","m_listening_devices_present":"Listening Devices Present"}}
require[[ "jquery", "plugins_core/main", "sv_site", "sv_crmLib", "sv_cloudinaryLib", "sv_asyncLib", "sv_clientMoment", "sv_arrayLib", "sv_load!plugins_dtn", "plugins_common_custom_layoutjs", "plugins_common_custom_lazyload", "sv_load!site_gamClient", "plugins_common_custom_ui_watcher", "sv_clientLib", "lodash" ], function[ $, core, site, crmLib, sv_cloudinaryLib, asyncLib, clientMoment, arrayLib, dtn, layoutjs, lazyload, gamClient, UIWatcher, clientLib, lodash ] { var widget = {"template":"list","showSearchBox":"true","listingcats":"23","listingsubcats":["324"],"amenityoptions":"custom","amenities":["420","362","365","481","480","479","482","483","242","488","245","268","419","260","262","418","355","423","295","319","426","310"],"custom_color":"rgb[209, 236, 255]","custom_defaultView":"grid","custom_amenities_filter":["restaurants_michelin_star_rated_1002_1016"],"custom_category_title":"Michelin-Rated Restaurants Directory"}; var useGroupedCats = false; var groupedCats = [{"label":"Hotels & Resorts","value":"12"},{"label":"Hide from Website","value":"13"},{"label":"Meeting & Event Venues","value":"15"},{"label":"Meeting Services","value":"16"},{"label":"Restaurants","value":"23","options":[{"label":"Coffee Shop / Bakery / Sweets","value":"793"},{"label":"Coffee Truck","value":"861"},{"label":"Food Truck","value":"860"},{"label":"Restaurant","value":"324"}]},{"label":"Things To Do","value":"28"},{"label":"Transportation","value":"29"},{"label":"Wedding Resources","value":"32"},{"label":"Wineries","value":"34"},{"label":"Weddings","value":"54"},{"label":"To Be Deleted","value":"60"},{"label":"Associate Partner","value":"61"}]; var subcats = [{"label":"Restaurant","value":"324"}]; var regions = [{"label":"Napa","value":"31"},{"label":"American Canyon","value":"32"},{"label":"Yountville","value":"33"},{"label":"St. Helena","value":"34"},{"label":"Calistoga","value":"35"},{"label":"Rutherford","value":"38"},{"label":"Oakville","value":"39"},{"label":"Downtown Napa","value":"47"}]; var regionsChosen = false; var subcatsChosen = true; var specificListingsChosen = false; var amenities = [{"label":"ADA Accessible","value":"restaurants_wheelchairyes","group":{"amenitytabid":1002,"sortorder":12,"amenitygroupname":"Restaurant Amenities","amenitygroupid":1016}},{"label":"1 Star","value":"restaurants_onestar","group":{"amenitytabid":1002,"sortorder":9,"amenitygroupname":"Michelin Rating","amenitygroupid":1033}},{"label":"Breakfast","value":"restaurants_breakfast","group":{"amenitytabid":1002,"sortorder":10,"amenitygroupname":"Meal","amenitygroupid":1026}},{"label":"2 Stars","value":"restaurants_twostars","group":{"amenitytabid":1002,"sortorder":9,"amenitygroupname":"Michelin Rating","amenitygroupid":1033}},{"label":"3 Stars","value":"restaurants_threestars","group":{"amenitytabid":1002,"sortorder":9,"amenitygroupname":"Michelin Rating","amenitygroupid":1033}},{"label":"Dinner","value":"restaurants_dinner_1002_1026","group":{"amenitytabid":1002,"sortorder":10,"amenitygroupname":"Meal","amenitygroupid":1026}},{"label":"Bib Gourmand","value":"restaurants_bibgourmand","group":{"amenitytabid":1002,"sortorder":9,"amenitygroupname":"Michelin Rating","amenitygroupid":1033}},{"label":"Lunch","value":"restaurants_lunch_1002_1026","group":{"amenitytabid":1002,"sortorder":10,"amenitygroupname":"Meal","amenitygroupid":1026}},{"label":"EV Charging Stations","value":"restaurants_evstations","group":{"amenitytabid":1002,"sortorder":12,"amenitygroupname":"Restaurant Amenities","amenitygroupid":1016}},{"label":"L'assiette","value":"restaurants_lassiette","group":{"amenitytabid":1002,"sortorder":9,"amenitygroupname":"Michelin Rating","amenitygroupid":1033}},{"label":"Green / Sustainable","value":"restaurants_greensustainable_1002_1016","group":{"amenitytabid":1002,"sortorder":12,"amenitygroupname":"Restaurant Amenities","amenitygroupid":1016}},{"label":"Group Friendly","value":"restaurants_group_friendly_1002_1016","group":{"amenitytabid":1002,"sortorder":12,"amenitygroupname":"Restaurant Amenities","amenitygroupid":1016}},{"label":"Kid Friendly","value":"restaurants_family_friendly_1002_1016","group":{"amenitytabid":1002,"sortorder":12,"amenitygroupname":"Restaurant Amenities","amenitygroupid":1016}},{"label":"Outdoor Dining","value":"restaurants_outdoor_dining_1002_1016","group":{"amenitytabid":1002,"sortorder":12,"amenitygroupname":"Restaurant Amenities","amenitygroupid":1016}},{"label":"Pet Friendly","value":"restaurants_petsok","group":{"amenitytabid":1002,"sortorder":12,"amenitygroupname":"Restaurant Amenities","amenitygroupid":1016}},{"label":"Picnic Supplies","value":"restaurants_picnic_supplies_1002_1016","group":{"amenitytabid":1002,"sortorder":12,"amenitygroupname":"Restaurant Amenities","amenitygroupid":1016}},{"label":"Romantic Dining","value":"restaurants_romantic_dining_1002_1016","group":{"amenitytabid":1002,"sortorder":12,"amenitygroupname":"Restaurant Amenities","amenitygroupid":1016}}]; var hasPrimaryCat = true; var initialAmenities = [widget !== undefined && widget.custom_amenities_filter !== undefined] ? widget.custom_amenities_filter : undefined; var dtnargs = {"auid":"/214662569/dtn_featured_listings","limit":10,"sort":"random"}; var hasDtn = [dtnargs.auid !== undefined && dtnargs.auid.length > 0 && dtnargs.limit > 0 && dtn !== undefined]; var limit = 12; var xhr; var defaultHooks = []; var color = widget.custom_color !== undefined ? widget.custom_color : "#fff" var defaultView = widget.custom_defaultView !== undefined ? widget.custom_defaultView : "grid"; var t = JSON.parse[$["#translations_b16dc358-89d1-41f2-831c-2f7a5fc13978"].html[]]; if [widget.detail_type !== undefined] { defaultHooks.push[{ name : "afterFind_custom_detail_type", args : { detail_type : widget.detail_type } }]; } if [widget.dtnlimit] { // if a limit is specified in the widget, override that passed in config dtnargs.limit = Number[widget.dtnlimit]; } if [hasDtn] { // we want the smaller of the limit and dtnargs.limit dtnargs.limit = Math.min[dtnargs.limit, limit]; } var allFilterTagItems = subcats.map[function[val] { return { site : site.site, subcatid : Number[val.value] } }]; // the base filter is the minimum filter applied to all queries. This is *not* the same as a "default" query, or the initial query. // this is the base. Any filter components that can be done in the UI are added to this object var baseFilter = { $and : [] } if [hasPrimaryCat] { baseFilter.$and.push[{ filter_tags : { $in : crmLib.getListingFilterTags[{ items : allFilterTagItems }] } }]; } else { baseFilter.$and.push[{ filter_tags : { $in : ['site_' + site.site] } }]; } if [regionsChosen] { baseFilter.regionid = { $in : regions.map[function[val] { return Number[val.value] }] } } if [specificListingsChosen] { baseFilter.recid = { $in : widget.custom_specific_listings_ids }; } if [initialAmenities && widget.amenityoptions === "none"] { initialAmenities.forEach[function[val] { baseFilter["amenities." + val + ".value_raw"] = true; }]; } else if [initialAmenities && widget.amenityoptions === "custom"] { initialAmenities.forEach[function[val] { let selected = amenities.some[function[amenity] { return amenity.value === val; }]; if [!selected] { baseFilter["amenities." + val + ".value_raw"] = true; } }]; } // BEGIN processing amenity groups amenities = lodash.groupBy[amenities, 'group.amenitygroupid']; var extraWatchers = []; const keys = Object.keys[amenities] for [const key of keys] { if[amenities[key].length > 0] { extraWatchers.push['amenities_'+amenities[key][0].group.amenitygroupid]; } } function getAmenityGroup[myval] { var addAmenityGroup = { name : amenities[myval] !== undefined && amenities[myval].length > 0 ? "amenities_"+amenities[myval][0].group.amenitygroupid : "amenities", label : amenities[myval] !== undefined && amenities[myval].length > 0 ? amenities[myval][0].group.amenitygroupname : t.listings.amenities, // we do not implicitly filter on amenities so if there is only one available option we still want to show the checkbox show : amenities[myval] !== undefined && amenities[myval].length > 0, type : "checkbox", initialValue : initialAmenities, typeExtra : { // options : amenities, options : amenities[myval] !== undefined ? amenities[myval].map[function[val] { return { label : val.label, value : val.value } }].sort[[a, b] => { if[a.label < b.label] { return -1; } if[a.label > b.label] { return 1; } return 0; }] : [], countArgs : { watchFilters : ["subcats", "regions", ...extraWatchers], unsupportedFilters : ["keyword"], field : "amenities_array.uniquename", unwind : "amenities_array", model : "plugins_listings_listings", sort : true } }, toFilter : function[value, filter] { value.forEach[function[val] { filter["amenities." + val + ".value_raw"] = true; }]; return filter; } } return addAmenityGroup; } // END processing amenity groups var categoryTitle = widget.custom_category_title || ""; var masterFlow = new asyncLib.Flow[]; masterFlow.series[{ init: function[cb] { var vue = layoutjs.getVue[{ rootNode : $["#layoutjs_b16dc358-89d1-41f2-831c-2f7a5fc13978"], type : "listings", view : defaultView, limit : limit, sort : "qualityScore", translations : t.leo, // if there is a defaultImageUrl defined in client config, use it. Else it will utilize the default declared in custom_layoutjs.js fallbackImageUrl : site.siteConfig.custom && site.siteConfig.custom[site.site] && site.siteConfig.custom[site.site].defaultImageUrl, showFilter : true, baseFilter : baseFilter, categoryTitle : categoryTitle, color: color, filters : [ { name : "keyword", label : t.leo.keyword, placeholder : t.leo.search_placeholder, type : "keyword", toFilter : function[value, filter, context] { filter.solrOptions = { keyword : value } return filter; } }, { name : "subcats", label : t.leo.categories, show : subcats.length > 1, type : useGroupedCats ? "twostage" : "checkbox", typeExtra : { options : useGroupedCats ? groupedCats : subcats, countArgs : { watchFilters : ["regions", ...extraWatchers], unsupportedFilters : ["keyword"], field : "categories.subcatid", unwind : "categories", model : "plugins_listings_listings", sort : true } }, toFilter : function[value, filter, context] { filter.$and.push[{ filter_tags : { $in : crmLib.getListingFilterTags[{ items : this.custom_selectedSubcatItems }] } }]; return filter; } }, { name : "regions", label : t.leo.regions, // we implicitly filter on regions if they have been selected in the widget, so no reason to display a region option with 1 choice // if no regions were selected, then a region option with 1 choice is valid and therefore we pass the whole array show : regionsChosen ? regions.length > 1 : regions.length > 0, type : "checkbox", typeExtra : { options : regions, countArgs : { watchFilters : ["subcats", ...extraWatchers], unsupportedFilters : ["keyword"], field : "regionid", model : "plugins_listings_listings", sort : true } }, toFilter : function[value, filter, context] { filter.$and.push[{ regionid : { $in : value.map[function[val] { return Number[val] }] } }]; return filter; } },getAmenityGroup["1"],getAmenityGroup["1022"],getAmenityGroup["1021"],getAmenityGroup["1023"],getAmenityGroup["1014"],getAmenityGroup["1015"],getAmenityGroup["1033"],getAmenityGroup["1026"],getAmenityGroup["1017"],getAmenityGroup["1016"],getAmenityGroup["1045"],getAmenityGroup["1040"],getAmenityGroup["1019"],getAmenityGroup["1041"],getAmenityGroup["1029"],getAmenityGroup["1043"],getAmenityGroup["1030"],getAmenityGroup["1032"],getAmenityGroup["1031"] ], sortOptions : [ { value : "qualityScore", label : t.leo.recommended }, { value : "distance", label : t.leo.near_me } ], maxRangeMiles : 100, latitude : 38.290359, longitude : -122.284088, data : { custom_catid : [widget.listingcats !== undefined] ? Number[widget.listingcats] : undefined, custom_dtnids : [] }, // computed allows the passing of computed and method properties, in cases where they may need to be unique to the template computed : { custom_selectedSubcatItems : function[] { return this.filter_subcats_numberArray.map[function[val] { return { site : site.site, subcatid : val } }]; }, custom_dtnFilterTagItems : function[] { // if we have not chosen subcats in the widget, then we need to load via the category id // if we have chosen subcats then we utilize whatever the state of the if [this.custom_selectedSubcatItems.length > 0] { // if we have items selected in the UI, use them return this.custom_selectedSubcatItems; } else if [subcatsChosen] { // if we have items chosen in the widget, use those return allFilterTagItems; } else { // otherwise fall back to the chosen catid return [{ site : site.site, catid : this.custom_catid }]; } } }, methods : {}, watch : { docs: function[] { // place logic in here that needs to happen after render of items this.$nextTick[function[] { if [hasDtn] { gamClient.renderAds[]; } }]; lazyload.lazy[$[this.$el].find['.content .item']] } }, query : function[cb] { var self = this; var filter = self.getFilter["query"]; var options = { limit : self.args.limit, skip : self.skip, count : true, castDocs : false, fields : { recid : 1, title : 1, city : 1, url : 1, isDTN : 1, latitude : 1, longitude : 1, primary_image_url : 1, qualityScore : 1, weburl : 1, rankid : 1, listingudfs_object: 1, primary_category : 1, "dtn.rank" : 1, "yelp.rating" : 1, "yelp.url" : 1, "yelp.review_count" : 1, "yelp.price" : 1, "crmtracking.core_listing_click" : 1, "crmtracking.core_booking_click" : 1, "crmtracking.core_itinerary" : 1, "amenities.restaurants_onestar" : 1, "amenities.restaurants_twostars" : 1, "amenities.restaurants_threestars" : 1, "amenities.restaurants_bibgourmand" : 1, "amenities.restaurants_lassiette" : 1 }, hooks : defaultHooks }; if [self.sort === "qualityScore"] { options.sort = { qualityScore : -1, sortcompany : 1 }; } else if [self.sort === "distance"] { filter.solrOptions = filter.solrOptions || {}; filter.solrOptions.sort = "distance"; filter.solrOptions.point = [self.georesult.latitude, self.georesult.longitude].join[","]; filter.solrOptions.radius = self.args.maxRangeMiles.toString[]; } if [options.skip === 0] { // whenever the skip is 0, we reset the custom_dtnids back to scratch self.custom_dtnids = []; } var flow = new asyncLib.Flow[]; flow.series[{ dtn : function[cb] { if [hasDtn === false || options.skip > 0 || self.sort === "distance" || self.custom_catid === undefined] { return cb[null, []]; } var dtnFilter = self.getFilter["query"]; dtnFilter.$and.push[{ filter_tags : { $in : crmLib.getListingFilterTags[{ items : self.custom_dtnFilterTagItems, dtn : true }] } }]; // using 0000 and 2359 for caching purposes, otherwise we could just use Date[].toISOString[] var today0000 = clientMoment[].startOf["day"]; // send date as 00:00:00 in the client timezone in UTC var today2359 = clientMoment[].endOf["day"]; // send date as 23:59:59 in the client timezone in UTC dtnFilter.$and.push[ { $or : [ { "dtn.sdate" : { $lte : { $date : today0000.toISOString[] } } }, { "dtn.sdate" : { $exists : false } } ] }, { $or : [ { "dtn.edate" : { $gte : { $date : today2359.toISOString[] } } }, { "dtn.edate" : { $exists : false } } ] } ]; var dtnOptions = $.extend[{}, options, { // we allow DTN to oversell the first page by a factor of 2 // we will pull from this set a max of the limit limit : self.limit * 2, count : false, hooks : defaultHooks.concat["afterFind_dtn"] }]; if [xhr] { xhr.abort[]; } xhr = $.get["/includes/rest_v2/plugins_listings_listings/find/", { json : JSON.stringify[{ filter : dtnFilter, options : dtnOptions }], token : core.simpleToken }]; xhr.done[function[res] { // randomize the result set, then trim it down to our desired limit res.docs = arrayLib.randomize[res.docs]; res.docs = res.docs.splice[0, dtnargs.limit]; res.docs.forEach[function[val] { self.custom_dtnids.push[val.recid]; val.dtnAuid = dtnargs.auid; val.isDTN = true; }]; return cb[null, res.docs]; }].fail[function[err, type, message] { if [type === "abort"] { return flow.halt[{ total : 0, docs : [] }]; } // another request has aborted this one, so halt this flow return cb[new Error[message]]; }]; }, data : function[cb] { if [flow.data.dtn.length > 0] { // has DTN listings, need to adjust page 1 limit and store dtnids for exclusion from main query on all pages options.limit -= self.custom_dtnids.length; } else { options.skip = [options.skip - self.custom_dtnids.length]; } if [self.custom_dtnids.length > 0] { filter.recid = { $nin : self.custom_dtnids } } if [xhr] { xhr.abort[]; } if [self.custom_dtnids.length === self.limit] { options.limit = 1; } xhr = $.get["/includes/rest_v2/plugins_listings_listings/find/", { json : JSON.stringify[{ filter : filter, options : options }], token : core.simpleToken }]; xhr.done[function[res] { var returnData = { total : res.docs.count + self.custom_dtnids.length, docs : flow.data.dtn.concat[res.docs.docs].slice[0, self.limit] }; returnData.docs = returnData.docs.map[function[val] { return { recid : val.recid, rankid : val.rankid, title : val.title, crmc : val.primary_category?.catname, crmsc : val.primary_category?.subcatname, image_url : val.primary_image_url, url : val.url, dtn : val.isDTN ? { auid : dtnargs.auid, rank : val.dtn.rank } : undefined, yelp : val.yelp, city: val.city, latitude : val.latitude, reservationUrl : val.listingudfs_object !== undefined && val.listingudfs_object[232] !== undefined ? crmLib.getTrackUrl[val.crmtracking.core_booking_click, val.listingudfs_object[232].value_string] : undefined, longitude : val.longitude, qualityScore : val.qualityScore, tripbuilderTracking : val.crmtracking, amenities : val.amenities !== undefined ? val.amenities : undefined, button : { title : t.leo.read_more, url : val.url, weburl : crmLib.getTrackUrl[val.crmtracking.core_listing_click, val.weburl], weburl_title : t.leo.visit_website } } }]; return cb[null, returnData]; }].fail[function[err, type, message] { if [type === "abort"] { return flow.halt[{ total : 0, docs : [] }]; } // another request has aborted this one, so halt this flow return cb[new Error[message]]; }]; } }, flow.cbLast[cb]]; } }]; /* register available UI events */ var watcher = new UIWatcher[vue, $, document]; var uid = clientLib.uuid[].toString[]; var widgetEvents = [ "change-page", "view-change", "value-change", "sort-change", "toggle-show-more", "scroll-into-view", "item-click", "title-click", "map-pin-click", "tripbuilder" ]; for [var i=0; i

Chủ Đề