Before Insert
refers to a specific point in time after the DML operation has started, but before the record is committed to the database. In other words, the user has already clicked the Save button and the system is starting to place the record in the database. In this sense, the fields won't be populated on the New Quote page, but the values would appear after the record that was just created is viewed by the user.
You can query the opportunity by its Id:
trigger copyOppFieldsToQuote on Quote (before insert) {
Map<Id, Opportunity> opps = new Map<Id, Opportunity>();
for(Quote record: Trigger.new) {
opps.put(record.OpportunityId, null);
}
opps.putAll([SELECT Name, CloseDate FROM Opportunity WHERE Id = :opps.keySet()]);
for(Quote record: Trigger.new) {
Opportunity opp = opps.get(record.OpportunityId);
// copy fields from opp to record as needed
}
// No need to update records, as changes to Trigger.new are
// automatically saved in a "before insert/update" trigger.
}
I refer to this pattern of operations as the Aggregate-Query-Update pattern: we aggregate together the data to query (Opportunity Id values), query the database, and then update records (in this case, our Quote records).